Change multipath daemon to use dm-daemon.c. Declare a jiffy_t type in dm.h. Let daemon work functions return a sleep duration hint (interface change only, hint not acted upon yet). --- diff/drivers/md/dm-daemon.h 2003-12-29 10:12:47.000000000 +0000 +++ source/drivers/md/dm-daemon.h 2003-12-29 10:15:50.000000000 +0000 @@ -10,8 +10,12 @@ #include #include +/* + * The daemons work function returns a *hint* as to when it + * should next be woken up. + */ struct dm_daemon { - void (*fn)(void); + jiffy_t (*fn)(void); char name[16]; atomic_t please_die; struct semaphore start_lock; --- diff/drivers/md/dm-mpath.c 2003-12-29 10:15:43.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2003-12-29 10:15:50.000000000 +0000 @@ -10,6 +10,7 @@ */ #include "dm.h" +#include "dm-daemon.h" #include #include @@ -314,20 +315,14 @@ kfree(mc); } -/******************************************************************** - * - * Daemon (FIXME: use dm-daemon.c) - */ +/*----------------------------------------------------------------- + * The multipath daemon is responsible for periodically + * retestings failed paths. + *---------------------------------------------------------------*/ +static struct dm_daemon _kmultipathd; static LIST_HEAD(_mc_jobs); static spinlock_t _job_lock = SPIN_LOCK_UNLOCKED; -static DECLARE_WAIT_QUEUE_HEAD(_multipathd_queue); - -/* Wake daemon up */ -static inline void wake_multipathd(void) -{ - wake_up_interruptible(&_multipathd_queue); -} /* Submit an IO and store the IO timestamp */ static inline void _make_request(struct multipath_io *io) @@ -418,7 +413,7 @@ _reset_failed(io); spin_unlock_irqrestore(&mc->lock, flags); - wake_multipathd(); + dm_daemon_wake(&_kmultipathd); } _reset_scrub_io(io->path); @@ -474,9 +469,11 @@ return 0; } -/* Check if paths need to get a test io queued either for - automatic failure recovery or scrubbing of idle paths */ -static inline long _do_scrubbing(void) +/* + * Check if paths need to get a test io queued either for + * automatic failure recovery or scrubbing of idle paths. + */ +static inline long do_scrubbing(void) { unsigned long flags; long timeout = MAX_SCHEDULE_TIMEOUT; @@ -501,78 +498,18 @@ return timeout; } -/* Multipathd does this every time it runs */ -static inline long _do_work(void) +/* Multipathd does this every time it runs, returns a sleep duration hint */ +static inline jiffy_t do_work(void) { - _do_ios(); - _do_table_events(); - return _do_scrubbing(); + do_ios(); + do_table_events(); + return do_scrubbing(); } -static DECLARE_MUTEX(_start_lock); -static DECLARE_MUTEX(_run_lock); -static unsigned long _multipathd_flags = 0; -#define RUN 1 - -/* The multipath daemon core */ -static int multipathd(void *arg) -{ - DECLARE_WAITQUEUE(wq, current); - - set_current_state(TASK_RUNNING); - daemonize(); - strcpy(current->comm, "multipathd"); - - add_wait_queue(&_multipathd_queue, &wq); - - down(&_run_lock); - up(&_start_lock); - - while (test_bit(RUN, &_multipathd_flags)) { - long timeout = _do_work(); - - if (timeout) - interruptible_sleep_on_timeout(&_multipathd_queue, - timeout); - } - - remove_wait_queue(&_multipathd_queue, &wq); - - up(&_run_lock); - - return 0; -} - -static inline int start_daemon(void) -{ - static pid_t pid = 0; - - down(&_start_lock); - - set_bit(RUN, &_multipathd_flags); - pid = kernel_thread(multipathd, NULL, 0); - if (pid <= 0) { - DMERR("Failed to start multipathd thread"); - return -EAGAIN; - } - - /* Wait for the daemon to up this mutex */ - down(&_start_lock); - up(&_start_lock); - - return 0; -} - -static inline void stop_daemon(void) -{ - clear_bit(RUN, &_multipathd_flags); - wake_multipathd(); - - /* Wait for thread exit (Don't need to up mutex. We exit anyway) */ - down(&_run_lock); -} -/* End daemon code */ +/*----------------------------------------------------------------- + * Constructor/argument parsing + *---------------------------------------------------------------*/ #define ARG_FORMAT "%d" @@ -788,7 +725,7 @@ /* Map the IO to this new path */ _map(io, path); push(&mc->io_jobs, &io->list, &mc->lock); - wake_multipathd(); + dm_daemon_wake(&_kmultipathd); return 1; /* Handle later */ } @@ -818,7 +755,7 @@ struct multipath_c *mc = (struct multipath_c *) ti->private; atomic_set(&mc->suspended, 0); - wake_multipathd(); + dm_daemon_wake(&_kmultipathd); } /* Multipath mapping */ @@ -954,7 +891,7 @@ if (r && r != -EEXIST) goto bad_ps; - r = start_daemon(); + r = dm_daemon_start(&_kmultipathd, "kmultipathd", do_work); if (!r) { DMINFO("dm_multipath v0.2.0 (%d io contexts preallocated)", ios); @@ -978,7 +915,7 @@ { int r; - stop_daemon(); + dm_daemon_stop(&_kmultipathd); dm_unregister_path_selectors(); r = dm_unregister_target(&multipath_target); if (r < 0) --- diff/drivers/md/dm.h 2003-12-29 10:12:47.000000000 +0000 +++ source/drivers/md/dm.h 2003-12-29 10:15:50.000000000 +0000 @@ -20,6 +20,12 @@ #define DMINFO(f, x...) printk(KERN_INFO DM_NAME ": " f "\n" , ## x) /* + * FIXME: There must be a better place for this. + */ +typedef typeof(jiffies) jiffy_t; + + +/* * FIXME: I think this should be with the definition of sector_t * in types.h. */