From: Bart Samwel 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(); _