Re: mmap dirty limits on 32 bit kernels (Was: [BUG] New Kernel Bugs)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2007-11-15 at 20:40 +0100, Peter Zijlstra wrote:

> As for the highmem part, that was due to buffer cache, and unfortunately
> that is still true. Although maybe we can do something smart with the
> per-bdi stuff.

Something like this ought to do I guess. Although my
mapping_is_buffercache() is the ugliest thing. I'm sure that can be done
better.

Uncompiled, untested

Not-Signed-off-by: Peter Zijlstra <[email protected]>
---
 mm/page-writeback.c |   28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

Index: linux-2.6/mm/page-writeback.c
===================================================================
--- linux-2.6.orig/mm/page-writeback.c
+++ linux-2.6/mm/page-writeback.c
@@ -280,27 +280,28 @@ static unsigned long highmem_dirtyable_m
 #endif
 }
 
-static unsigned long determine_dirtyable_memory(void)
+static unsigned long determine_dirtyable_memory(int highmem)
 {
 	unsigned long x;
 
 	x = global_page_state(NR_FREE_PAGES)
 		+ global_page_state(NR_INACTIVE)
 		+ global_page_state(NR_ACTIVE);
-	x -= highmem_dirtyable_memory(x);
+	if (!highmem)
+		x -= highmem_dirtyable_memory(x);
 	return x + 1;	/* Ensure that we never return 0 */
 }
 
 static void
 get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
-		 struct backing_dev_info *bdi)
+		 struct backing_dev_info *bdi, int highmem)
 {
 	int background_ratio;		/* Percentages */
 	int dirty_ratio;
 	int unmapped_ratio;
 	long background;
 	long dirty;
-	unsigned long available_memory = determine_dirtyable_memory();
+	unsigned long available_memory = determine_dirtyable_memory(highmem);
 	struct task_struct *tsk;
 
 	unmapped_ratio = 100 - ((global_page_state(NR_FILE_MAPPED) +
@@ -346,6 +347,16 @@ get_dirty_limits(long *pbackground, long
 	}
 }
 
+static inline int mapping_is_buffercache(struct address_space *mapping)
+{
+	struct super_block *sb = mapping->host->i_sb;
+
+	if (sb && sb->s_bdev && sb->s_bdev->bd_inode->i_mapping != mapping)
+		return 0;
+
+	return 1;
+}
+
 /*
  * balance_dirty_pages() must be called by processes which are generating dirty
  * data.  It looks at the number of dirty pages in the machine and will force
@@ -364,6 +375,7 @@ static void balance_dirty_pages(struct a
 	unsigned long write_chunk = sync_writeback_pages();
 
 	struct backing_dev_info *bdi = mapping->backing_dev_info;
+	int highmem = !mapping_is_buffercache(mapping);
 
 	for (;;) {
 		struct writeback_control wbc = {
@@ -375,7 +387,7 @@ static void balance_dirty_pages(struct a
 		};
 
 		get_dirty_limits(&background_thresh, &dirty_thresh,
-				&bdi_thresh, bdi);
+				&bdi_thresh, bdi, highmem);
 		bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
 		bdi_nr_writeback = bdi_stat(bdi, BDI_WRITEBACK);
 		if (bdi_nr_reclaimable + bdi_nr_writeback <= bdi_thresh)
@@ -394,7 +406,7 @@ static void balance_dirty_pages(struct a
 			writeback_inodes(&wbc);
 			pages_written += write_chunk - wbc.nr_to_write;
 			get_dirty_limits(&background_thresh, &dirty_thresh,
-				       &bdi_thresh, bdi);
+				       &bdi_thresh, bdi, highmem);
 		}
 
 		/*
@@ -503,7 +515,7 @@ void throttle_vm_writeout(gfp_t gfp_mask
 	long dirty_thresh;
 
         for ( ; ; ) {
-		get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL);
+		get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL, 1);
 
                 /*
                  * Boost the allowable dirty threshold a bit for page
@@ -546,7 +558,7 @@ static void background_writeout(unsigned
 		long background_thresh;
 		long dirty_thresh;
 
-		get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL);
+		get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL, 1);
 		if (global_page_state(NR_FILE_DIRTY) +
 			global_page_state(NR_UNSTABLE_NFS) < background_thresh
 				&& min_pages <= 0)



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux