dm: update targets using system workqueues to use a local workqueue
Flushing system-wide workqueues is dangerous and will be forbidden. Use a local workqueue in dm-mpath.c, dm-raid1.c, and dm-stripe.c. Link: https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@I-love.SAKURA.ne.jp Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
This commit is contained in:
parent
0b22ff5360
commit
a7e8f7fbe2
@ -28,6 +28,8 @@
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/blk-mq.h>
|
||||
|
||||
static struct workqueue_struct *dm_mpath_wq;
|
||||
|
||||
#define DM_MSG_PREFIX "multipath"
|
||||
#define DM_PG_INIT_DELAY_MSECS 2000
|
||||
#define DM_PG_INIT_DELAY_DEFAULT ((unsigned int) -1)
|
||||
@ -1353,7 +1355,7 @@ static int fail_path(struct pgpath *pgpath)
|
||||
dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti,
|
||||
pgpath->path.dev->name, atomic_read(&m->nr_valid_paths));
|
||||
|
||||
schedule_work(&m->trigger_event);
|
||||
queue_work(dm_mpath_wq, &m->trigger_event);
|
||||
|
||||
enable_nopath_timeout(m);
|
||||
|
||||
@ -2205,12 +2207,11 @@ static struct target_type multipath_target = {
|
||||
|
||||
static int __init dm_multipath_init(void)
|
||||
{
|
||||
int r;
|
||||
int r = -ENOMEM;
|
||||
|
||||
kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0);
|
||||
if (!kmultipathd) {
|
||||
DMERR("failed to create workqueue kmpathd");
|
||||
r = -ENOMEM;
|
||||
goto bad_alloc_kmultipathd;
|
||||
}
|
||||
|
||||
@ -2224,10 +2225,15 @@ static int __init dm_multipath_init(void)
|
||||
WQ_MEM_RECLAIM);
|
||||
if (!kmpath_handlerd) {
|
||||
DMERR("failed to create workqueue kmpath_handlerd");
|
||||
r = -ENOMEM;
|
||||
goto bad_alloc_kmpath_handlerd;
|
||||
}
|
||||
|
||||
dm_mpath_wq = alloc_workqueue("dm_mpath_wq", 0, 0);
|
||||
if (!dm_mpath_wq) {
|
||||
DMERR("failed to create workqueue dm_mpath_wq");
|
||||
goto bad_alloc_dm_mpath_wq;
|
||||
}
|
||||
|
||||
r = dm_register_target(&multipath_target);
|
||||
if (r < 0) {
|
||||
DMERR("request-based register failed %d", r);
|
||||
@ -2238,6 +2244,8 @@ static int __init dm_multipath_init(void)
|
||||
return 0;
|
||||
|
||||
bad_register_target:
|
||||
destroy_workqueue(dm_mpath_wq);
|
||||
bad_alloc_dm_mpath_wq:
|
||||
destroy_workqueue(kmpath_handlerd);
|
||||
bad_alloc_kmpath_handlerd:
|
||||
destroy_workqueue(kmultipathd);
|
||||
@ -2247,6 +2255,7 @@ bad_alloc_kmultipathd:
|
||||
|
||||
static void __exit dm_multipath_exit(void)
|
||||
{
|
||||
destroy_workqueue(dm_mpath_wq);
|
||||
destroy_workqueue(kmpath_handlerd);
|
||||
destroy_workqueue(kmultipathd);
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/dm-kcopyd.h>
|
||||
#include <linux/dm-region-hash.h>
|
||||
|
||||
static struct workqueue_struct *dm_raid1_wq;
|
||||
|
||||
#define DM_MSG_PREFIX "raid1"
|
||||
|
||||
#define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */
|
||||
@ -251,7 +253,7 @@ static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type)
|
||||
DMWARN("All sides of mirror have failed.");
|
||||
|
||||
out:
|
||||
schedule_work(&ms->trigger_event);
|
||||
queue_work(dm_raid1_wq, &ms->trigger_event);
|
||||
}
|
||||
|
||||
static int mirror_flush(struct dm_target *ti)
|
||||
@ -1496,22 +1498,28 @@ static struct target_type mirror_target = {
|
||||
|
||||
static int __init dm_mirror_init(void)
|
||||
{
|
||||
int r;
|
||||
int r = -ENOMEM;
|
||||
|
||||
dm_raid1_wq = alloc_workqueue("dm_raid1_wq", 0, 0);
|
||||
if (!dm_raid1_wq)
|
||||
goto bad_target;
|
||||
|
||||
r = dm_register_target(&mirror_target);
|
||||
if (r < 0) {
|
||||
DMERR("Failed to register mirror target");
|
||||
destroy_workqueue(dm_raid1_wq);
|
||||
goto bad_target;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
bad_target:
|
||||
DMERR("Failed to register mirror target");
|
||||
return r;
|
||||
}
|
||||
|
||||
static void __exit dm_mirror_exit(void)
|
||||
{
|
||||
destroy_workqueue(dm_raid1_wq);
|
||||
dm_unregister_target(&mirror_target);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/log2.h>
|
||||
|
||||
static struct workqueue_struct *dm_stripe_wq;
|
||||
|
||||
#define DM_MSG_PREFIX "striped"
|
||||
#define DM_IO_ERROR_THRESHOLD 15
|
||||
|
||||
@ -428,7 +430,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
|
||||
atomic_inc(&(sc->stripe[i].error_count));
|
||||
if (atomic_read(&(sc->stripe[i].error_count)) <
|
||||
DM_IO_ERROR_THRESHOLD)
|
||||
schedule_work(&sc->trigger_event);
|
||||
queue_work(dm_stripe_wq, &sc->trigger_event);
|
||||
}
|
||||
|
||||
return DM_ENDIO_DONE;
|
||||
@ -481,9 +483,14 @@ int __init dm_stripe_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
dm_stripe_wq = alloc_workqueue("dm_stripe_wq", 0, 0);
|
||||
if (!dm_stripe_wq)
|
||||
return -ENOMEM;
|
||||
r = dm_register_target(&stripe_target);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
destroy_workqueue(dm_stripe_wq);
|
||||
DMWARN("target registration failed");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -491,4 +498,5 @@ int __init dm_stripe_init(void)
|
||||
void dm_stripe_exit(void)
|
||||
{
|
||||
dm_unregister_target(&stripe_target);
|
||||
destroy_workqueue(dm_stripe_wq);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user