diff -urNp linux-11000/fs/buffer.c linux-11001/fs/buffer.c --- linux-11000/fs/buffer.c +++ linux-11001/fs/buffer.c @@ -92,6 +92,9 @@ static void __refile_buffer(struct buffe /* This is used by some architectures to estimate available memory. */ atomic_t buffermem_pages = ATOMIC_INIT(0); +static unsigned long bdflush_needs_waking; +static struct timer_list bdflush_timer; + /* Here is the parameter block for the bdflush process. If you add or * remove any of the parameters, make sure to update kernel/sysctl.c * and the documentation at linux/Documentation/sysctl/vm.txt. @@ -2819,7 +2822,16 @@ DECLARE_WAIT_QUEUE_HEAD(bdflush_wait); void wakeup_bdflush(void) { - wake_up_interruptible(&bdflush_wait); + /* only do something if a wakup isn't already scheduled */ + if (!test_and_set_bit(0, &bdflush_needs_waking)) { + /* schedule a timer 20 msec from now for bdflush to wake up */ + mod_timer(&bdflush_timer, jiffies + HZ/50); + /* + * do a non-preempting bdflush wakeup as well so that if the system has + * idle time bdflush runs then + */ + wake_up_interruptible_sync(&bdflush_wait); + } } /* @@ -2911,6 +2923,15 @@ asmlinkage long sys_bdflush(int func, lo return 0; } + +static void bdflush_timeout(unsigned long unused) +{ + if (test_and_clear_bit(0,&bdflush_needs_waking)) + wake_up_interruptible(&bdflush_wait); +} + + + /* * This is the actual bdflush daemon itself. It used to be started from * the syscall above, but now we launch it ourselves internally with @@ -2937,6 +2958,15 @@ int bdflush(void *startup) spin_unlock_irq(&tsk->sig->siglock); complete((struct completion *)startup); + + /* + * set up the timer + */ + init_timer(&bdflush_timer); + bdflush_timer.function = bdflush_timeout; + bdflush_timer.expires = jiffies + HZ/50; + add_timer(&bdflush_timer); + /* * FIXME: The ndirty logic here is wrong. It's supposed to @@ -2953,6 +2983,9 @@ int bdflush(void *startup) CHECK_EMERGENCY_SYNC + del_timer(&bdflush_timer); + clear_bit(0, &bdflush_needs_waking); + while (ndirty > 0) { spin_lock(&lru_list_lock); if (!write_some_buffers(NODEV))