From patchwork Mon Jul 10 22:47:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 9833849 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9E6C160363 for ; Mon, 10 Jul 2017 22:49:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 900D1283C7 for ; Mon, 10 Jul 2017 22:49:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 83D352847D; Mon, 10 Jul 2017 22:49:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EE274283C7 for ; Mon, 10 Jul 2017 22:49:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932111AbdGJWtT (ORCPT ); Mon, 10 Jul 2017 18:49:19 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:54240 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754951AbdGJWrv (ORCPT ); Mon, 10 Jul 2017 18:47:51 -0400 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v6AMYRcq060025 for ; Mon, 10 Jul 2017 18:47:50 -0400 Received: from e24smtp04.br.ibm.com (e24smtp04.br.ibm.com [32.104.18.25]) by mx0b-001b2d01.pphosted.com with ESMTP id 2bm48ysbpn-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 10 Jul 2017 18:47:49 -0400 Received: from localhost by e24smtp04.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 10 Jul 2017 19:47:48 -0300 Received: from d24relay03.br.ibm.com (9.13.39.225) by e24smtp04.br.ibm.com (10.172.0.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 10 Jul 2017 19:47:46 -0300 Received: from d24av04.br.ibm.com (d24av04.br.ibm.com [9.8.31.97]) by d24relay03.br.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v6AMhPYQ12517416; Mon, 10 Jul 2017 19:43:25 -0300 Received: from d24av04.br.ibm.com (localhost [127.0.0.1]) by d24av04.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v6AMlk0C009468; Mon, 10 Jul 2017 19:47:47 -0300 Received: from t440.ibm.com ([9.85.207.174]) by d24av04.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id v6AMldAJ009404; Mon, 10 Jul 2017 19:47:43 -0300 From: Mauricio Faria de Oliveira To: jejb@linux.vnet.ibm.com, martin.petersen@oracle.com Cc: hare@suse.de, bart.vanassche@sandisk.com, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/4] scsi: scsi_dh_alua: allow I/O in target port unavailable and standby states Date: Mon, 10 Jul 2017 19:47:34 -0300 X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1499726857-7875-1-git-send-email-mauricfo@linux.vnet.ibm.com> References: <1499726857-7875-1-git-send-email-mauricfo@linux.vnet.ibm.com> X-TM-AS-MML: disable x-cbid: 17071022-0028-0000-0000-000001C9E197 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17071022-0029-0000-0000-000014CC12C1 Message-Id: <1499726857-7875-2-git-send-email-mauricfo@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-07-10_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1707100389 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP According to SPC-4 (5.15.2.4.5 Unavailable state), the unavailable state may (or may not) transition to other states (e.g., microcode downloading or hardware error, which may be temporary or permanent). But, scsi_dh_alua currently fails I/O requests early on once that state occurs (in alua_prep_fn()) preventing path checkers in such function path to actually check if I/O still fails or now works. And that prevents a path activation (alua_activate()) which could update the PG state if it eventually recovered to an active state, thus resume I/O. (This is also the case with the standby state.) This might cause device-mapper multipath to fail all paths to some storage system that moves the controllers to the unavailable state for firmware upgrades, and never recover regardless of the storage system doing upgrades one controller at a time and get them online. Then I/O requests are blocked indefinitely due to queue_if_no_path but the underlying individual paths are fully operational, and can be verified as such through other function paths (e.g., SG_IO): # multipath -l mpatha (360050764008100dac000000000000100) dm-0 IBM,2145 size=40G features='2 queue_if_no_path retain_attached_hw_handler' hwhandler='1 alua' wp=rw |-+- policy='service-time 0' prio=0 status=enabled | |- 1:0:1:0 sdf 8:80 failed undef running | `- 2:0:1:0 sdn 8:208 failed undef running `-+- policy='service-time 0' prio=0 status=enabled |- 1:0:0:0 sdb 8:16 failed undef running `- 2:0:0:0 sdj 8:144 failed undef running # strace -e read \ sg_dd blk_sgio=0 \ if=/dev/sdj of=/dev/null bs=512 count=1 iflag=direct \ 2>&1 | grep 512 read(3, 0x3fff7ba80000, 512) = -1 EIO (Input/output error) # strace -e ioctl \ sg_dd blk_sgio=1 \ if=/dev/sdj of=/dev/null bs=512 count=1 iflag=direct \ 2>&1 | grep 512 ioctl(3, SG_IO, {'S', SG_DXFER_FROM_DEV, cmd[10]=[28, 00, 00, 00, 00, 00, 00, 00, 01, 00], <...>) = 0 So, allow I/O to paths of PGs in unavailable/standby state, so path checkers can actually check them. Also, schedule a recheck when unavailable/standby state is detected (in alua_check_sense()) to update pg->state, and quiet further SCSI error messages (in alua_prep_fn()). Once a path checker eventually detects a working/active state again, the PG state is normally updated on path activation (alua_activate(), as it schedules a recheck), thus I/O requests are no longer failed. Signed-off-by: Mauricio Faria de Oliveira Reported-by: Naresh Bannoth --- v2: - also add support for standby state to alua_check_sense(), alua_prep_fn() (Bart Van Assche ) drivers/scsi/device_handler/scsi_dh_alua.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index c01b47e5b55a..a1cf3d6aa853 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -431,6 +431,26 @@ static int alua_check_sense(struct scsi_device *sdev, alua_check(sdev, false); return NEEDS_RETRY; } + if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) { + /* + * LUN Not Accessible - target port in standby state. + * + * Do not retry, so failover to another target port occur. + * Schedule a recheck to update state for other functions. + */ + alua_check(sdev, true); + return SUCCESS; + } + if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0c) { + /* + * LUN Not Accessible - target port in unavailable state. + * + * Do not retry, so failover to another target port occur. + * Schedule a recheck to update state for other functions. + */ + alua_check(sdev, true); + return SUCCESS; + } break; case UNIT_ATTENTION: if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) { @@ -1057,6 +1077,8 @@ static void alua_check(struct scsi_device *sdev, bool force) * * Fail I/O to all paths not in state * active/optimized or active/non-optimized. + * Allow I/O to paths in state unavailable/standby + * so path checkers can actually check them. */ static int alua_prep_fn(struct scsi_device *sdev, struct request *req) { @@ -1072,6 +1094,9 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req) rcu_read_unlock(); if (state == SCSI_ACCESS_STATE_TRANSITIONING) ret = BLKPREP_DEFER; + else if (state == SCSI_ACCESS_STATE_UNAVAILABLE || + state == SCSI_ACCESS_STATE_STANDBY) + req->rq_flags |= RQF_QUIET; else if (state != SCSI_ACCESS_STATE_OPTIMAL && state != SCSI_ACCESS_STATE_ACTIVE && state != SCSI_ACCESS_STATE_LBA) {