From: Bart Samwel <bart@samwel.tk>

Writebacks on writes can be implemented in submit_bio for writes as well,
removing this code from balance_dirty_pages.



---

 drivers/block/ll_rw_blk.c |    6 ++++
 mm/page-writeback.c       |   56 ++++++++++++++++++----------------------------
 2 files changed, 29 insertions(+), 33 deletions(-)

diff -puN drivers/block/ll_rw_blk.c~laptop-mode-simplification drivers/block/ll_rw_blk.c
--- 25/drivers/block/ll_rw_blk.c~laptop-mode-simplification	2004-02-16 17:49:27.000000000 -0800
+++ 25-akpm/drivers/block/ll_rw_blk.c	2004-02-16 17:49:27.000000000 -0800
@@ -2608,6 +2608,12 @@ void end_that_request_last(struct reques
 		unsigned long duration = jiffies - req->start_time;
 		switch (rq_data_dir(req)) {
 		    case WRITE:
+			/*
+			 * schedule the writeout of pending dirty data when the disk is idle.
+			 * (Writeback is not postponed by writes, only by reads.)
+			 */
+			if (unlikely(laptop_mode))
+				disk_is_spun_up(0);
 			disk_stat_inc(disk, writes);
 			disk_stat_add(disk, write_ticks, duration);
 			break;
diff -puN mm/page-writeback.c~laptop-mode-simplification mm/page-writeback.c
--- 25/mm/page-writeback.c~laptop-mode-simplification	2004-02-16 17:49:27.000000000 -0800
+++ 25-akpm/mm/page-writeback.c	2004-02-16 17:49:27.000000000 -0800
@@ -206,17 +206,6 @@ static void balance_dirty_pages(struct a
 	if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
 		dirty_exceeded = 0;
 
-	if (unlikely(laptop_mode) && pages_written > 0) {
-		/*
-		 * Schedule full writeout to happen soon. We don't postpone
-		 * previously scheduled full writeouts, otherwise a writing
-		 * process throttled by balance_dirty_pages will be able to
-		 * postpone the full writeout indefinitely, keeping the disk
-		 * spun up as a result.
-		 */
-		disk_is_spun_up(0);
-	}
-
 	if (!unlikely(laptop_mode) && !writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
 		pdflush_operation(background_writeout, 0);
 }
@@ -311,7 +300,17 @@ int wakeup_bdflush(long nr_pages)
 	return pdflush_operation(background_writeout, nr_pages);
 }
 
-static struct timer_list wb_timer;
+
+static void wb_timer_fn(unsigned long unused);
+
+/*
+ * Both timers share the same handler
+ */
+static struct timer_list wb_timer =
+			TIMER_INITIALIZER(wb_timer_fn, 0, 0);
+static struct timer_list laptop_mode_wb_timer =
+			TIMER_INITIALIZER(wb_timer_fn, 0, 0);
+
 
 /*
  * Periodic writeback of "old" data.
@@ -368,15 +367,12 @@ static void wb_kupdate(unsigned long arg
 	}
 	if (time_before(next_jif, jiffies + HZ))
 		next_jif = jiffies + HZ;
-	if (laptop_mode) {
-		sync_inodes(0);
-		sync_filesystems(0);
-		DQUOT_SYNC(NULL);
-	}
 	if (dirty_writeback_centisecs)
 		mod_timer(&wb_timer, next_jif);
+	del_timer(&laptop_mode_wb_timer); /* May have been set as a result of our writes. */
 }
 
+
 /*
  * sysctl handler for /proc/sys/vm/dirty_writeback_centisecs
  */
@@ -393,19 +389,6 @@ int dirty_writeback_centisecs_handler(ct
 	return 0;
 }
 
-static void wb_timer_fn(unsigned long unused)
-{
-	if (pdflush_operation(wb_kupdate, 0) < 0)
-		mod_timer(&wb_timer, jiffies + HZ); /* delay 1 second */
-
-}
-
-/*
- * Both timers share the same handler
- */
-static struct timer_list laptop_mode_wb_timer =
-			TIMER_INITIALIZER(wb_timer_fn, 0, 0);
-
 /*
  * We've spun up the disk and we're in laptop mode: schedule writeback
  * of all dirty data in 5 seconds.
@@ -422,6 +405,16 @@ void disk_is_spun_up(int postpone_writeb
 
 
 /*
+ * Handler for wb_timer and laptop_mode_wb_timer.
+ */
+static void wb_timer_fn(unsigned long unused)
+{
+	if (pdflush_operation(wb_kupdate, 0) < 0)
+		mod_timer(&wb_timer, jiffies + HZ); /* delay 1 second */
+}
+
+
+/*
  * If ratelimit_pages is too high then we can get into dirty-data overload
  * if a large number of processes all perform writes at the same time.
  * If it is too low then SMP machines will call the (expensive) get_page_state
@@ -480,10 +473,7 @@ void __init page_writeback_init(void)
 		vm_dirty_ratio /= 100;
 	}
 
-	init_timer(&wb_timer);
 	wb_timer.expires = jiffies + (dirty_writeback_centisecs * HZ) / 100;
-	wb_timer.data = 0;
-	wb_timer.function = wb_timer_fn;
 	add_timer(&wb_timer);
 
 	set_ratelimit();

_