Use work_queues rather than dm-daemon. [Mike Christie/Joe Thornber] --- diff/drivers/md/dm-mpath.c 2004-02-18 09:17:31.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2004-02-18 09:17:41.000000000 +0000 @@ -5,7 +5,6 @@ */ #include "dm.h" -#include "dm-daemon.h" #include "dm-path-selector.h" #include "dm-bio-list.h" @@ -16,6 +15,7 @@ #include #include #include +#include #include /* FIXME: get rid of these */ @@ -60,10 +60,15 @@ struct path *current_path; unsigned current_count; + struct work_struct dispatch_failed; struct bio_list failed_ios; - unsigned trigger_event; + + struct work_struct trigger_event; }; +static void dispatch_failed_ios(void *data); +static void trigger_event(void *data); + static struct path *alloc_path(void) { struct path *path = kmalloc(sizeof(*path), GFP_KERNEL); @@ -139,6 +144,8 @@ memset(m, 0, sizeof(*m)); INIT_LIST_HEAD(&m->priority_groups); m->lock = SPIN_LOCK_UNLOCKED; + INIT_WORK(&m->dispatch_failed, dispatch_failed_ios, m); + INIT_WORK(&m->trigger_event, trigger_event, m); } return m; @@ -159,10 +166,7 @@ /*----------------------------------------------------------------- * The multipath daemon is responsible for resubmitting failed ios. *---------------------------------------------------------------*/ -static struct dm_daemon _kmpathd; - -static LIST_HEAD(_mpaths); -static DECLARE_MUTEX(_mpath_lock); +static struct workqueue_struct *_kmpathd_wq; static int __choose_path(struct multipath *m) { @@ -180,7 +184,7 @@ m->current_path = path; m->current_count = MPATH_MIN_IO; -; + return 0; } @@ -214,8 +218,10 @@ return 0; } -static void dispatch_failed_ios(struct multipath *m) +static void dispatch_failed_ios(void *data) { + struct multipath *m = (struct multipath *) data; + int r; unsigned long flags; struct bio *bio = NULL, *next; @@ -241,31 +247,18 @@ bio = next; } + + /* + * FIXME: this now gets called once for each mpath + * target, rather than once per daemon cycle. + */ + blk_run_queues(); } -/* - * Multipathd does this every time it runs, returning a sleep - * duration hint. - */ -static jiffy_t do_work(void) +static void trigger_event(void *data) { - unsigned long flags; - struct multipath *m; - - down(&_mpath_lock); - list_for_each_entry (m, &_mpaths, list) { - dispatch_failed_ios(m); - - /* No locking is needed around this */ - if (m->trigger_event) { - m->trigger_event = 0; - dm_table_event(m->ti->table); - } - } - up(&_mpath_lock); - - blk_run_queues(); - return 0; + struct multipath *m = (struct multipath *) data; + dm_table_event(m->ti->table); } /*----------------------------------------------------------------- @@ -491,10 +484,6 @@ ti->private = m; m->ti = ti; - down(&_mpath_lock); - list_add(&m->list, &_mpaths); - up(&_mpath_lock); - return 0; bad: @@ -505,11 +494,6 @@ static void multipath_dtr(struct dm_target *ti) { struct multipath *m = (struct multipath *) ti->private; - - down(&_mpath_lock); - list_del(&m->list); - up(&_mpath_lock); - free_multipath(m); } @@ -552,11 +536,12 @@ /* FIXME: path->fail_count is brain dead */ if (!path->has_failed && !--path->fail_count) { + m = path->pg->m; + path->has_failed = 1; path->pg->ps->type->fail_path(path->pg->ps, path); - path->pg->m->trigger_event = 1; + queue_work(_kmpathd_wq, &m->trigger_event); - m = path->pg->m; spin_lock(&m->lock); m->nr_valid_paths--; @@ -591,7 +576,7 @@ bio_list_add(&m->failed_ios, bio); spin_unlock(&m->lock); - dm_daemon_wake(&_kmpathd); + queue_work(_kmpathd_wq, &m->dispatch_failed); return 1; /* io not complete */ } @@ -700,8 +685,8 @@ return r; } - r = dm_daemon_start(&_kmpathd, "kpathd", do_work); - if (r) { + _kmpathd_wq = create_workqueue("dm-multipath"); + if (!_kmpathd_wq) { /* FIXME: remove this */ dm_unregister_path_selectors(); dm_unregister_target(&multipath_target); @@ -715,7 +700,7 @@ { int r; - dm_daemon_stop(&_kmpathd); + destroy_workqueue(_kmpathd_wq); dm_unregister_path_selectors(); r = dm_unregister_target(&multipath_target); if (r < 0)