aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2010-05-21 14:00:35 -0400
committerJens Axboe <jens.axboe@oracle.com>2010-05-21 14:00:35 -0400
commit6423104b6a1e6f0c18be60e8c33f02d263331d5e (patch)
treee22957400e9679bf82b62e03d6bd831181053945
parentf9eadbbd424c083b8005c7b738f644611b9ef489 (diff)
writeback: fixups for !dirty_writeback_centisecs
Commit 69b62d01 fixed up most of the places where we would enter busy schedule() spins when disabling the periodic background writeback. This fixes up the sb timer so that it doesn't get hammered on with the delay disabled, and ensures that it gets rearmed if needed when /proc/sys/vm/dirty_writeback_centisecs gets modified. bdi_forker_task() also needs to check for !dirty_writeback_centisecs and use schedule() appropriately, fix that up too. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--include/linux/backing-dev.h1
-rw-r--r--mm/backing-dev.c15
-rw-r--r--mm/page-writeback.c1
3 files changed, 12 insertions, 5 deletions
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index ff8bac63213f..e6e0cb5437e6 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -109,6 +109,7 @@ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
109 long nr_pages, int sb_locked); 109 long nr_pages, int sb_locked);
110int bdi_writeback_task(struct bdi_writeback *wb); 110int bdi_writeback_task(struct bdi_writeback *wb);
111int bdi_has_dirty_io(struct backing_dev_info *bdi); 111int bdi_has_dirty_io(struct backing_dev_info *bdi);
112void bdi_arm_supers_timer(void);
112 113
113extern spinlock_t bdi_lock; 114extern spinlock_t bdi_lock;
114extern struct list_head bdi_list; 115extern struct list_head bdi_list;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 707d0dc6da0f..660a87a22511 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -48,7 +48,6 @@ static struct timer_list sync_supers_timer;
48 48
49static int bdi_sync_supers(void *); 49static int bdi_sync_supers(void *);
50static void sync_supers_timer_fn(unsigned long); 50static void sync_supers_timer_fn(unsigned long);
51static void arm_supers_timer(void);
52 51
53static void bdi_add_default_flusher_task(struct backing_dev_info *bdi); 52static void bdi_add_default_flusher_task(struct backing_dev_info *bdi);
54 53
@@ -252,7 +251,7 @@ static int __init default_bdi_init(void)
252 251
253 init_timer(&sync_supers_timer); 252 init_timer(&sync_supers_timer);
254 setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0); 253 setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
255 arm_supers_timer(); 254 bdi_arm_supers_timer();
256 255
257 err = bdi_init(&default_backing_dev_info); 256 err = bdi_init(&default_backing_dev_info);
258 if (!err) 257 if (!err)
@@ -374,10 +373,13 @@ static int bdi_sync_supers(void *unused)
374 return 0; 373 return 0;
375} 374}
376 375
377static void arm_supers_timer(void) 376void bdi_arm_supers_timer(void)
378{ 377{
379 unsigned long next; 378 unsigned long next;
380 379
380 if (!dirty_writeback_interval)
381 return;
382
381 next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies; 383 next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
382 mod_timer(&sync_supers_timer, round_jiffies_up(next)); 384 mod_timer(&sync_supers_timer, round_jiffies_up(next));
383} 385}
@@ -385,7 +387,7 @@ static void arm_supers_timer(void)
385static void sync_supers_timer_fn(unsigned long unused) 387static void sync_supers_timer_fn(unsigned long unused)
386{ 388{
387 wake_up_process(sync_supers_tsk); 389 wake_up_process(sync_supers_tsk);
388 arm_supers_timer(); 390 bdi_arm_supers_timer();
389} 391}
390 392
391static int bdi_forker_task(void *ptr) 393static int bdi_forker_task(void *ptr)
@@ -428,7 +430,10 @@ static int bdi_forker_task(void *ptr)
428 430
429 spin_unlock_bh(&bdi_lock); 431 spin_unlock_bh(&bdi_lock);
430 wait = msecs_to_jiffies(dirty_writeback_interval * 10); 432 wait = msecs_to_jiffies(dirty_writeback_interval * 10);
431 schedule_timeout(wait); 433 if (wait)
434 schedule_timeout(wait);
435 else
436 schedule();
432 try_to_freeze(); 437 try_to_freeze();
433 continue; 438 continue;
434 } 439 }
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 53b2fcf2d283..0d7bbe859550 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -690,6 +690,7 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write,
690 void __user *buffer, size_t *length, loff_t *ppos) 690 void __user *buffer, size_t *length, loff_t *ppos)
691{ 691{
692 proc_dointvec(table, write, buffer, length, ppos); 692 proc_dointvec(table, write, buffer, length, ppos);
693 bdi_arm_supers_timer();
693 return 0; 694 return 0;
694} 695}
695 696