aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-mpath.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 43763a0bd096..1e97b3c12bd5 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -101,6 +101,7 @@ typedef int (*action_fn) (struct pgpath *pgpath);
101 101
102static kmem_cache_t *_mpio_cache; 102static kmem_cache_t *_mpio_cache;
103 103
104struct workqueue_struct *kmultipathd;
104static void process_queued_ios(void *data); 105static void process_queued_ios(void *data);
105static void trigger_event(void *data); 106static void trigger_event(void *data);
106 107
@@ -308,7 +309,7 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
308 bio_list_add(&m->queued_ios, bio); 309 bio_list_add(&m->queued_ios, bio);
309 m->queue_size++; 310 m->queue_size++;
310 if (m->pg_init_required || !m->queue_io) 311 if (m->pg_init_required || !m->queue_io)
311 schedule_work(&m->process_queued_ios); 312 queue_work(kmultipathd, &m->process_queued_ios);
312 pgpath = NULL; 313 pgpath = NULL;
313 r = 0; 314 r = 0;
314 } else if (!pgpath) 315 } else if (!pgpath)
@@ -334,7 +335,7 @@ static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
334 335
335 m->queue_if_no_path = queue_if_no_path; 336 m->queue_if_no_path = queue_if_no_path;
336 if (!m->queue_if_no_path) 337 if (!m->queue_if_no_path)
337 schedule_work(&m->process_queued_ios); 338 queue_work(kmultipathd, &m->process_queued_ios);
338 339
339 spin_unlock_irqrestore(&m->lock, flags); 340 spin_unlock_irqrestore(&m->lock, flags);
340 341
@@ -800,7 +801,7 @@ static int fail_path(struct pgpath *pgpath)
800 if (pgpath == m->current_pgpath) 801 if (pgpath == m->current_pgpath)
801 m->current_pgpath = NULL; 802 m->current_pgpath = NULL;
802 803
803 schedule_work(&m->trigger_event); 804 queue_work(kmultipathd, &m->trigger_event);
804 805
805out: 806out:
806 spin_unlock_irqrestore(&m->lock, flags); 807 spin_unlock_irqrestore(&m->lock, flags);
@@ -837,9 +838,9 @@ static int reinstate_path(struct pgpath *pgpath)
837 838
838 m->current_pgpath = NULL; 839 m->current_pgpath = NULL;
839 if (!m->nr_valid_paths++) 840 if (!m->nr_valid_paths++)
840 schedule_work(&m->process_queued_ios); 841 queue_work(kmultipathd, &m->process_queued_ios);
841 842
842 schedule_work(&m->trigger_event); 843 queue_work(kmultipathd, &m->trigger_event);
843 844
844out: 845out:
845 spin_unlock_irqrestore(&m->lock, flags); 846 spin_unlock_irqrestore(&m->lock, flags);
@@ -883,7 +884,7 @@ static void bypass_pg(struct multipath *m, struct priority_group *pg,
883 884
884 spin_unlock_irqrestore(&m->lock, flags); 885 spin_unlock_irqrestore(&m->lock, flags);
885 886
886 schedule_work(&m->trigger_event); 887 queue_work(kmultipathd, &m->trigger_event);
887} 888}
888 889
889/* 890/*
@@ -913,7 +914,7 @@ static int switch_pg_num(struct multipath *m, const char *pgstr)
913 } 914 }
914 spin_unlock_irqrestore(&m->lock, flags); 915 spin_unlock_irqrestore(&m->lock, flags);
915 916
916 schedule_work(&m->trigger_event); 917 queue_work(kmultipathd, &m->trigger_event);
917 return 0; 918 return 0;
918} 919}
919 920
@@ -968,7 +969,7 @@ void dm_pg_init_complete(struct path *path, unsigned err_flags)
968 m->current_pgpath = NULL; 969 m->current_pgpath = NULL;
969 m->current_pg = NULL; 970 m->current_pg = NULL;
970 } 971 }
971 schedule_work(&m->process_queued_ios); 972 queue_work(kmultipathd, &m->process_queued_ios);
972 spin_unlock_irqrestore(&m->lock, flags); 973 spin_unlock_irqrestore(&m->lock, flags);
973} 974}
974 975
@@ -1018,7 +1019,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
1018 bio_list_add(&m->queued_ios, bio); 1019 bio_list_add(&m->queued_ios, bio);
1019 m->queue_size++; 1020 m->queue_size++;
1020 if (!m->queue_io) 1021 if (!m->queue_io)
1021 schedule_work(&m->process_queued_ios); 1022 queue_work(kmultipathd, &m->process_queued_ios);
1022 spin_unlock(&m->lock); 1023 spin_unlock(&m->lock);
1023 1024
1024 return 1; /* io not complete */ 1025 return 1; /* io not complete */
@@ -1057,7 +1058,7 @@ static void multipath_presuspend(struct dm_target *ti)
1057 spin_lock_irqsave(&m->lock, flags); 1058 spin_lock_irqsave(&m->lock, flags);
1058 m->suspended = 1; 1059 m->suspended = 1;
1059 if (m->queue_if_no_path) 1060 if (m->queue_if_no_path)
1060 schedule_work(&m->process_queued_ios); 1061 queue_work(kmultipathd, &m->process_queued_ios);
1061 spin_unlock_irqrestore(&m->lock, flags); 1062 spin_unlock_irqrestore(&m->lock, flags);
1062} 1063}
1063 1064
@@ -1274,6 +1275,15 @@ static int __init dm_multipath_init(void)
1274 return -EINVAL; 1275 return -EINVAL;
1275 } 1276 }
1276 1277
1278 kmultipathd = create_workqueue("kmpathd");
1279 if (!kmultipathd) {
1280 DMERR("%s: failed to create workqueue kmpathd",
1281 multipath_target.name);
1282 dm_unregister_target(&multipath_target);
1283 kmem_cache_destroy(_mpio_cache);
1284 return -ENOMEM;
1285 }
1286
1277 DMINFO("dm-multipath version %u.%u.%u loaded", 1287 DMINFO("dm-multipath version %u.%u.%u loaded",
1278 multipath_target.version[0], multipath_target.version[1], 1288 multipath_target.version[0], multipath_target.version[1],
1279 multipath_target.version[2]); 1289 multipath_target.version[2]);
@@ -1285,6 +1295,8 @@ static void __exit dm_multipath_exit(void)
1285{ 1295{
1286 int r; 1296 int r;
1287 1297
1298 destroy_workqueue(kmultipathd);
1299
1288 r = dm_unregister_target(&multipath_target); 1300 r = dm_unregister_target(&multipath_target);
1289 if (r < 0) 1301 if (r < 0)
1290 DMERR("%s: target unregister failed %d", 1302 DMERR("%s: target unregister failed %d",