Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[pandora-kernel.git] / mm / page-writeback.c
index 838a5e3..3d3848f 100644 (file)
@@ -297,20 +297,12 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
 {
        int background_ratio;           /* Percentages */
        int dirty_ratio;
-       int unmapped_ratio;
        long background;
        long dirty;
        unsigned long available_memory = determine_dirtyable_memory();
        struct task_struct *tsk;
 
-       unmapped_ratio = 100 - ((global_page_state(NR_FILE_MAPPED) +
-                               global_page_state(NR_ANON_PAGES)) * 100) /
-                                       available_memory;
-
        dirty_ratio = vm_dirty_ratio;
-       if (dirty_ratio > unmapped_ratio / 2)
-               dirty_ratio = unmapped_ratio / 2;
-
        if (dirty_ratio < 5)
                dirty_ratio = 5;
 
@@ -355,8 +347,8 @@ get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
  */
 static void balance_dirty_pages(struct address_space *mapping)
 {
-       long bdi_nr_reclaimable;
-       long bdi_nr_writeback;
+       long nr_reclaimable, bdi_nr_reclaimable;
+       long nr_writeback, bdi_nr_writeback;
        long background_thresh;
        long dirty_thresh;
        long bdi_thresh;
@@ -376,11 +368,26 @@ static void balance_dirty_pages(struct address_space *mapping)
 
                get_dirty_limits(&background_thresh, &dirty_thresh,
                                &bdi_thresh, bdi);
+
+               nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
+                                       global_page_state(NR_UNSTABLE_NFS);
+               nr_writeback = global_page_state(NR_WRITEBACK);
+
                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)
                        break;
 
+               /*
+                * Throttle it only when the background writeback cannot
+                * catch-up. This avoids (excessively) small writeouts
+                * when the bdi limits are ramping up.
+                */
+               if (nr_reclaimable + nr_writeback <
+                               (background_thresh + dirty_thresh) / 2)
+                       break;
+
                if (!bdi->dirty_exceeded)
                        bdi->dirty_exceeded = 1;
 
@@ -551,7 +558,6 @@ static void background_writeout(unsigned long _min_pages)
                        global_page_state(NR_UNSTABLE_NFS) < background_thresh
                                && min_pages <= 0)
                        break;
-               wbc.more_io = 0;
                wbc.encountered_congestion = 0;
                wbc.nr_to_write = MAX_WRITEBACK_PAGES;
                wbc.pages_skipped = 0;
@@ -559,9 +565,8 @@ static void background_writeout(unsigned long _min_pages)
                min_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
                if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) {
                        /* Wrote less than expected */
-                       if (wbc.encountered_congestion || wbc.more_io)
-                               congestion_wait(WRITE, HZ/10);
-                       else
+                       congestion_wait(WRITE, HZ/10);
+                       if (!wbc.encountered_congestion)
                                break;
                }
        }
@@ -626,12 +631,11 @@ static void wb_kupdate(unsigned long arg)
                        global_page_state(NR_UNSTABLE_NFS) +
                        (inodes_stat.nr_inodes - inodes_stat.nr_unused);
        while (nr_to_write > 0) {
-               wbc.more_io = 0;
                wbc.encountered_congestion = 0;
                wbc.nr_to_write = MAX_WRITEBACK_PAGES;
                writeback_inodes(&wbc);
                if (wbc.nr_to_write > 0) {
-                       if (wbc.encountered_congestion || wbc.more_io)
+                       if (wbc.encountered_congestion)
                                congestion_wait(WRITE, HZ/10);
                        else
                                break;  /* All the old data is written */