replace kupdate and bdflush with pdflush
PATCH 1/1 replace kupdate and bdflush with pdflush
Pretty simple.
- use a timer to kick off a pdflush thread every five seconds to run the kupdate code.
- wakeup_bdflush() kicks off a pdflush thread to run the current bdflush function.
There's some loss of functionality here - the ability to tune the writeback periods. The numbers are hardwired at present. But the intent is that buffer-based writeback disappears altogether. New mechanisms for tuning the writeback will need to be introduced.
Patch against 2.5.8-pre3+ratcache+readahead+pageprivate+pdflush+pdflush_inodes
fs/buffer.c renamed from fs/buffer.c~dallocbase-50-pdflush_buffers +28 -112
@@ -46,7 +46,6 @@#include <linux/iobuf.h> #include <linux/highmem.h> #include <linux/module.h> -#include <linux/completion.h> #include <linux/compiler.h> #include <asm/uaccess.h>
@@ -2603,21 +2602,6 @@ void __init buffer_init(unsigned long me } - -/* ====================== bdflush support =================== */ - -/* This is a simple kernel daemon, whose job it is to provide a dynamic -* response to dirty buffers. Once this process is activated, we write back -* a limited number of buffers to the disks and then go back to sleep again. -*/ - -DECLARE_WAIT_QUEUE_HEAD (bdflush_wait); - -void wakeup_bdflush (void ) -{ -wake_up_interruptible (&bdflush_wait); -} -/* * Here we attempt to write back old buffers. We also try to flush inodes * and supers as well, since this function is essentially "update", and
@@ -2626,7 +2610,7 @@ void wakeup_bdflush(void)* and superblocks so that we could write back only the old ones as well */ -static int sync_old_buffers (void ) +static void sync_old_buffers (unsigned long dummy) {lock_kernel ();sync_unlocked_inodes ();
@@ -2642,10 +2626,9 @@ static int sync_old_buffers(void)break ;if (write_some_buffers (NULL ))continue ; -return 0 ; +return ; }spin_unlock (&lru_list_lock); -return 0 ; }int block_sync_page (struct page *page)
@@ -2707,112 +2690,45 @@ asmlinkage long sys_bdflush(int func, loreturn 0 ; } -/* -* This is the actual bdflush daemon itself. It used to be started from -* the syscall above, but now we launch it ourselves internally with -* kernel_thread(...) directly after the first thread in init/main.c -*/ -int bdflush (void *startup) +static void bdflush (unsigned long pexclude) { -struct task_struct *tsk = current; - -/* -* We have a bare-bones task_struct, and really should fill -* in a few more things so "top" and /proc/2/{exe,root,cwd} -* display semi-sane things. Not real crucial though... -*/ - - tsk->session =1 ; - tsk->pgrp =1 ; -strcpy (tsk->comm,"bdflush" ); - -/* avoid getting signals */ -spin_lock_irq (&tsk->sigmask_lock); -flush_signals (tsk); -sigfillset (&tsk->blocked); -recalc_sigpending (); -spin_unlock_irq (&tsk->sigmask_lock); - -complete ((struct completion *)startup); - -for (;;) { -CHECK_EMERGENCY_SYNC - +while (balance_dirty_state () >=0 ) {spin_lock (&lru_list_lock); -if (!write_some_buffers (NULL ) ||balance_dirty_state () <0 ) { -wait_for_some_buffers (NULL ); -interruptible_sleep_on (&bdflush_wait); - } +if (write_some_buffers (NULL ) ==0 ) +break ; } +clear_bit (0 , (unsigned long *)pexclude); } -/* -* This is the kernel update daemon. It was used to live in userspace -* but since it's need to run safely we want it unkillable by mistake. -* You don't need to change your userspace configuration since -* the userspace `update` will do_exit(0) at the first sys_bdflush(). -*/ -int kupdate (void *startup) +void wakeup_bdflush (void ) { -struct task_struct * tsk = current; -int interval; - - tsk->session =1 ; - tsk->pgrp =1 ; -strcpy (tsk->comm,"kupdated" ); - -/* sigstop and sigcont will stop and wakeup kupdate */ -spin_lock_irq (&tsk->sigmask_lock); -sigfillset (&tsk->blocked); -siginitsetinv (¤t->blocked,sigmask (SIGCONT ) |sigmask (SIGSTOP )); -recalc_sigpending (); -spin_unlock_irq (&tsk->sigmask_lock); +static unsigned long exclude; -complete ((struct completion *)startup); - -for (;;) { -wait_for_some_buffers (NULL ); - -/* update interval */ - interval = bdf_prm.b_un.interval; -if (interval) { - tsk->state =TASK_INTERRUPTIBLE ; -schedule_timeout (interval); - }else { - stop_kupdate: - tsk->state =TASK_STOPPED ; -schedule ();/* wait for SIGCONT */ - } -/* check for sigstop */ -if (signal_pending (tsk)) { -int stopped =0 ; -spin_lock_irq (&tsk->sigmask_lock); -if (sigismember (&tsk->pending.signal,SIGSTOP )) { -sigdelset (&tsk->pending.signal,SIGSTOP ); - stopped =1 ; - } -recalc_sigpending (); -spin_unlock_irq (&tsk->sigmask_lock); -if (stopped) - goto stop_kupdate; - } -#ifdef DEBUG -printk (KERN_DEBUG "kupdate() activated...\n" ); -#endif -sync_old_buffers (); +if (!test_and_set_bit (0 , &exclude)) { +if (pdflush_operation (bdflush, (unsigned long )&exclude)) +clear_bit (0 , &exclude); } } -static int __init bdflush_init (void ) +/* +* kupdate +*/ +static struct timer_list kupdate_timer; +static void kupdate_handler (unsigned long dummy) { -static struct completion startup__initdata =COMPLETION_INITIALIZER (startup); +pdflush_operation (sync_old_buffers,0 ); +mod_timer (&kupdate_timer, jiffies + bdf_prm.b_un.interval); +} -kernel_thread (bdflush, &startup,CLONE_FS |CLONE_FILES |CLONE_SIGNAL ); -wait_for_completion (&startup); -kernel_thread (kupdate, &startup,CLONE_FS |CLONE_FILES |CLONE_SIGNAL ); -wait_for_completion (&startup); +static int __init kupdate_init (void ) +{ +init_timer (&kupdate_timer); + kupdate_timer.expires = jiffies + bdf_prm.b_un.interval; + kupdate_timer.data =0 ; + kupdate_timer.function = kupdate_handler; +add_timer (&kupdate_timer);return 0 ; } -module_init (bdflush_init) +module_init (kupdate_init)
-