diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2022-04-20 08:12:26 +0300 |
---|---|---|
committer | Mike Snitzer <snitzer@kernel.org> | 2023-02-14 22:23:08 +0300 |
commit | a7e8f7fbe2adc132c0222fea96a18610337e2775 (patch) | |
tree | 0ab392cd3d53f2da2098815c057d2c8ef895117c /drivers/md | |
parent | 0b22ff5360f5c4e11050b89206370fdf7dc0a226 (diff) | |
download | linux-a7e8f7fbe2adc132c0222fea96a18610337e2775.tar.xz |
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>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-mpath.c | 17 | ||||
-rw-r--r-- | drivers/md/dm-raid1.c | 14 | ||||
-rw-r--r-- | drivers/md/dm-stripe.c | 12 |
3 files changed, 34 insertions, 9 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 371a38bc0c61..61ab1a8d2c9c 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -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); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index b20c0ad13712..bc417a5e5b89 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -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); } diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 4335828a43e4..8d6951157106 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -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); } |