aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2018-01-12 19:53:40 -0500
committerMike Snitzer <snitzer@redhat.com>2018-01-29 13:44:54 -0500
commitac514ffc968bf14649dd0e048447dc966ee49555 (patch)
tree5f855e84e686deabbe559f2b7f4e440e5c8fd2c5
parent459b54019cfeb7330ed4863ad40f78489e0ff23d (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.c5
-rw-r--r--drivers/md/dm-rq.c4
-rw-r--r--include/linux/device-mapper.h3
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)( \