diff options
author | Bart Van Assche <bart.vanassche@sandisk.com> | 2017-04-27 13:11:24 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2017-04-27 17:08:45 -0400 |
commit | ca5beb76c32af33e5be4e01c85c8bd5a067c4543 (patch) | |
tree | da891f5543130b6f7ead7bc135d1d203104471eb | |
parent | 7e0d574f2683a2346c978613a72ff07afc89b17a (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.c | 70 |
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 | */ | ||
453 | static 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 | |||
460 | static 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 | |||
473 | static 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 | */ |
488 | static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, | 447 | static 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); |