aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-mpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-mpath.c')
-rw-r--r--drivers/md/dm-mpath.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 43763a0bd096..0c1b8520ef86 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
@@ -984,6 +985,9 @@ static int do_end_io(struct multipath *m, struct bio *bio,
984 if (!error) 985 if (!error)
985 return 0; /* I/O complete */ 986 return 0; /* I/O complete */
986 987
988 if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
989 return error;
990
987 spin_lock(&m->lock); 991 spin_lock(&m->lock);
988 if (!m->nr_valid_paths) { 992 if (!m->nr_valid_paths) {
989 if (!m->queue_if_no_path || m->suspended) { 993 if (!m->queue_if_no_path || m->suspended) {
@@ -1018,7 +1022,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
1018 bio_list_add(&m->queued_ios, bio); 1022 bio_list_add(&m->queued_ios, bio);
1019 m->queue_size++; 1023 m->queue_size++;
1020 if (!m->queue_io) 1024 if (!m->queue_io)
1021 schedule_work(&m->process_queued_ios); 1025 queue_work(kmultipathd, &m->process_queued_ios);
1022 spin_unlock(&m->lock); 1026 spin_unlock(&m->lock);
1023 1027
1024 return 1; /* io not complete */ 1028 return 1; /* io not complete */
@@ -1057,7 +1061,7 @@ static void multipath_presuspend(struct dm_target *ti)
1057 spin_lock_irqsave(&m->lock, flags); 1061 spin_lock_irqsave(&m->lock, flags);
1058 m->suspended = 1; 1062 m->suspended = 1;
1059 if (m->queue_if_no_path) 1063 if (m->queue_if_no_path)
1060 schedule_work(&m->process_queued_ios); 1064 queue_work(kmultipathd, &m->process_queued_ios);
1061 spin_unlock_irqrestore(&m->lock, flags); 1065 spin_unlock_irqrestore(&m->lock, flags);
1062} 1066}
1063 1067
@@ -1274,6 +1278,15 @@ static int __init dm_multipath_init(void)
1274 return -EINVAL; 1278 return -EINVAL;
1275 } 1279 }
1276 1280
1281 kmultipathd = create_workqueue("kmpathd");
1282 if (!kmultipathd) {
1283 DMERR("%s: failed to create workqueue kmpathd",
1284 multipath_target.name);
1285 dm_unregister_target(&multipath_target);
1286 kmem_cache_destroy(_mpio_cache);
1287 return -ENOMEM;
1288 }
1289
1277 DMINFO("dm-multipath version %u.%u.%u loaded", 1290 DMINFO("dm-multipath version %u.%u.%u loaded",
1278 multipath_target.version[0], multipath_target.version[1], 1291 multipath_target.version[0], multipath_target.version[1],
1279 multipath_target.version[2]); 1292 multipath_target.version[2]);
@@ -1285,6 +1298,8 @@ static void __exit dm_multipath_exit(void)
1285{ 1298{
1286 int r; 1299 int r;
1287 1300
1301 destroy_workqueue(kmultipathd);
1302
1288 r = dm_unregister_target(&multipath_target); 1303 r = dm_unregister_target(&multipath_target);
1289 if (r < 0) 1304 if (r < 0)
1290 DMERR("%s: target unregister failed %d", 1305 DMERR("%s: target unregister failed %d",