diff options
author | Mike Snitzer <snitzer@redhat.com> | 2018-01-12 19:53:40 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2018-01-29 13:44:54 -0500 |
commit | ac514ffc968bf14649dd0e048447dc966ee49555 (patch) | |
tree | 5f855e84e686deabbe559f2b7f4e440e5c8fd2c5 | |
parent | 459b54019cfeb7330ed4863ad40f78489e0ff23d (diff) |
dm mpath: delay the retry of a request if the target responded as busy
Add DM_ENDIO_DELAY_REQUEUE to allow request-based multipath's
multipath_end_io() to instruct dm-rq.c:dm_done() to delay a requeue.
This is beneficial to do if BLK_STS_RESOURCE is returned from the target
(because target is busy).
Relative to blk-mq: kick the hw queues via blk_mq_requeue_work(),
indirectly from dm-rq.c:__dm_mq_kick_requeue_list(), after a delay.
For old .request_fn: use blk_delay_queue().
bio-based multipath doesn't have feature parity with request-based for
retryable error requeues; that is something that'll need fixing in the
future.
Suggested-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Acked-by: Bart Van Assche <bart.vanassche@wdc.com>
[as interpreted from Bart's "... patch looks fine to me."]
-rw-r--r-- | drivers/md/dm-mpath.c | 5 | ||||
-rw-r--r-- | drivers/md/dm-rq.c | 4 | ||||
-rw-r--r-- | include/linux/device-mapper.h | 3 |
3 files changed, 10 insertions, 2 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 815de2b091a5..a8b1ffc0cb3d 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1585,7 +1585,10 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, | |||
1585 | if (error && !noretry_error(error)) { | 1585 | if (error && !noretry_error(error)) { |
1586 | struct multipath *m = ti->private; | 1586 | struct multipath *m = ti->private; |
1587 | 1587 | ||
1588 | r = DM_ENDIO_REQUEUE; | 1588 | if (error == BLK_STS_RESOURCE) |
1589 | r = DM_ENDIO_DELAY_REQUEUE; | ||
1590 | else | ||
1591 | r = DM_ENDIO_REQUEUE; | ||
1589 | 1592 | ||
1590 | if (pgpath) | 1593 | if (pgpath) |
1591 | fail_path(pgpath); | 1594 | fail_path(pgpath); |
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 9d32f25489c2..b78ff6921cfb 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c | |||
@@ -315,6 +315,10 @@ static void dm_done(struct request *clone, blk_status_t error, bool mapped) | |||
315 | /* The target wants to requeue the I/O */ | 315 | /* The target wants to requeue the I/O */ |
316 | dm_requeue_original_request(tio, false); | 316 | dm_requeue_original_request(tio, false); |
317 | break; | 317 | break; |
318 | case DM_ENDIO_DELAY_REQUEUE: | ||
319 | /* The target wants to requeue the I/O after a delay */ | ||
320 | dm_requeue_original_request(tio, true); | ||
321 | break; | ||
318 | default: | 322 | default: |
319 | DMWARN("unimplemented target endio return value: %d", r); | 323 | DMWARN("unimplemented target endio return value: %d", r); |
320 | BUG(); | 324 | BUG(); |
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 9ba84532947d..da83f64952e7 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -550,6 +550,7 @@ do { \ | |||
550 | #define DM_ENDIO_DONE 0 | 550 | #define DM_ENDIO_DONE 0 |
551 | #define DM_ENDIO_INCOMPLETE 1 | 551 | #define DM_ENDIO_INCOMPLETE 1 |
552 | #define DM_ENDIO_REQUEUE 2 | 552 | #define DM_ENDIO_REQUEUE 2 |
553 | #define DM_ENDIO_DELAY_REQUEUE 3 | ||
553 | 554 | ||
554 | /* | 555 | /* |
555 | * Definitions of return values from target map function. | 556 | * Definitions of return values from target map function. |
@@ -557,7 +558,7 @@ do { \ | |||
557 | #define DM_MAPIO_SUBMITTED 0 | 558 | #define DM_MAPIO_SUBMITTED 0 |
558 | #define DM_MAPIO_REMAPPED 1 | 559 | #define DM_MAPIO_REMAPPED 1 |
559 | #define DM_MAPIO_REQUEUE DM_ENDIO_REQUEUE | 560 | #define DM_MAPIO_REQUEUE DM_ENDIO_REQUEUE |
560 | #define DM_MAPIO_DELAY_REQUEUE 3 | 561 | #define DM_MAPIO_DELAY_REQUEUE DM_ENDIO_DELAY_REQUEUE |
561 | #define DM_MAPIO_KILL 4 | 562 | #define DM_MAPIO_KILL 4 |
562 | 563 | ||
563 | #define dm_sector_div64(x, y)( \ | 564 | #define dm_sector_div64(x, y)( \ |