Multipath: dispatch_failed_ios can sleep. It should not disrupt other users of the default work queue. Under heavy load or group/ps initializations on a single processor machine, this conflict becomes painful. [Mike Christie] --- diff/drivers/md/dm-mpath.c 2004-04-06 15:54:57.053833320 +0100 +++ source/drivers/md/dm-mpath.c 2004-04-06 15:54:58.885554856 +0100 @@ -285,6 +285,8 @@ static int map_io(struct multipath *m, s /*----------------------------------------------------------------- * The multipath daemon is responsible for resubmitting failed ios. *---------------------------------------------------------------*/ +struct workqueue_struct *kmultipathd; + static void dispatch_failed_ios(void *data) { struct multipath *m = (struct multipath *) data; @@ -592,7 +594,7 @@ static int do_end_io(struct multipath *m bio_list_add(&m->failed_ios, bio); spin_unlock(&m->lock); - schedule_work(&m->dispatch_failed); + queue_work(kmultipathd, &m->dispatch_failed); return 1; /* io not complete */ } @@ -707,6 +709,13 @@ int __init dm_multipath_init(void) return r; } + kmultipathd = create_workqueue("kmpathd"); + if (!kmultipathd) { + dm_unregister_path_selectors(); + dm_unregister_target(&multipath_target); + kmem_cache_destroy(_details_cache); + } + DMINFO("dm_multipath v0.2.0"); return r; } @@ -715,6 +724,7 @@ void __exit dm_multipath_exit(void) { int r; + destroy_workqueue(kmultipathd); dm_unregister_path_selectors(); r = dm_unregister_target(&multipath_target); if (r < 0)