* [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION
@ 2017-04-11 2:28 Mauricio Faria de Oliveira
2017-04-11 14:34 ` Brian King
0 siblings, 1 reply; 6+ messages in thread
From: Mauricio Faria de Oliveira @ 2017-04-11 2:28 UTC (permalink / raw)
To: linux-scsi, brking, wenxiong; +Cc: martin.petersen
On a dual controller setup with multipath enabled, some MEDIUM ERRORs
caused both paths to be failed, thus I/O got queued/blocked since the
'queue_if_no_path' feature is enabled by default on IPR controllers.
This example disabled 'queue_if_no_path' so the I/O failure is seen at
the sg_dd program. Notice that after the sg_dd test-case, both paths
are in 'failed' state, and both path/priority groups are in 'enabled'
state (not 'active') -- which would block I/O with 'queue_if_no_path'.
# sg_dd if=/dev/dm-2 bs=4096 count=1 dio=1 verbose=4 blk_sgio=0
<...>
read(unix): count=4096, res=-1
sg_dd: reading, skip=0 : Input/output error
<...>
# dmesg
[...] sd 2:2:16:0: [sds] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[...] sd 2:2:16:0: [sds] Sense Key : Medium Error [current]
[...] sd 2:2:16:0: [sds] Add. Sense: Unrecovered read error - recommend rewrite the data
[...] sd 2:2:16:0: [sds] CDB: Read(10) 28 00 00 00 00 00 00 00 20 00
[...] blk_update_request: I/O error, dev sds, sector 0
[...] device-mapper: multipath: Failing path 65:32.
<...>
[...] device-mapper: multipath: Failing path 65:224.
# multipath -l
1IBM_IPR-0_59C2AE0000001F80 dm-2 IBM ,IPR-0 59C2AE00
size=5.2T features='0' hwhandler='1 alua' wp=rw
|-+- policy='service-time 0' prio=0 status=enabled
| `- 2:2:16:0 sds 65:32 failed undef running
`-+- policy='service-time 0' prio=0 status=enabled
`- 1:2:7:0 sdae 65:224 failed undef running
This is not the desired behavior. The dm-multipath explicitly checks
for the MEDIUM ERROR case (and a few others) so not to fail the path
(e.g., I/O to other sectors could potentially happen without problems).
See dm-mpath.c :: do_end_io_bio() -> noretry_error() !->! fail_path().
The problem trace is:
1) ipr_scsi_done() // SENSE KEY/CHECK CONDITION detected, go to..
2) ipr_erp_start() // ipr_is_gscsi() and masked_ioasc OK, go to..
3) ipr_gen_sense() // masked_ioasc is IPR_IOASC_MED_DO_NOT_REALLOC,
// so set DID_PASSTHROUGH.
4) scsi_decide_disposition() // check for DID_PASSTHROUGH and return
// early on, faking a DID_OK.. *instead*
// of reaching scsi_check_sense().
// Had it reached the latter, that would
// set host_byte to DID_MEDIUM_ERROR.
5) scsi_finish_command()
6) scsi_io_completion()
7) __scsi_error_from_host_byte() // That would be converted to -ENODATA
<...>
8) dm_softirq_done()
9) multipath_end_io()
10) do_end_io()
11) noretry_error() // And that is checked in dm-mpath :: noretry_error()
// which would cause fail_path() not to be called.
With this patch applied, the I/O is failed but the paths are not. This
multipath device continues accepting more I/O requests without blocking.
(and notice the different host byte/driver byte handling per SCSI layer).
# dmesg
[...] sd 2:2:7:0: [sdaf] Done: SUCCESS Result: hostbyte=0x13 driverbyte=DRIVER_OK
[...] sd 2:2:7:0: [sdaf] CDB: Read(10) 28 00 00 00 00 00 00 00 40 00
[...] sd 2:2:7:0: [sdaf] Sense Key : Medium Error [current]
[...] sd 2:2:7:0: [sdaf] Add. Sense: Unrecovered read error - recommend rewrite the data
[...] blk_update_request: critical medium error, dev sdaf, sector 0
[...] blk_update_request: critical medium error, dev dm-6, sector 0
[...] sd 2:2:7:0: [sdaf] Done: SUCCESS Result: hostbyte=0x13 driverbyte=DRIVER_OK
[...] sd 2:2:7:0: [sdaf] CDB: Read(10) 28 00 00 00 00 00 00 00 10 00
[...] sd 2:2:7:0: [sdaf] Sense Key : Medium Error [current]
[...] sd 2:2:7:0: [sdaf] Add. Sense: Unrecovered read error - recommend rewrite the data
[...] blk_update_request: critical medium error, dev sdaf, sector 0
[...] blk_update_request: critical medium error, dev dm-6, sector 0
[...] Buffer I/O error on dev dm-6, logical block 0, async page read
# multipath -l 1IBM_IPR-0_59C2AE0000001F80
1IBM_IPR-0_59C2AE0000001F80 dm-6 IBM ,IPR-0 59C2AE00
size=5.2T features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
|-+- policy='service-time 0' prio=0 status=active
| `- 2:2:7:0 sdaf 65:240 active undef running
`-+- policy='service-time 0' prio=0 status=enabled
`- 1:2:7:0 sdh 8:112 active undef running
Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
---
P.S.: The switch-case checking this condition predates linux.git, so I'd
like to ask Brian for a review too, as I imagine he probably might
have worked with this back then (if memory may serve one this well :-)
drivers/scsi/ipr.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b29afafc2885..1012674d9dc5 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6293,7 +6293,12 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
break;
case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */
case IPR_IOASA_IR_DUAL_IOA_DISABLED:
- scsi_cmd->result |= (DID_PASSTHROUGH << 16);
+ /*
+ * exception: do not set DID_PASSTHROUGH on CHECK CONDITION
+ * so SCSI mid-layer and upper layers handle it accordingly.
+ */
+ if (ipr_cmd->scsi_cmd->result != SAM_STAT_CHECK_CONDITION)
+ scsi_cmd->result |= (DID_PASSTHROUGH << 16);
break;
case IPR_IOASC_BUS_WAS_RESET:
case IPR_IOASC_BUS_WAS_RESET_BY_OTHER:
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION
2017-04-11 2:28 [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION Mauricio Faria de Oliveira
@ 2017-04-11 14:34 ` Brian King
2017-04-11 14:40 ` Mauricio Faria de Oliveira
0 siblings, 1 reply; 6+ messages in thread
From: Brian King @ 2017-04-11 14:34 UTC (permalink / raw)
To: Mauricio Faria de Oliveira, linux-scsi, wenxiong; +Cc: martin.petersen
Mauricio,
Looks good to me. Thanks for the detailed analysis. One minor nit below
and you can add:
Acked-by: Brian King <brking@linux.vnet.ibm.com>
On 04/10/2017 09:28 PM, Mauricio Faria de Oliveira wrote:
> diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
> index b29afafc2885..1012674d9dc5 100644
> --- a/drivers/scsi/ipr.c
> +++ b/drivers/scsi/ipr.c
> @@ -6293,7 +6293,12 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
> break;
> case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */
> case IPR_IOASA_IR_DUAL_IOA_DISABLED:
> - scsi_cmd->result |= (DID_PASSTHROUGH << 16);
> + /*
> + * exception: do not set DID_PASSTHROUGH on CHECK CONDITION
> + * so SCSI mid-layer and upper layers handle it accordingly.
> + */
> + if (ipr_cmd->scsi_cmd->result != SAM_STAT_CHECK_CONDITION)
Since we already have a scsi_cmd local, you don't need to go back to the ipr_cmd
to get the pointer, so could be:
if (scsi_cmd->result != SAM_STAT_CHECK_CONDITION)
> + scsi_cmd->result |= (DID_PASSTHROUGH << 16);
> break;
> case IPR_IOASC_BUS_WAS_RESET:
> case IPR_IOASC_BUS_WAS_RESET_BY_OTHER:
>
Thanks,
Brian
--
Brian King
Power Linux I/O
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION
2017-04-11 14:34 ` Brian King
@ 2017-04-11 14:40 ` Mauricio Faria de Oliveira
0 siblings, 0 replies; 6+ messages in thread
From: Mauricio Faria de Oliveira @ 2017-04-11 14:40 UTC (permalink / raw)
To: Brian King, linux-scsi, wenxiong; +Cc: martin.petersen
On 04/11/2017 11:34 AM, Brian King wrote:
> Looks good to me. Thanks for the detailed analysis. One minor nit below
> and you can add:
>
> Acked-by: Brian King <brking@linux.vnet.ibm.com>
Cool, thanks. I'll submit a v2.
> Since we already have a scsi_cmd local, you don't need to go back to the ipr_cmd
> to get the pointer, so could be:
Thanks for catching that oversight.
--
Mauricio Faria de Oliveira
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION
2017-04-11 14:46 Mauricio Faria de Oliveira
2017-04-11 14:48 ` Mauricio Faria de Oliveira
@ 2017-04-12 1:41 ` Martin K. Petersen
1 sibling, 0 replies; 6+ messages in thread
From: Martin K. Petersen @ 2017-04-12 1:41 UTC (permalink / raw)
To: Mauricio Faria de Oliveira; +Cc: martin.petersen, brking, linux-scsi, wenxiong
Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com> writes:
> On a dual controller setup with multipath enabled, some MEDIUM ERRORs
> caused both paths to be failed, thus I/O got queued/blocked since the
> 'queue_if_no_path' feature is enabled by default on IPR controllers.
Applied to 4.11/scsi-fixes, thanks!
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION
2017-04-11 14:46 Mauricio Faria de Oliveira
@ 2017-04-11 14:48 ` Mauricio Faria de Oliveira
2017-04-12 1:41 ` Martin K. Petersen
1 sibling, 0 replies; 6+ messages in thread
From: Mauricio Faria de Oliveira @ 2017-04-11 14:48 UTC (permalink / raw)
To: martin.petersen, brking; +Cc: linux-scsi, wenxiong
This is the PATCH v2. Sorry for the wrong subject line.
On 04/11/2017 11:46 AM, Mauricio Faria de Oliveira wrote:
> Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
> Acked-by: Brian King <brking@linux.vnet.ibm.com>
> ---
> v2:
> - use the scsi_cmd local variable rather than ipr_cmd->scsi_cmd dereference.
> - add Acked-by: Brian King.
--
Mauricio Faria de Oliveira
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION
@ 2017-04-11 14:46 Mauricio Faria de Oliveira
2017-04-11 14:48 ` Mauricio Faria de Oliveira
2017-04-12 1:41 ` Martin K. Petersen
0 siblings, 2 replies; 6+ messages in thread
From: Mauricio Faria de Oliveira @ 2017-04-11 14:46 UTC (permalink / raw)
To: martin.petersen, brking; +Cc: linux-scsi, wenxiong
On a dual controller setup with multipath enabled, some MEDIUM ERRORs
caused both paths to be failed, thus I/O got queued/blocked since the
'queue_if_no_path' feature is enabled by default on IPR controllers.
This example disabled 'queue_if_no_path' so the I/O failure is seen at
the sg_dd program. Notice that after the sg_dd test-case, both paths
are in 'failed' state, and both path/priority groups are in 'enabled'
state (not 'active') -- which would block I/O with 'queue_if_no_path'.
# sg_dd if=/dev/dm-2 bs=4096 count=1 dio=1 verbose=4 blk_sgio=0
<...>
read(unix): count=4096, res=-1
sg_dd: reading, skip=0 : Input/output error
<...>
# dmesg
[...] sd 2:2:16:0: [sds] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[...] sd 2:2:16:0: [sds] Sense Key : Medium Error [current]
[...] sd 2:2:16:0: [sds] Add. Sense: Unrecovered read error - recommend rewrite the data
[...] sd 2:2:16:0: [sds] CDB: Read(10) 28 00 00 00 00 00 00 00 20 00
[...] blk_update_request: I/O error, dev sds, sector 0
[...] device-mapper: multipath: Failing path 65:32.
<...>
[...] device-mapper: multipath: Failing path 65:224.
# multipath -l
1IBM_IPR-0_59C2AE0000001F80 dm-2 IBM ,IPR-0 59C2AE00
size=5.2T features='0' hwhandler='1 alua' wp=rw
|-+- policy='service-time 0' prio=0 status=enabled
| `- 2:2:16:0 sds 65:32 failed undef running
`-+- policy='service-time 0' prio=0 status=enabled
`- 1:2:7:0 sdae 65:224 failed undef running
This is not the desired behavior. The dm-multipath explicitly checks
for the MEDIUM ERROR case (and a few others) so not to fail the path
(e.g., I/O to other sectors could potentially happen without problems).
See dm-mpath.c :: do_end_io_bio() -> noretry_error() !->! fail_path().
The problem trace is:
1) ipr_scsi_done() // SENSE KEY/CHECK CONDITION detected, go to..
2) ipr_erp_start() // ipr_is_gscsi() and masked_ioasc OK, go to..
3) ipr_gen_sense() // masked_ioasc is IPR_IOASC_MED_DO_NOT_REALLOC,
// so set DID_PASSTHROUGH.
4) scsi_decide_disposition() // check for DID_PASSTHROUGH and return
// early on, faking a DID_OK.. *instead*
// of reaching scsi_check_sense().
// Had it reached the latter, that would
// set host_byte to DID_MEDIUM_ERROR.
5) scsi_finish_command()
6) scsi_io_completion()
7) __scsi_error_from_host_byte() // That would be converted to -ENODATA
<...>
8) dm_softirq_done()
9) multipath_end_io()
10) do_end_io()
11) noretry_error() // And that is checked in dm-mpath :: noretry_error()
// which would cause fail_path() not to be called.
With this patch applied, the I/O is failed but the paths are not. This
multipath device continues accepting more I/O requests without blocking.
(and notice the different host byte/driver byte handling per SCSI layer).
# dmesg
[...] sd 2:2:7:0: [sdaf] Done: SUCCESS Result: hostbyte=0x13 driverbyte=DRIVER_OK
[...] sd 2:2:7:0: [sdaf] CDB: Read(10) 28 00 00 00 00 00 00 00 40 00
[...] sd 2:2:7:0: [sdaf] Sense Key : Medium Error [current]
[...] sd 2:2:7:0: [sdaf] Add. Sense: Unrecovered read error - recommend rewrite the data
[...] blk_update_request: critical medium error, dev sdaf, sector 0
[...] blk_update_request: critical medium error, dev dm-6, sector 0
[...] sd 2:2:7:0: [sdaf] Done: SUCCESS Result: hostbyte=0x13 driverbyte=DRIVER_OK
[...] sd 2:2:7:0: [sdaf] CDB: Read(10) 28 00 00 00 00 00 00 00 10 00
[...] sd 2:2:7:0: [sdaf] Sense Key : Medium Error [current]
[...] sd 2:2:7:0: [sdaf] Add. Sense: Unrecovered read error - recommend rewrite the data
[...] blk_update_request: critical medium error, dev sdaf, sector 0
[...] blk_update_request: critical medium error, dev dm-6, sector 0
[...] Buffer I/O error on dev dm-6, logical block 0, async page read
# multipath -l 1IBM_IPR-0_59C2AE0000001F80
1IBM_IPR-0_59C2AE0000001F80 dm-6 IBM ,IPR-0 59C2AE00
size=5.2T features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
|-+- policy='service-time 0' prio=0 status=active
| `- 2:2:7:0 sdaf 65:240 active undef running
`-+- policy='service-time 0' prio=0 status=enabled
`- 1:2:7:0 sdh 8:112 active undef running
Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
Acked-by: Brian King <brking@linux.vnet.ibm.com>
---
v2:
- use the scsi_cmd local variable rather than ipr_cmd->scsi_cmd dereference.
- add Acked-by: Brian King.
drivers/scsi/ipr.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b29afafc2885..5d5e272fd815 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6293,7 +6293,12 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg,
break;
case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */
case IPR_IOASA_IR_DUAL_IOA_DISABLED:
- scsi_cmd->result |= (DID_PASSTHROUGH << 16);
+ /*
+ * exception: do not set DID_PASSTHROUGH on CHECK CONDITION
+ * so SCSI mid-layer and upper layers handle it accordingly.
+ */
+ if (scsi_cmd->result != SAM_STAT_CHECK_CONDITION)
+ scsi_cmd->result |= (DID_PASSTHROUGH << 16);
break;
case IPR_IOASC_BUS_WAS_RESET:
case IPR_IOASC_BUS_WAS_RESET_BY_OTHER:
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-04-12 1:41 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-11 2:28 [PATCH] ipr: do not set DID_PASSTHROUGH on CHECK CONDITION Mauricio Faria de Oliveira
2017-04-11 14:34 ` Brian King
2017-04-11 14:40 ` Mauricio Faria de Oliveira
2017-04-11 14:46 Mauricio Faria de Oliveira
2017-04-11 14:48 ` Mauricio Faria de Oliveira
2017-04-12 1:41 ` Martin K. Petersen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.