Skip to content

Commit a7e8f7f

Browse files
Tetsuo HandaMike Snitzer
authored andcommitted
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/[email protected] Signed-off-by: Tetsuo Handa <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 0b22ff5 commit a7e8f7f

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

drivers/md/dm-mpath.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <linux/atomic.h>
2929
#include <linux/blk-mq.h>
3030

31+
static struct workqueue_struct *dm_mpath_wq;
32+
3133
#define DM_MSG_PREFIX "multipath"
3234
#define DM_PG_INIT_DELAY_MSECS 2000
3335
#define DM_PG_INIT_DELAY_DEFAULT ((unsigned int) -1)
@@ -1353,7 +1355,7 @@ static int fail_path(struct pgpath *pgpath)
13531355
dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti,
13541356
pgpath->path.dev->name, atomic_read(&m->nr_valid_paths));
13551357

1356-
schedule_work(&m->trigger_event);
1358+
queue_work(dm_mpath_wq, &m->trigger_event);
13571359

13581360
enable_nopath_timeout(m);
13591361

@@ -2205,12 +2207,11 @@ static struct target_type multipath_target = {
22052207

22062208
static int __init dm_multipath_init(void)
22072209
{
2208-
int r;
2210+
int r = -ENOMEM;
22092211

22102212
kmultipathd = alloc_workqueue("kmpathd", WQ_MEM_RECLAIM, 0);
22112213
if (!kmultipathd) {
22122214
DMERR("failed to create workqueue kmpathd");
2213-
r = -ENOMEM;
22142215
goto bad_alloc_kmultipathd;
22152216
}
22162217

@@ -2224,10 +2225,15 @@ static int __init dm_multipath_init(void)
22242225
WQ_MEM_RECLAIM);
22252226
if (!kmpath_handlerd) {
22262227
DMERR("failed to create workqueue kmpath_handlerd");
2227-
r = -ENOMEM;
22282228
goto bad_alloc_kmpath_handlerd;
22292229
}
22302230

2231+
dm_mpath_wq = alloc_workqueue("dm_mpath_wq", 0, 0);
2232+
if (!dm_mpath_wq) {
2233+
DMERR("failed to create workqueue dm_mpath_wq");
2234+
goto bad_alloc_dm_mpath_wq;
2235+
}
2236+
22312237
r = dm_register_target(&multipath_target);
22322238
if (r < 0) {
22332239
DMERR("request-based register failed %d", r);
@@ -2238,6 +2244,8 @@ static int __init dm_multipath_init(void)
22382244
return 0;
22392245

22402246
bad_register_target:
2247+
destroy_workqueue(dm_mpath_wq);
2248+
bad_alloc_dm_mpath_wq:
22412249
destroy_workqueue(kmpath_handlerd);
22422250
bad_alloc_kmpath_handlerd:
22432251
destroy_workqueue(kmultipathd);
@@ -2247,6 +2255,7 @@ static int __init dm_multipath_init(void)
22472255

22482256
static void __exit dm_multipath_exit(void)
22492257
{
2258+
destroy_workqueue(dm_mpath_wq);
22502259
destroy_workqueue(kmpath_handlerd);
22512260
destroy_workqueue(kmultipathd);
22522261

drivers/md/dm-raid1.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <linux/dm-kcopyd.h>
2121
#include <linux/dm-region-hash.h>
2222

23+
static struct workqueue_struct *dm_raid1_wq;
24+
2325
#define DM_MSG_PREFIX "raid1"
2426

2527
#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)
251253
DMWARN("All sides of mirror have failed.");
252254

253255
out:
254-
schedule_work(&ms->trigger_event);
256+
queue_work(dm_raid1_wq, &ms->trigger_event);
255257
}
256258

257259
static int mirror_flush(struct dm_target *ti)
@@ -1496,22 +1498,28 @@ static struct target_type mirror_target = {
14961498

14971499
static int __init dm_mirror_init(void)
14981500
{
1499-
int r;
1501+
int r = -ENOMEM;
1502+
1503+
dm_raid1_wq = alloc_workqueue("dm_raid1_wq", 0, 0);
1504+
if (!dm_raid1_wq)
1505+
goto bad_target;
15001506

15011507
r = dm_register_target(&mirror_target);
15021508
if (r < 0) {
1503-
DMERR("Failed to register mirror target");
1509+
destroy_workqueue(dm_raid1_wq);
15041510
goto bad_target;
15051511
}
15061512

15071513
return 0;
15081514

15091515
bad_target:
1516+
DMERR("Failed to register mirror target");
15101517
return r;
15111518
}
15121519

15131520
static void __exit dm_mirror_exit(void)
15141521
{
1522+
destroy_workqueue(dm_raid1_wq);
15151523
dm_unregister_target(&mirror_target);
15161524
}
15171525

drivers/md/dm-stripe.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <linux/slab.h>
1717
#include <linux/log2.h>
1818

19+
static struct workqueue_struct *dm_stripe_wq;
20+
1921
#define DM_MSG_PREFIX "striped"
2022
#define DM_IO_ERROR_THRESHOLD 15
2123

@@ -428,7 +430,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
428430
atomic_inc(&(sc->stripe[i].error_count));
429431
if (atomic_read(&(sc->stripe[i].error_count)) <
430432
DM_IO_ERROR_THRESHOLD)
431-
schedule_work(&sc->trigger_event);
433+
queue_work(dm_stripe_wq, &sc->trigger_event);
432434
}
433435

434436
return DM_ENDIO_DONE;
@@ -481,14 +483,20 @@ int __init dm_stripe_init(void)
481483
{
482484
int r;
483485

486+
dm_stripe_wq = alloc_workqueue("dm_stripe_wq", 0, 0);
487+
if (!dm_stripe_wq)
488+
return -ENOMEM;
484489
r = dm_register_target(&stripe_target);
485-
if (r < 0)
490+
if (r < 0) {
491+
destroy_workqueue(dm_stripe_wq);
486492
DMWARN("target registration failed");
493+
}
487494

488495
return r;
489496
}
490497

491498
void dm_stripe_exit(void)
492499
{
493500
dm_unregister_target(&stripe_target);
501+
destroy_workqueue(dm_stripe_wq);
494502
}

0 commit comments

Comments
 (0)