aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2017-12-07 22:42:27 -0500
committerMike Snitzer <snitzer@redhat.com>2017-12-08 10:49:40 -0500
commitc1fd0abee0d52eb7e2871194b6c79d54792f515f (patch)
tree682306b0ffb307ae6dbc465459ca3db400b1aea3
parent7e6358d244e4706fe612a77b9c36519a33600ac0 (diff)
dm mpath: fix bio-based multipath queue_if_no_path handling
Commit ca5beb76 ("dm mpath: micro-optimize the hot path relative to MPATHF_QUEUE_IF_NO_PATH") caused bio-based DM-multipath to fail mptest's "test_02_sdev_delete". Restoring the logic that existed prior to commit ca5beb76 fixes this bio-based DM-multipath regression. Also verified all mptest tests pass with request-based DM-multipath. This commit effectively reverts commit ca5beb76 -- but it does so without reintroducing the need to take the m->lock spinlock in must_push_back_{rq,bio}. Fixes: ca5beb76 ("dm mpath: micro-optimize the hot path relative to MPATHF_QUEUE_IF_NO_PATH") Cc: stable@vger.kernel.org # 4.12+ Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-mpath.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 35a2a2fa477f..f7810cc869ac 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -458,6 +458,38 @@ do { \
458} while (0) 458} while (0)
459 459
460/* 460/*
461 * Check whether bios must be queued in the device-mapper core rather
462 * than here in the target.
463 *
464 * If MPATHF_QUEUE_IF_NO_PATH and MPATHF_SAVED_QUEUE_IF_NO_PATH hold
465 * the same value then we are not between multipath_presuspend()
466 * and multipath_resume() calls and we have no need to check
467 * for the DMF_NOFLUSH_SUSPENDING flag.
468 */
469static bool __must_push_back(struct multipath *m, unsigned long flags)
470{
471 return ((test_bit(MPATHF_QUEUE_IF_NO_PATH, &flags) !=
472 test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &flags)) &&
473 dm_noflush_suspending(m->ti));
474}
475
476/*
477 * Following functions use READ_ONCE to get atomic access to
478 * all m->flags to avoid taking spinlock
479 */
480static bool must_push_back_rq(struct multipath *m)
481{
482 unsigned long flags = READ_ONCE(m->flags);
483 return test_bit(MPATHF_QUEUE_IF_NO_PATH, &flags) || __must_push_back(m, flags);
484}
485
486static bool must_push_back_bio(struct multipath *m)
487{
488 unsigned long flags = READ_ONCE(m->flags);
489 return __must_push_back(m, flags);
490}
491
492/*
461 * Map cloned requests (request-based multipath) 493 * Map cloned requests (request-based multipath)
462 */ 494 */
463static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, 495static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
@@ -478,7 +510,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
478 pgpath = choose_pgpath(m, nr_bytes); 510 pgpath = choose_pgpath(m, nr_bytes);
479 511
480 if (!pgpath) { 512 if (!pgpath) {
481 if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) 513 if (must_push_back_rq(m))
482 return DM_MAPIO_DELAY_REQUEUE; 514 return DM_MAPIO_DELAY_REQUEUE;
483 dm_report_EIO(m); /* Failed */ 515 dm_report_EIO(m); /* Failed */
484 return DM_MAPIO_KILL; 516 return DM_MAPIO_KILL;
@@ -553,7 +585,7 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m
553 } 585 }
554 586
555 if (!pgpath) { 587 if (!pgpath) {
556 if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) 588 if (must_push_back_bio(m))
557 return DM_MAPIO_REQUEUE; 589 return DM_MAPIO_REQUEUE;
558 dm_report_EIO(m); 590 dm_report_EIO(m);
559 return DM_MAPIO_KILL; 591 return DM_MAPIO_KILL;
@@ -651,8 +683,7 @@ static int queue_if_no_path(struct multipath *m, bool queue_if_no_path,
651 assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags, 683 assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags,
652 (save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) || 684 (save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) ||
653 (!save_old_value && queue_if_no_path)); 685 (!save_old_value && queue_if_no_path));
654 assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, 686 assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags, queue_if_no_path);
655 queue_if_no_path || dm_noflush_suspending(m->ti));
656 spin_unlock_irqrestore(&m->lock, flags); 687 spin_unlock_irqrestore(&m->lock, flags);
657 688
658 if (!queue_if_no_path) { 689 if (!queue_if_no_path) {
@@ -1486,7 +1517,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
1486 fail_path(pgpath); 1517 fail_path(pgpath);
1487 1518
1488 if (atomic_read(&m->nr_valid_paths) == 0 && 1519 if (atomic_read(&m->nr_valid_paths) == 0 &&
1489 !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { 1520 !must_push_back_rq(m)) {
1490 if (error == BLK_STS_IOERR) 1521 if (error == BLK_STS_IOERR)
1491 dm_report_EIO(m); 1522 dm_report_EIO(m);
1492 /* complete with the original error */ 1523 /* complete with the original error */
@@ -1521,8 +1552,12 @@ static int multipath_end_io_bio(struct dm_target *ti, struct bio *clone,
1521 1552
1522 if (atomic_read(&m->nr_valid_paths) == 0 && 1553 if (atomic_read(&m->nr_valid_paths) == 0 &&
1523 !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { 1554 !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
1524 dm_report_EIO(m); 1555 if (must_push_back_bio(m)) {
1525 *error = BLK_STS_IOERR; 1556 r = DM_ENDIO_REQUEUE;
1557 } else {
1558 dm_report_EIO(m);
1559 *error = BLK_STS_IOERR;
1560 }
1526 goto done; 1561 goto done;
1527 } 1562 }
1528 1563