aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@sandisk.com>2017-04-27 13:11:24 -0400
committerMike Snitzer <snitzer@redhat.com>2017-04-27 17:08:45 -0400
commitca5beb76c32af33e5be4e01c85c8bd5a067c4543 (patch)
treeda891f5543130b6f7ead7bc135d1d203104471eb
parent7e0d574f2683a2346c978613a72ff07afc89b17a (diff)
dm mpath: micro-optimize the hot path relative to MPATHF_QUEUE_IF_NO_PATH
Instead of checking MPATHF_QUEUE_IF_NO_PATH, MPATHF_SAVED_QUEUE_IF_NO_PATH and the no_flush flag to decide whether or not to push back a request (or bio) if there are no paths available, only clear MPATHF_QUEUE_IF_NO_PATH in queue_if_no_path() if no_flush has not been set. The result is that only a single bit has to be tested in the hot path to decide whether or not a request must be pushed back and also that m->lock does not have to be taken in the hot path. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-mpath.c70
1 files changed, 11 insertions, 59 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 8336332bd61f..5cb1beccd1e2 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -442,47 +442,6 @@ failed:
442} 442}
443 443
444/* 444/*
445 * Check whether bios must be queued in the device-mapper core rather
446 * than here in the target.
447 *
448 * If m->queue_if_no_path and m->saved_queue_if_no_path hold the
449 * same value then we are not between multipath_presuspend()
450 * and multipath_resume() calls and we have no need to check
451 * for the DMF_NOFLUSH_SUSPENDING flag.
452 */
453static bool __must_push_back(struct multipath *m)
454{
455 return ((test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) !=
456 test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags)) &&
457 dm_noflush_suspending(m->ti));
458}
459
460static bool must_push_back_rq(struct multipath *m)
461{
462 bool r;
463 unsigned long flags;
464
465 spin_lock_irqsave(&m->lock, flags);
466 r = (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) ||
467 __must_push_back(m));
468 spin_unlock_irqrestore(&m->lock, flags);
469
470 return r;
471}
472
473static bool must_push_back_bio(struct multipath *m)
474{
475 bool r;
476 unsigned long flags;
477
478 spin_lock_irqsave(&m->lock, flags);
479 r = __must_push_back(m);
480 spin_unlock_irqrestore(&m->lock, flags);
481
482 return r;
483}
484
485/*
486 * Map cloned requests (request-based multipath) 445 * Map cloned requests (request-based multipath)
487 */ 446 */
488static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, 447static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
@@ -503,7 +462,7 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
503 pgpath = choose_pgpath(m, nr_bytes); 462 pgpath = choose_pgpath(m, nr_bytes);
504 463
505 if (!pgpath) { 464 if (!pgpath) {
506 if (must_push_back_rq(m)) 465 if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
507 return DM_MAPIO_DELAY_REQUEUE; 466 return DM_MAPIO_DELAY_REQUEUE;
508 return -EIO; /* Failed */ 467 return -EIO; /* Failed */
509 } else if (test_bit(MPATHF_QUEUE_IO, &m->flags) || 468 } else if (test_bit(MPATHF_QUEUE_IO, &m->flags) ||
@@ -580,9 +539,9 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m
580 } 539 }
581 540
582 if (!pgpath) { 541 if (!pgpath) {
583 if (!must_push_back_bio(m)) 542 if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
584 return -EIO; 543 return DM_MAPIO_REQUEUE;
585 return DM_MAPIO_REQUEUE; 544 return -EIO;
586 } 545 }
587 546
588 mpio->pgpath = pgpath; 547 mpio->pgpath = pgpath;
@@ -674,7 +633,7 @@ static int queue_if_no_path(struct multipath *m, bool queue_if_no_path,
674 else 633 else
675 clear_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags); 634 clear_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags);
676 } 635 }
677 if (queue_if_no_path) 636 if (queue_if_no_path || dm_noflush_suspending(m->ti))
678 set_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags); 637 set_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags);
679 else 638 else
680 clear_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags); 639 clear_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags);
@@ -1519,12 +1478,9 @@ static int do_end_io(struct multipath *m, struct request *clone,
1519 if (mpio->pgpath) 1478 if (mpio->pgpath)
1520 fail_path(mpio->pgpath); 1479 fail_path(mpio->pgpath);
1521 1480
1522 if (!atomic_read(&m->nr_valid_paths)) { 1481 if (atomic_read(&m->nr_valid_paths) == 0 &&
1523 if (!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { 1482 !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
1524 if (!must_push_back_rq(m)) 1483 r = -EIO;
1525 r = -EIO;
1526 }
1527 }
1528 1484
1529 return r; 1485 return r;
1530} 1486}
@@ -1565,13 +1521,9 @@ static int do_end_io_bio(struct multipath *m, struct bio *clone,
1565 if (mpio->pgpath) 1521 if (mpio->pgpath)
1566 fail_path(mpio->pgpath); 1522 fail_path(mpio->pgpath);
1567 1523
1568 if (!atomic_read(&m->nr_valid_paths)) { 1524 if (atomic_read(&m->nr_valid_paths) == 0 &&
1569 if (!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { 1525 !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
1570 if (!must_push_back_bio(m)) 1526 return -EIO;
1571 return -EIO;
1572 return DM_ENDIO_REQUEUE;
1573 }
1574 }
1575 1527
1576 /* Queue for the daemon to resubmit */ 1528 /* Queue for the daemon to resubmit */
1577 dm_bio_restore(get_bio_details_from_bio(clone), clone); 1529 dm_bio_restore(get_bio_details_from_bio(clone), clone);