writeback: fixups for !dirty_writeback_centisecs
authorJens Axboe <jens.axboe@oracle.com>
Fri, 21 May 2010 18:00:35 +0000 (20:00 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 21 May 2010 18:00:35 +0000 (20:00 +0200)
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>
include/linux/backing-dev.h
mm/backing-dev.c
mm/page-writeback.c

index ff8bac63213f95949df83f704d0b2a306022b11e..e6e0cb5437e6ce6d00a7fcebe7756b9fdac92480 100644 (file)
@@ -109,6 +109,7 @@ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
                                long nr_pages, int sb_locked);
 int bdi_writeback_task(struct bdi_writeback *wb);
 int bdi_has_dirty_io(struct backing_dev_info *bdi);
+void bdi_arm_supers_timer(void);
 
 extern spinlock_t bdi_lock;
 extern struct list_head bdi_list;
index 707d0dc6da0f59a5730f613e2980fefc154c807a..660a87a2251189e00b83a954ec6ab13679f38bc1 100644 (file)
@@ -48,7 +48,6 @@ static struct timer_list sync_supers_timer;
 
 static int bdi_sync_supers(void *);
 static void sync_supers_timer_fn(unsigned long);
-static void arm_supers_timer(void);
 
 static void bdi_add_default_flusher_task(struct backing_dev_info *bdi);
 
@@ -252,7 +251,7 @@ static int __init default_bdi_init(void)
 
        init_timer(&sync_supers_timer);
        setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
-       arm_supers_timer();
+       bdi_arm_supers_timer();
 
        err = bdi_init(&default_backing_dev_info);
        if (!err)
@@ -374,10 +373,13 @@ static int bdi_sync_supers(void *unused)
        return 0;
 }
 
-static void arm_supers_timer(void)
+void bdi_arm_supers_timer(void)
 {
        unsigned long next;
 
+       if (!dirty_writeback_interval)
+               return;
+
        next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
        mod_timer(&sync_supers_timer, round_jiffies_up(next));
 }
@@ -385,7 +387,7 @@ static void arm_supers_timer(void)
 static void sync_supers_timer_fn(unsigned long unused)
 {
        wake_up_process(sync_supers_tsk);
-       arm_supers_timer();
+       bdi_arm_supers_timer();
 }
 
 static int bdi_forker_task(void *ptr)
@@ -428,7 +430,10 @@ static int bdi_forker_task(void *ptr)
 
                        spin_unlock_bh(&bdi_lock);
                        wait = msecs_to_jiffies(dirty_writeback_interval * 10);
-                       schedule_timeout(wait);
+                       if (wait)
+                               schedule_timeout(wait);
+                       else
+                               schedule();
                        try_to_freeze();
                        continue;
                }
index 53b2fcf2d28365eec65776f7bebe4e20a38de5a1..0d7bbe859550786970845fc55f7700c385386539 100644 (file)
@@ -690,6 +690,7 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write,
        void __user *buffer, size_t *length, loff_t *ppos)
 {
        proc_dointvec(table, write, buffer, length, ppos);
+       bdi_arm_supers_timer();
        return 0;
 }