From patchwork Wed Mar 2 05:35:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765490 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07D88C433FE for ; Wed, 2 Mar 2022 05:36:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238953AbiCBFhO (ORCPT ); Wed, 2 Mar 2022 00:37:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232134AbiCBFhM (ORCPT ); Wed, 2 Mar 2022 00:37:12 -0500 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C26D0B16D3 for ; Tue, 1 Mar 2022 21:36:29 -0800 (PST) Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222UedC006483; Wed, 2 Mar 2022 05:36:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=8Fm0R5XbiuzQxIxzml0L1PPjFnIg15ezMQU/G80e/8I=; b=nQZOGtdpAx2EqXWCwPrgsU7QSY1aYFhjnUFimRHIQg3a+4+rdBtGwdPnuD7UFI8RquEl 25C/FzIM701/KAd5hcCbMWVf6Gc396atnSfMaNADyq3XUzqjESw+jVJUJpDt9+ArIYH1 J18K8wSswHinN1cNGyIfk3yFhFtb6ilggd8piLKryTkVqIiLgbKO1K+VHr//HES7X9ut jcKx2QtHkd82Bp+MpI+cbgoMNSbnY7HxVxUMmwPbHMdlgo0258lJ/ZXsmcKM/j4ngAOx oahkB6e40YokuyDV+YFnan9PnTuSGjgSdM/0Gu4PiRcsyJu7NbZrMG469ybQWVlsdGoE sA== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3ehh2ejnvt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:28 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IpFO175821; Wed, 2 Mar 2022 05:36:27 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vafg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:27 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZV014395; Wed, 2 Mar 2022 05:36:27 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-2; Wed, 02 Mar 2022 05:36:27 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" , Sreekanth Reddy Subject: [PATCH 01/14] scsi: mpt3sas: Use cached ATA Information VPD page Date: Wed, 2 Mar 2022 00:35:46 -0500 Message-Id: <20220302053559.32147-2-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 5FPxwm4ywrJEbnPkx6_ZLPzM7s9hQXCQ X-Proofpoint-GUID: 5FPxwm4ywrJEbnPkx6_ZLPzM7s9hQXCQ Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org We now cache VPD page 0x89 so there is no need to request it from the hardware. Make mpt3sas use the cached page. Cc: Sreekanth Reddy Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Hannes Reinecke --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 00792767c620..69cd64a26141 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -12585,20 +12585,18 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev) */ bool scsih_ncq_prio_supp(struct scsi_device *sdev) { - unsigned char *buf; + struct scsi_vpd *vpd; bool ncq_prio_supp = false; - if (!scsi_device_supports_vpd(sdev)) - return ncq_prio_supp; - - buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL); - if (!buf) - return ncq_prio_supp; + rcu_read_lock(); + vpd = rcu_dereference(sdev->vpd_pg89); + if (!vpd || vpd->len < 214) + goto out; - if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN)) - ncq_prio_supp = (buf[213] >> 4) & 1; + ncq_prio_supp = (vpd->data[213] >> 4) & 1; +out: + rcu_read_unlock(); - kfree(buf); return ncq_prio_supp; } /* From patchwork Wed Mar 2 05:35:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765499 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CEB21C433EF for ; Wed, 2 Mar 2022 05:36:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239642AbiCBFhY (ORCPT ); Wed, 2 Mar 2022 00:37:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239521AbiCBFhQ (ORCPT ); Wed, 2 Mar 2022 00:37:16 -0500 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0865CB16F2 for ; Tue, 1 Mar 2022 21:36:33 -0800 (PST) Received: from pps.filterd (m0246630.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222iBHk016894; Wed, 2 Mar 2022 05:36:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=ULnz/gkzD/hTVp62r05l6On+ELMmvG4umJ5WzfAQZts=; b=d3TszB61ijkLjHtsY+WmgP916WXsaCLHvS10CbMWv2SPrL5eRtTohRbHQwqbRLeJ059L EiPpN4jH7jRPZnhttQjl/DSGS8inOdl/xnbOmrQUxqMTbjcviMr9hZI8rPacOIgTGgwB ZdF2zMyhKmOIMDIzbqLTOIyIkBSq6+Vosmswh9Lc9DEcogfPzUKAdUYMvyCSVleo/exo 7dma0wULgpQO5Cl4PiXPgzn0A7vCIsnNBf2m37gDCKlpqZIMbmF8zR2chrnovS78ffF3 cCIKPWDw0qconnjdb8Msd+7smeTG9m3kFwaAnOSkeDFZKb337SYOnTaj0JDLTysMcFi1 oQ== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3ehdayu52n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:29 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225Ipfg175853; Wed, 2 Mar 2022 05:36:28 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vag7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:28 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZX014395; Wed, 2 Mar 2022 05:36:28 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-3; Wed, 02 Mar 2022 05:36:27 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" , "Maciej W . Rozycki" Subject: [PATCH 02/14] scsi: core: Query VPD size before getting full page Date: Wed, 2 Mar 2022 00:35:47 -0500 Message-Id: <20220302053559.32147-3-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: w7o7fsOylgUtcgd0RgQ-LkZWA1vo8q4a X-Proofpoint-ORIG-GUID: w7o7fsOylgUtcgd0RgQ-LkZWA1vo8q4a Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org We currently default to 255 bytes when fetching VPD pages during discovery. However, we have had a few devices that are known to wedge if the requested buffer exceeds a certain size. See commit af73623f5f10 ("[SCSI] sd: Reduce buffer size for vpd request") which works around one example of this problem in the SCSI disk driver. With commit d188b0675b21 ("scsi: core: Add sysfs attributes for VPD pages 0h and 89h") we now risk triggering the same issue in the generic midlayer code. The problem with the ATA VPD page in particular is that the SCSI portion of the page is trailed by 512 bytes of verbatim ATA Identify Device information. However, not all controllers actually provide the additional 512 bytes and will lock up if one asks for more than the 64 bytes containing the SCSI protocol fields. Instead of picking a new, somewhat arbitrary, number of bytes for the VPD buffer size, start fetching the 4-byte header for each page. The header contains the size of the page as far as the device is concerned. We can use the reported size to specify the correct allocation length when subsequently fetching the full page. The header validation is done by a new helper function scsi_get_vpd_size() and both scsi_get_vpd_page() and scsi_get_vpd_buf() now rely on this to query the page size. In addition, scsi_get_vpd_page() is simplified to mirror the logic in scsi_get_vpd_page(). This involves removing the Supported VPD Pages lookup prior to attempting to query a page. There does not appear any evidence, even in the oldest SCSI specs, that this step is required. We already rely on scsi_get_vpd_page() throughout the stack and this function never consulted the Supported VPD Pages. Since this has not caused any problems it should be safe to remove the precondition from scsi_get_vpd_page(). Instrumented runs also revealed that the Supported VPD Pages lookup had little effect since the device page index often was larger than the supplied buffer size. As a result, inquiries frequently bypassed the index check and went through the "If we ran off the end of the buffer, give us the benefit of the doubt" code path which assumed the page was present despite not being listed. The revised code takes both the page size reported by the device as well as the size of the buffer provided by the scsi_get_vpd_page() caller into account. Fixes: d188b0675b21 ("scsi: core: Add sysfs attributes for VPD pages 0h and 89h") Reported-by: Maciej W. Rozycki Tested-by: Maciej W. Rozycki Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn --- drivers/scsi/scsi.c | 94 +++++++++++++++++++++++++------------- include/scsi/scsi_device.h | 5 +- 2 files changed, 67 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 211aace69c22..af896d0647a7 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -321,6 +321,32 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, return get_unaligned_be16(&buffer[2]) + 4; } +static int scsi_get_vpd_size(struct scsi_device *sdev, u8 page) +{ + unsigned char vpd_header[SCSI_VPD_HEADER_SIZE]; + int result; + + /* + * Fetch the VPD page header to find out how big the page + * is. This is done to prevent problems on legacy devices + * which can not handle allocation lengths as large as + * potentially requested by the caller. + */ + result = scsi_vpd_inquiry(sdev, vpd_header, page, sizeof(vpd_header)); + + if (result < 0) + return 0; + + if (result < SCSI_VPD_HEADER_SIZE) { + dev_warn_once(&sdev->sdev_gendev, + "%s: short VPD page 0x%02x length: %d bytes\n", + __func__, page, result); + return 0; + } + + return result; +} + /** * scsi_get_vpd_page - Get Vital Product Data from a SCSI device * @sdev: The device to ask @@ -330,47 +356,42 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, * * SCSI devices may optionally supply Vital Product Data. Each 'page' * of VPD is defined in the appropriate SCSI document (eg SPC, SBC). - * If the device supports this VPD page, this routine returns a pointer - * to a buffer containing the data from that page. The caller is - * responsible for calling kfree() on this pointer when it is no longer - * needed. If we cannot retrieve the VPD page this routine returns %NULL. + * If the device supports this VPD page, this routine fills @buf + * with the data from that page and return 0. If the VPD page is not + * supported or its content cannot be retrieved, -EINVAL is returned. */ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, int buf_len) { - int i, result; + int result, vpd_len; - if (sdev->skip_vpd_pages) - goto fail; - - /* Ask for all the pages supported by this device */ - result = scsi_vpd_inquiry(sdev, buf, 0, buf_len); - if (result < 4) - goto fail; - - /* If the user actually wanted this page, we can skip the rest */ - if (page == 0) - return 0; + if (!scsi_device_supports_vpd(sdev)) + return -EINVAL; - for (i = 4; i < min(result, buf_len); i++) - if (buf[i] == page) - goto found; + vpd_len = scsi_get_vpd_size(sdev, page); + if (vpd_len <= 0) + return -EINVAL; - if (i < result && i >= buf_len) - /* ran off the end of the buffer, give us benefit of doubt */ - goto found; - /* The device claims it doesn't support the requested page */ - goto fail; + vpd_len = min(vpd_len, buf_len); - found: - result = scsi_vpd_inquiry(sdev, buf, page, buf_len); +retry_pg: + /* + * Fetch the actual page. Since the appropriate size was reported + * by the device it is now safe to ask for something bigger. + */ + memset(buf, 0, buf_len); + result = scsi_vpd_inquiry(sdev, buf, page, vpd_len); if (result < 0) - goto fail; + return -EINVAL; + else if (result > vpd_len) { + dev_warn_once(&sdev->sdev_gendev, + "%s: VPD page 0x%02x result %d > %d bytes\n", + __func__, page, result, vpd_len); + vpd_len = min(result, buf_len); + goto retry_pg; + } return 0; - - fail: - return -EINVAL; } EXPORT_SYMBOL_GPL(scsi_get_vpd_page); @@ -384,9 +405,17 @@ EXPORT_SYMBOL_GPL(scsi_get_vpd_page); static struct scsi_vpd *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page) { struct scsi_vpd *vpd_buf; - int vpd_len = SCSI_VPD_PG_LEN, result; + int vpd_len, result; + + vpd_len = scsi_get_vpd_size(sdev, page); + if (vpd_len <= 0) + return NULL; retry_pg: + /* + * Fetch the actual page. Since the appropriate size was reported + * by the device it is now safe to ask for something bigger. + */ vpd_buf = kmalloc(sizeof(*vpd_buf) + vpd_len, GFP_KERNEL); if (!vpd_buf) return NULL; @@ -397,6 +426,9 @@ static struct scsi_vpd *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page) return NULL; } if (result > vpd_len) { + dev_warn_once(&sdev->sdev_gendev, + "%s: VPD page 0x%02x result %d > %d bytes\n", + __func__, page, result, vpd_len); vpd_len = result; kfree(vpd_buf); goto retry_pg; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 647c53b26105..144d3a801c8d 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -100,6 +100,10 @@ struct scsi_vpd { unsigned char data[]; }; +enum scsi_vpd_parameters { + SCSI_VPD_HEADER_SIZE = 4, +}; + struct scsi_device { struct Scsi_Host *host; struct request_queue *request_queue; @@ -141,7 +145,6 @@ struct scsi_device { const char * model; /* ... after scan; point to static string */ const char * rev; /* ... "nullnullnullnull" before scan */ -#define SCSI_VPD_PG_LEN 255 struct scsi_vpd __rcu *vpd_pg0; struct scsi_vpd __rcu *vpd_pg83; struct scsi_vpd __rcu *vpd_pg80; From patchwork Wed Mar 2 05:35:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765492 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4CE47C433EF for ; Wed, 2 Mar 2022 05:36:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239567AbiCBFhR (ORCPT ); Wed, 2 Mar 2022 00:37:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38272 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234218AbiCBFhM (ORCPT ); Wed, 2 Mar 2022 00:37:12 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36641B16D4 for ; Tue, 1 Mar 2022 21:36:30 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222bNBZ010964 for ; Wed, 2 Mar 2022 05:36:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=CvzoEmqD2Ha8aFPBnqln8rrAH5c7YpxI7vZhSAvmsos=; b=c/E0iKxkVB/QjNi1XlZg1m59gPb4xI4VWgwB/C5JOFBITdPFsdp28gyfH51Fb75NwL2V BBgd5v6aJUr+JkEvWB2KN9sIjgAwR69ftXZBUgIWS2HTAfmQ5+Hv6AJTqkaG1Nw3L5Xg 1sG/tT74hjBnVAVvRnjBpX+VzjbNG4Oe6kfvBqO7/1E1iAAZAiCtfVV36ehixZuMfOvu 4C5cgRi8jpTJcvNAgHX10KzPc+dfM/mwFUwCvVDbvWezJt2WfJFRfPFyheLiJ0RxQvhS ezKPn+jCrI//2UvBhpJFanJh4RgxoLGhLbVgERfsb92xH8dfNr3i6gRJpZ0/B0+DIg0I rw== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh14bvwcg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:29 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IpfH175835 for ; Wed, 2 Mar 2022 05:36:28 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vagt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:28 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZZ014395 for ; Wed, 2 Mar 2022 05:36:28 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-4; Wed, 02 Mar 2022 05:36:28 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 03/14] scsi: core: Do not truncate INQUIRY data on modern devices Date: Wed, 2 Mar 2022 00:35:48 -0500 Message-Id: <20220302053559.32147-4-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: rlDMHU01r3H8SS-bluSHtUyH09vMIjx8 X-Proofpoint-ORIG-GUID: rlDMHU01r3H8SS-bluSHtUyH09vMIjx8 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Low-level device drivers have had the ability to limit the size of an INQUIRY for many years. This made sense for a wide variety of legacy devices. However, we are unnecessarily truncating the INQUIRY response for many modern devices. This prevents us from consulting fields beyond the first 36 bytes. If a device reports that it supports a larger INQUIRY response, and the device also reports that it implements SPC-4 or newer, allow the larger INQUIRY to proceed. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn --- drivers/scsi/scsi_scan.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index f4e6c68ac99e..95bf9a1f35ce 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -728,7 +728,17 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, if (pass == 1) { if (BLIST_INQUIRY_36 & *bflags) next_inquiry_len = 36; - else if (sdev->inquiry_len) + /* + * LLD specified a maximum sdev->inquiry_len + * but device claims it has more data. Capping + * the length only makes sense for legacy + * devices. If a device supports SPC-4 (2014) + * or newer, assume that it is safe to ask for + * as much as the device says it supports. + */ + else if (sdev->inquiry_len && + response_len > sdev->inquiry_len && + (inq_result[2] & 0x7) < 6) /* SPC-4 */ next_inquiry_len = sdev->inquiry_len; else next_inquiry_len = response_len; From patchwork Wed Mar 2 05:35:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0F46C433F5 for ; Wed, 2 Mar 2022 05:36:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239371AbiCBFhP (ORCPT ); Wed, 2 Mar 2022 00:37:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38282 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235160AbiCBFhN (ORCPT ); Wed, 2 Mar 2022 00:37:13 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10822B16D5 for ; Tue, 1 Mar 2022 21:36:31 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222m9p1014692 for ; Wed, 2 Mar 2022 05:36:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=nMmBzpYhUHTdlPVXepcIyqO48i+jKceUhZejNfuElOs=; b=C3wNdcrdE338iPTniS9aUCgXr/6Sul8+sXigFdPMg23vwSI0PC32K2WNUw8EhCDhJZpH fXngYM6Z/damNSJ8nY01z0NIOZH5hoPTTJjmAL/oA+X8uuj+4GZrwZh1Gl+5vbNs6I8g Lm6q4+a2N+5eYDwDJR8UyA435y9EmjjM4PiTYbopSt6MYv78K1oPIDzQWOGLIs4wfIWu tlxMkqT35x3NX3L2zf6uSytmG8ZdPfwqMNfNDyQpUZ81Gh1nzNVvHpN4/z5Vl5jBeOeu 18lJVnapOSXhJaI2nmTFEFM63CQCsZPsoysl9OxPjnTFhLaLwHcZiw5RY18Gm+jEVnDT ug== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh15amq8q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:30 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IpLO175843 for ; Wed, 2 Mar 2022 05:36:29 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vah8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:29 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZb014395 for ; Wed, 2 Mar 2022 05:36:29 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-5; Wed, 02 Mar 2022 05:36:28 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 04/14] scsi: core: Pick suitable allocation length in scsi_report_opcode() Date: Wed, 2 Mar 2022 00:35:49 -0500 Message-Id: <20220302053559.32147-5-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: mewB3eW7IELqvE2jKHUFx05AN2Lvu2KN X-Proofpoint-GUID: mewB3eW7IELqvE2jKHUFx05AN2Lvu2KN Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Some devices hang when a buffer size larger than expected is passed in the ALLOCATION LENGTH field. For REPORT SUPPORTED OPERATION CODES we currently only request a single command descriptor at a time and therefore the actual size of the command is known ahead of time. Limit the ALLOCATION LENGTH to the header size plus the command length of the opcode we are asking about. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Bart Van Assche Reviewed-by: Hannes Reinecke --- drivers/scsi/scsi.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index af896d0647a7..c6221a2ca04e 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -508,21 +508,30 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, { unsigned char cmd[16]; struct scsi_sense_hdr sshdr; - int result; + int result, request_len; if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) return -EINVAL; + /* RSOC header + size of command we are asking about */ + request_len = 4 + COMMAND_SIZE(opcode); + if (request_len > len) { + dev_warn_once(&sdev->sdev_gendev, + "%s: len %u bytes, opcode 0x%02x needs %u\n", + __func__, len, opcode, request_len); + return -EINVAL; + } + memset(cmd, 0, 16); cmd[0] = MAINTENANCE_IN; cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; cmd[2] = 1; /* One command format */ cmd[3] = opcode; - put_unaligned_be32(len, &cmd[6]); + put_unaligned_be32(request_len, &cmd[6]); memset(buffer, 0, len); - result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, - &sshdr, 30 * HZ, 3, NULL); + result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, + request_len, &sshdr, 30 * HZ, 3, NULL); if (result < 0) return result; From patchwork Wed Mar 2 05:35:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765494 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C3571C433F5 for ; Wed, 2 Mar 2022 05:36:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239597AbiCBFhU (ORCPT ); Wed, 2 Mar 2022 00:37:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238246AbiCBFhN (ORCPT ); Wed, 2 Mar 2022 00:37:13 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56305B16DA for ; Tue, 1 Mar 2022 21:36:31 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222jYNA010945 for ; Wed, 2 Mar 2022 05:36:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=6MeIGjyLcXc7nLxRjHNUMype0upcrKejx82eHH9RsUM=; b=W0nAf89BZx6MliGzlNSHxyCrgUe/OLJ66SxVFCj1UXjjS3J+vFYN60zh/a9D61wMICcQ wlYOdd6YiJ5SI0CRuXOMtdaZLwRVhS+mK2C8kOULRSV5I2XRnIZCE3K6IQaQnkKxQBkI i+Cvg5sM1eO5vKDUll/r88DJCDeQ/7avYN4pObWVDasEPegiASr4P+7nu2nqHzAfxAlT sq73yOsdIC2hXis2iWd03f8ZAfdK06chU5mYP4oRyNbpfPz1yfEzyobFU+eJefLt9vYO CNKe6rY9qaPa8I7hI4M/g9BZgfRVtCLjLOsyGQkEiR1zHVhBofineCmFiZtBh/ZRz0B9 Fg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh14bvwcj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:30 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IpAg175833 for ; Wed, 2 Mar 2022 05:36:29 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vahk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:29 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZd014395 for ; Wed, 2 Mar 2022 05:36:29 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-6; Wed, 02 Mar 2022 05:36:29 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 05/14] scsi: core: Cache VPD pages b0, b1, b2 Date: Wed, 2 Mar 2022 00:35:50 -0500 Message-Id: <20220302053559.32147-6-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: vEqFnmZBRPRGU2igZyzj93NljSZpG99i X-Proofpoint-ORIG-GUID: vEqFnmZBRPRGU2igZyzj93NljSZpG99i Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Bart Van Assche Reviewed-by: Hannes Reinecke --- drivers/scsi/scsi.c | 6 ++++++ drivers/scsi/scsi_sysfs.c | 28 ++++++++++++++++++++++++++++ include/scsi/scsi_device.h | 4 ++++ 3 files changed, 38 insertions(+) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c6221a2ca04e..524e03aba9ef 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -488,6 +488,12 @@ void scsi_attach_vpd(struct scsi_device *sdev) scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83); if (vpd_buf->data[i] == 0x89) scsi_update_vpd_page(sdev, 0x89, &sdev->vpd_pg89); + if (vpd_buf->data[i] == 0xb0) + scsi_update_vpd_page(sdev, 0xb0, &sdev->vpd_pgb0); + if (vpd_buf->data[i] == 0xb1) + scsi_update_vpd_page(sdev, 0xb1, &sdev->vpd_pgb1); + if (vpd_buf->data[i] == 0xb2) + scsi_update_vpd_page(sdev, 0xb2, &sdev->vpd_pgb2); } kfree(vpd_buf); } diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 226a50944c00..1ed45de9970d 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -448,6 +448,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) struct list_head *this, *tmp; struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL; + struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL; unsigned long flags; struct module *mod; @@ -490,6 +491,12 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) lockdep_is_held(&sdev->inquiry_mutex)); vpd_pg89 = rcu_replace_pointer(sdev->vpd_pg89, vpd_pg89, lockdep_is_held(&sdev->inquiry_mutex)); + vpd_pgb0 = rcu_replace_pointer(sdev->vpd_pgb0, vpd_pgb0, + lockdep_is_held(&sdev->inquiry_mutex)); + vpd_pgb1 = rcu_replace_pointer(sdev->vpd_pgb1, vpd_pgb1, + lockdep_is_held(&sdev->inquiry_mutex)); + vpd_pgb2 = rcu_replace_pointer(sdev->vpd_pgb2, vpd_pgb2, + lockdep_is_held(&sdev->inquiry_mutex)); mutex_unlock(&sdev->inquiry_mutex); if (vpd_pg0) @@ -500,6 +507,12 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) kfree_rcu(vpd_pg80, rcu); if (vpd_pg89) kfree_rcu(vpd_pg89, rcu); + if (vpd_pgb0) + kfree_rcu(vpd_pgb0, rcu); + if (vpd_pgb1) + kfree_rcu(vpd_pgb1, rcu); + if (vpd_pgb2) + kfree_rcu(vpd_pgb2, rcu); kfree(sdev->inquiry); kfree(sdev); @@ -913,6 +926,9 @@ static struct bin_attribute dev_attr_vpd_##_page = { \ sdev_vpd_pg_attr(pg83); sdev_vpd_pg_attr(pg80); sdev_vpd_pg_attr(pg89); +sdev_vpd_pg_attr(pgb0); +sdev_vpd_pg_attr(pgb1); +sdev_vpd_pg_attr(pgb2); sdev_vpd_pg_attr(pg0); static ssize_t show_inquiry(struct file *filep, struct kobject *kobj, @@ -1250,6 +1266,15 @@ static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_vpd_pg89 && !sdev->vpd_pg89) return 0; + if (attr == &dev_attr_vpd_pgb0 && !sdev->vpd_pgb0) + return 0; + + if (attr == &dev_attr_vpd_pgb1 && !sdev->vpd_pgb1) + return 0; + + if (attr == &dev_attr_vpd_pgb2 && !sdev->vpd_pgb2) + return 0; + return S_IRUGO; } @@ -1296,6 +1321,9 @@ static struct bin_attribute *scsi_sdev_bin_attrs[] = { &dev_attr_vpd_pg83, &dev_attr_vpd_pg80, &dev_attr_vpd_pg89, + &dev_attr_vpd_pgb0, + &dev_attr_vpd_pgb1, + &dev_attr_vpd_pgb2, &dev_attr_inquiry, NULL }; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 144d3a801c8d..fd6a803ac8cd 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -149,6 +149,10 @@ struct scsi_device { struct scsi_vpd __rcu *vpd_pg83; struct scsi_vpd __rcu *vpd_pg80; struct scsi_vpd __rcu *vpd_pg89; + struct scsi_vpd __rcu *vpd_pgb0; + struct scsi_vpd __rcu *vpd_pgb1; + struct scsi_vpd __rcu *vpd_pgb2; + struct scsi_target *sdev_target; blist_flags_t sdev_bflags; /* black/white flags as also found in From patchwork Wed Mar 2 05:35:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6C17C433F5 for ; Wed, 2 Mar 2022 05:36:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239591AbiCBFhS (ORCPT ); Wed, 2 Mar 2022 00:37:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238131AbiCBFhN (ORCPT ); Wed, 2 Mar 2022 00:37:13 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC073B16F2 for ; Tue, 1 Mar 2022 21:36:31 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222mYWQ014686 for ; Wed, 2 Mar 2022 05:36:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=0LLMyZhZjz4qMc2o8EuyyAy4o3yGULcdQ9C4Xi4+nss=; b=ytz0ctY8htiH9ppNYzuSqyoxB1DyB5pLAZO5KIfB5eeJ9ars2AjWCBay72zFAikwKtDw 1oj6WMrx0SuYpwdSu/wNHwFZu57TKxt7O4Fjd3Q3qXJKN/A4f8+GQozJ6dxCtD1ZiU37 8488r2Gjn0iaZr/mqBGqY9W9H8FBKda5v12fosvV8h0mvmERF+BamUC8KECrrHUt8jh4 TuUvpvXtOLAoHRFmuacMLIv1N6nTrP1LSJRbBKFmVn/oyGGoAMzgaQ/mjIToAMIrir8M wV2X8dqobpaRAvEKbTCzh1ibszE3ZxiSJzXdwFj6k+bQYwU+kyH4aPHPIS18k+7j+pLn jw== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh15amq8s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:31 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IpAh175833 for ; Wed, 2 Mar 2022 05:36:30 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vahw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:30 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZf014395 for ; Wed, 2 Mar 2022 05:36:30 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-7; Wed, 02 Mar 2022 05:36:29 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 06/14] scsi: sd: Use cached ATA Information VPD page Date: Wed, 2 Mar 2022 00:35:51 -0500 Message-Id: <20220302053559.32147-7-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: eTF4YuAL-mjpXUhY7NKsl9A1jf9gv1jw X-Proofpoint-GUID: eTF4YuAL-mjpXUhY7NKsl9A1jf9gv1jw Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Since the ATA Information VPD is now cached at device discovery time it is no longer necessary to request this page when we configure WRITE SAME. Instead use the cached information to determine if this disk sits behind a SCSI-ATA translation layer. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Reviewed-by: Johannes Thumshirn --- drivers/scsi/sd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2f9d160bc8c2..d6aec12aef76 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3024,8 +3024,7 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) } if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) { - /* too large values might cause issues with arcmsr */ - int vpd_buf_len = 64; + struct scsi_vpd *vpd; sdev->no_report_opcodes = 1; @@ -3033,8 +3032,11 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) * CODES is unsupported and the device has an ATA * Information VPD page (SAT). */ - if (!scsi_get_vpd_page(sdev, 0x89, buffer, vpd_buf_len)) + rcu_read_lock(); + vpd = rcu_dereference(sdev->vpd_pg89); + if (vpd) sdev->no_write_same = 1; + rcu_read_unlock(); } if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16) == 1) From patchwork Wed Mar 2 05:35:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765495 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6A248C433EF for ; Wed, 2 Mar 2022 05:36:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239615AbiCBFhW (ORCPT ); Wed, 2 Mar 2022 00:37:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238851AbiCBFhO (ORCPT ); Wed, 2 Mar 2022 00:37:14 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66B68B16D3 for ; Tue, 1 Mar 2022 21:36:32 -0800 (PST) Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222iL0V001861 for ; Wed, 2 Mar 2022 05:36:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=/P5q7khzDGWORmvHzneH31Pu5xI/KSICky+FITQwTec=; b=RlH/WrA5ZhhTY3hPTz2KhblsbYN25rIpC2R3/++3g/RmtxWwI5FjT9/fB742rKzYDn6u STzyVl9o7k4u/OE8P0rhlskDLraa8g0yc8dHjMjwpB0sijm8rWOt4P3EIi8M27wAnH8r DP61tvlnTvKDJBK6kw5sqs1Gu+Pg870NjegfAsjh6J1kKhGHoTEeAtcRGWFLYYl31G5J jNUdIc72c114Dsb3hGqQ3ehj355fYS06Ws3D+Co9OXuZfy6XgvCoXROeb8J+mno3Hx8e WPB4g2I+pJRJ7wSzZU+dwAb9bmDRo055hbUOsxsDnLQMnbL0l2rSV3J5XLh1U9tIRWd9 5Q== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh1k44uec-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:31 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IqDM175869 for ; Wed, 2 Mar 2022 05:36:30 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vaj8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:30 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZh014395 for ; Wed, 2 Mar 2022 05:36:30 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-8; Wed, 02 Mar 2022 05:36:30 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 07/14] scsi: sd: Switch to using scsi_device VPD pages Date: Wed, 2 Mar 2022 00:35:52 -0500 Message-Id: <20220302053559.32147-8-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: p0kXBoXRdWWqJAyNe_kM1ftWTDOmcDVT X-Proofpoint-GUID: p0kXBoXRdWWqJAyNe_kM1ftWTDOmcDVT Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Use the VPD pages already provided by the SCSI midlayer. No need to request them individually in the SCSI disk driver. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Reviewed-by: Johannes Thumshirn --- drivers/scsi/sd.c | 80 +++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d6aec12aef76..84c04691841f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2872,39 +2872,39 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) static void sd_read_block_limits(struct scsi_disk *sdkp) { unsigned int sector_sz = sdkp->device->sector_size; - const int vpd_len = 64; - unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); + struct scsi_vpd *vpd; - if (!buffer || - /* Block Limits VPD */ - scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len)) + rcu_read_lock(); + + vpd = rcu_dereference(sdkp->device->vpd_pgb0); + if (!vpd || vpd->len < 16) goto out; blk_queue_io_min(sdkp->disk->queue, - get_unaligned_be16(&buffer[6]) * sector_sz); + get_unaligned_be16(&vpd->data[6]) * sector_sz); - sdkp->max_xfer_blocks = get_unaligned_be32(&buffer[8]); - sdkp->opt_xfer_blocks = get_unaligned_be32(&buffer[12]); + sdkp->max_xfer_blocks = get_unaligned_be32(&vpd->data[8]); + sdkp->opt_xfer_blocks = get_unaligned_be32(&vpd->data[12]); - if (buffer[3] == 0x3c) { + if (vpd->len >= 64) { unsigned int lba_count, desc_count; - sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); + sdkp->max_ws_blocks = (u32)get_unaligned_be64(&vpd->data[36]); if (!sdkp->lbpme) goto out; - lba_count = get_unaligned_be32(&buffer[20]); - desc_count = get_unaligned_be32(&buffer[24]); + lba_count = get_unaligned_be32(&vpd->data[20]); + desc_count = get_unaligned_be32(&vpd->data[24]); if (lba_count && desc_count) sdkp->max_unmap_blocks = lba_count; - sdkp->unmap_granularity = get_unaligned_be32(&buffer[28]); + sdkp->unmap_granularity = get_unaligned_be32(&vpd->data[28]); - if (buffer[32] & 0x80) + if (vpd->data[32] & 0x80) sdkp->unmap_alignment = - get_unaligned_be32(&buffer[32]) & ~(1 << 31); + get_unaligned_be32(&vpd->data[32]) & ~(1 << 31); if (!sdkp->lbpvpd) { /* LBP VPD page not provided */ @@ -2926,7 +2926,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) } out: - kfree(buffer); + rcu_read_unlock(); } /** @@ -2936,18 +2936,21 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) static void sd_read_block_characteristics(struct scsi_disk *sdkp) { struct request_queue *q = sdkp->disk->queue; - unsigned char *buffer; + struct scsi_vpd *vpd; u16 rot; - const int vpd_len = 64; + u8 zoned; - buffer = kmalloc(vpd_len, GFP_KERNEL); + rcu_read_lock(); + vpd = rcu_dereference(sdkp->device->vpd_pgb1); - if (!buffer || - /* Block Device Characteristics VPD */ - scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len)) - goto out; + if (!vpd || vpd->len < 8) { + rcu_read_unlock(); + return; + } - rot = get_unaligned_be16(&buffer[4]); + rot = get_unaligned_be16(&vpd->data[4]); + zoned = (vpd->data[8] >> 4) & 3; + rcu_read_unlock(); if (rot == 1) { blk_queue_flag_set(QUEUE_FLAG_NONROT, q); @@ -2958,7 +2961,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) /* Host-managed */ blk_queue_set_zoned(sdkp->disk, BLK_ZONED_HM); } else { - sdkp->zoned = (buffer[8] >> 4) & 3; + sdkp->zoned = zoned; if (sdkp->zoned == 1) { /* Host-aware */ blk_queue_set_zoned(sdkp->disk, BLK_ZONED_HA); @@ -2969,7 +2972,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) } if (!sdkp->first_scan) - goto out; + return; if (blk_queue_is_zoned(q)) { sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n", @@ -2982,9 +2985,6 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) sd_printk(KERN_NOTICE, sdkp, "Drive-managed SMR disk\n"); } - - out: - kfree(buffer); } /** @@ -2993,24 +2993,24 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) */ static void sd_read_block_provisioning(struct scsi_disk *sdkp) { - unsigned char *buffer; - const int vpd_len = 8; + struct scsi_vpd *vpd; if (sdkp->lbpme == 0) return; - buffer = kmalloc(vpd_len, GFP_KERNEL); + rcu_read_lock(); + vpd = rcu_dereference(sdkp->device->vpd_pgb2); - if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) - goto out; + if (!vpd || vpd->len < 8) { + rcu_read_unlock(); + return; + } sdkp->lbpvpd = 1; - sdkp->lbpu = (buffer[5] >> 7) & 1; /* UNMAP */ - sdkp->lbpws = (buffer[5] >> 6) & 1; /* WRITE SAME(16) with UNMAP */ - sdkp->lbpws10 = (buffer[5] >> 5) & 1; /* WRITE SAME(10) with UNMAP */ - - out: - kfree(buffer); + sdkp->lbpu = (vpd->data[5] >> 7) & 1; /* UNMAP */ + sdkp->lbpws = (vpd->data[5] >> 6) & 1; /* WRITE SAME(16) w/ UNMAP */ + sdkp->lbpws10 = (vpd->data[5] >> 5) & 1; /* WRITE SAME(10) w/ UNMAP */ + rcu_read_unlock(); } static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) From patchwork Wed Mar 2 05:35:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765496 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C903C43217 for ; Wed, 2 Mar 2022 05:36:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239638AbiCBFhX (ORCPT ); Wed, 2 Mar 2022 00:37:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239520AbiCBFhQ (ORCPT ); Wed, 2 Mar 2022 00:37:16 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F29DBB16D4 for ; Tue, 1 Mar 2022 21:36:33 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222jYNB010945; Wed, 2 Mar 2022 05:36:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=GkDE/hlNw16W+LVhEbObnJBC9YC+b98WI5GqfISARrI=; b=AtWq515GPMNIDsjAE6fJNcPvOTLyUHN8bF8k8AcpNYyHlfdlNScPfpie4w6LxKyFk2Es ZExkq7jmqy7TwpMSehgpeRTmRfpeZUXLPjEH9NV/xZZEmP3OUp16Bka6VBYdoPd/GVDQ GUwBaSnc9czNRKj/OMH1L8QvL/Ua3BIH9sMrzW6K7XmLso0Swtcr1O/vE2u54sAlCoFM gXpwZp1VtOhAbNhyeArq4sPrqbOp5XGelVf6AAQK1a+wi9DDJN4u/w99E4qJ30ESP+oD fG0JwHym2Fvj+25gUSY2/JRXIsBEle5Ww8+CP4TBMn6/ay2Mmzzi6sD+U3OQw5NNeHdI xA== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh14bvwck-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:32 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IqLS175868; Wed, 2 Mar 2022 05:36:31 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vajg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:31 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZj014395; Wed, 2 Mar 2022 05:36:31 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-9; Wed, 02 Mar 2022 05:36:31 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" , Bernhard Sulzer Subject: [PATCH 08/14] scsi: sd: Optimal I/O size should be a multiple of reported granularity Date: Wed, 2 Mar 2022 00:35:53 -0500 Message-Id: <20220302053559.32147-9-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: BClhjpCyshYtpq2LqtMEiaaBV-IiAjmD X-Proofpoint-ORIG-GUID: BClhjpCyshYtpq2LqtMEiaaBV-IiAjmD Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Commit a83da8a4509d ("scsi: sd: Optimal I/O size should be a multiple of physical block size") validated the reported optimal I/O size against the physical block size to overcome problems with devices reporting nonsensical transfer sizes. However, some devices claim conformity to older SCSI versions that predate the physical block size being reported. Other devices do not report a physical block size at all. We need to be able to validate the optimal I/O size on those devices as well. Many devices report an OPTIMAL TRANSFER LENGTH GRANULARITY in the same VPD page as the OPTIMAL TRANSFER LENGTH. Use this value to validate the optimal I/O size. Also check that the reported granularity is a multiple of the physical block size, if supported. Link: https://lore.kernel.org/r/33fb522e-4f61-1b76-914f-c9e6a3553c9b@gmail.com Reported-by: Bernhard Sulzer Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig --- drivers/scsi/sd.c | 45 +++++++++++++++++++++++++++++++++++++++++---- drivers/scsi/sd.h | 1 + 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 84c04691841f..8595c4f2e915 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2871,7 +2871,6 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) */ static void sd_read_block_limits(struct scsi_disk *sdkp) { - unsigned int sector_sz = sdkp->device->sector_size; struct scsi_vpd *vpd; rcu_read_lock(); @@ -2880,9 +2879,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) if (!vpd || vpd->len < 16) goto out; - blk_queue_io_min(sdkp->disk->queue, - get_unaligned_be16(&vpd->data[6]) * sector_sz); - + sdkp->min_xfer_blocks = get_unaligned_be16(&vpd->data[6]); sdkp->max_xfer_blocks = get_unaligned_be32(&vpd->data[8]); sdkp->opt_xfer_blocks = get_unaligned_be32(&vpd->data[12]); @@ -3140,6 +3137,29 @@ static void sd_read_cpr(struct scsi_disk *sdkp) kfree(buffer); } +static bool sd_validate_min_xfer_size(struct scsi_disk *sdkp) +{ + struct scsi_device *sdp = sdkp->device; + unsigned int min_xfer_bytes = + logical_to_bytes(sdp, sdkp->min_xfer_blocks); + + if (sdkp->min_xfer_blocks == 0) + return false; + + if (min_xfer_bytes & (sdkp->physical_block_size - 1)) { + sd_first_printk(KERN_WARNING, sdkp, + "Preferred minimum I/O size %u bytes not a " \ + "multiple of physical block size (%u bytes)\n", + min_xfer_bytes, sdkp->physical_block_size); + sdkp->min_xfer_blocks = 0; + return false; + } + + sd_first_printk(KERN_INFO, sdkp, "Preferred minimum I/O size %u bytes\n", + min_xfer_bytes); + return true; +} + /* * Determine the device's preferred I/O size for reads and writes * unless the reported value is unreasonably small, large, not a @@ -3151,6 +3171,8 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp, struct scsi_device *sdp = sdkp->device; unsigned int opt_xfer_bytes = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); + unsigned int min_xfer_bytes = + logical_to_bytes(sdp, sdkp->min_xfer_blocks); if (sdkp->opt_xfer_blocks == 0) return false; @@ -3179,6 +3201,15 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp, return false; } + if (min_xfer_bytes && opt_xfer_bytes & (min_xfer_bytes - 1)) { + sd_first_printk(KERN_WARNING, sdkp, + "Optimal transfer size %u bytes not a " \ + "multiple of preferred minimum block " \ + "size (%u bytes)\n", + opt_xfer_bytes, min_xfer_bytes); + return false; + } + if (opt_xfer_bytes & (sdkp->physical_block_size - 1)) { sd_first_printk(KERN_WARNING, sdkp, "Optimal transfer size %u bytes not a " \ @@ -3271,6 +3302,12 @@ static int sd_revalidate_disk(struct gendisk *disk) dev_max = min_not_zero(dev_max, sdkp->max_xfer_blocks); q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max); + if (sd_validate_min_xfer_size(sdkp)) + blk_queue_io_min(sdkp->disk->queue, + logical_to_bytes(sdp, sdkp->min_xfer_blocks)); + else + blk_queue_io_min(sdkp->disk->queue, 0); + if (sd_validate_opt_xfer_size(sdkp, dev_max)) { q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 2e5932bde43d..f4fbca90e997 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -91,6 +91,7 @@ struct scsi_disk { atomic_t openers; sector_t capacity; /* size in logical blocks */ int max_retries; + u32 min_xfer_blocks; u32 max_xfer_blocks; u32 opt_xfer_blocks; u32 max_ws_blocks; From patchwork Wed Mar 2 05:35:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765498 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC7E0C4332F for ; Wed, 2 Mar 2022 05:36:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239635AbiCBFhX (ORCPT ); Wed, 2 Mar 2022 00:37:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239174AbiCBFhQ (ORCPT ); Wed, 2 Mar 2022 00:37:16 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BFB0B16DA for ; Tue, 1 Mar 2022 21:36:33 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222xusi014684 for ; Wed, 2 Mar 2022 05:36:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=spiTjECS3j/j0hj9fPE/LCcxtLqmuh29URnhLx1qvo8=; b=vDT9nen1GtL5b4yNWZon6aBAA6/d8ZgHN93NEBVGniTUeh9RLPKjVXUvyPuMranQL+jh /R7VdrCFEiRJGNy1kQemc0pVuFncC8+oeyVMWb6DZdgty0Tv35PthhFRQiXGnb46CPeF uE6mIIkrWyhqnVbvh0kmfYEyVs+2clHyOxkzoPu9wu9zPmNIBSPU5bxIvDW1axQhrXAM /fqVcHXDBp/53pqWhbxtIDBJyAhUIL4zgSqTROpMUGR1MgfnKc+r6Ts6p6B+EMY5sZSW u73/7WjBzEW+/ODSmeTbadZRwK7l0BlsHCIWdCOqCRXbVbOeOdgvdk9A4nIrYQp2VKRE vQ== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh15amq8t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:32 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IqLT175868 for ; Wed, 2 Mar 2022 05:36:32 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vajv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:31 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZl014395 for ; Wed, 2 Mar 2022 05:36:31 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-10; Wed, 02 Mar 2022 05:36:31 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 09/14] scsi: sd: Fix discard errors during revalidate Date: Wed, 2 Mar 2022 00:35:54 -0500 Message-Id: <20220302053559.32147-10-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: W2pIoSh-M4BUfatyCRc1Te3xuqnuMr89 X-Proofpoint-GUID: W2pIoSh-M4BUfatyCRc1Te3xuqnuMr89 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org We previously switched to SD_LBP_WS16 mode by default if a device identified itself as being thinly provisioned. This was done for compatibility with older devices that predate the Logical Block Provisioning VPD page and the introduction of the separate UNMAP command. Since WS16 was originally the only option there was no way to explicitly signal support for it outside of the device reporting LBPME=1. And thus we switch it on every time we discover a thinly provisioned device in READ CAPACITY(16). Some devices, however, report different values for unmap operations performed with WRITE SAME and ones performed with the UNMAP command. For instance a device may report that it can unmap 64KB with WRITE SAME but only 32KB with UNMAP. If the device then reports a preference for UNMAP in the LBP VPD, there is a tiny window between the WS16 being enabled and the UNMAP limit being set. And during that window the block layer can issue 64KB discards which, when being prepped by the sd driver, now violate the UNMAP limit. To avoid temporarily setting WS16 during revalidate, relocate all the provisioning mode setting heuristics to sd_config_discard(). Introduce a new mode, SD_LBP_DEFAULT, which sd_revalidate() will use to trigger the heuristic to select a suitable mode based on what the device reports. SD_LBP_DEFAULT can also be triggered in sysfs via the string "default", should a user decide to change back to the kernel-chosen provisioning mode after manually overriding the default. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig --- drivers/scsi/sd.c | 124 +++++++++++++++++++++++++++++++++++----------- drivers/scsi/sd.h | 9 ++-- 2 files changed, 101 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8595c4f2e915..eae5c81ae515 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -100,7 +100,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC); #define SD_MINORS 16 -static void sd_config_discard(struct scsi_disk *, unsigned int); +static void sd_config_discard(struct scsi_disk *, enum sd_lbp_mode); static void sd_config_write_same(struct scsi_disk *); static int sd_revalidate_disk(struct gendisk *); static void sd_unlock_native_capacity(struct gendisk *disk); @@ -374,6 +374,7 @@ static DEVICE_ATTR_RO(thin_provisioning); /* sysfs_match_string() requires dense arrays */ static const char *lbp_mode[] = { + [SD_LBP_DEFAULT] = "default", [SD_LBP_FULL] = "full", [SD_LBP_UNMAP] = "unmap", [SD_LBP_WS16] = "writesame_16", @@ -414,6 +415,11 @@ provisioning_mode_store(struct device *dev, struct device_attribute *attr, if (mode < 0) return -EINVAL; + if (mode == SD_LBP_DEFAULT) + sdkp->provisioning_override = false; + else + sdkp->provisioning_override = true; + sd_config_discard(sdkp, mode); return count; @@ -812,23 +818,95 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, return protect; } -static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) +/* + * It took many iterations in T10 to develop a model for thinly provisioned + * devices. Linux was an early adopter of the concept of discards, and as a + * result of the SCSI spec being a moving target for several years, we have a + * set of heuristics in place that allow us to support a wide variety of + * devices that predate the final SBC specification. + * + * These heuristics are triggered by default during device discovery, but the + * user can subsequently override what the kernel decided by writing a + * particular mode string to a scsi_disk's provisioning_mode node in sysfs. + * For devices that predate any of the provisioning knobs in the spec but rely + * on zero-detection, it is possible to enable discard through the + * "writesame_zero" override. + * + * For Linux to automatically identify a SCSI disk as being thinly + * provisioned, the device must set the LBPME bit in READ CAPACITY(16). + * + * In the ratified version of T10 SBC-4, a device must also provide a Logical + * Block Provisioning VPD page which has three fields that indicate which + * provisioning commands the device supports. The device should also implement + * the extended version of the Block Limits VPD which is used to indicate any + * limitations on the size of unmap operations as well as alignment and + * granularity used inside the device. + * + * If the device supports the Logical Block Provisioning VPD, and sets the + * LBPU flag, and reports a MAXIMUM UNMAP LBA COUNT > 0 and a MAXIMUM UNMAP + * BLOCK DESCRIPTOR count > 0 in the extended Block Limits VPD, then we will + * use UNMAP for discards. Otherwise, if the device set LBPWS in the LBP VPD, + * we will use WRITE SAME(16) with the UNMAP bit set for discards. Otherwise, + * if the device sets LBPWS10 in the LBP VPD, then we will use WRITE SAME(10) + * with the UNMAP bit set for discards. + * + * If the device does *not* support the Logical Block Provisioning VPD, we + * rely on the extended version of the Block Limits VPD. If that is supported, + * and and the device reports a MAXIMUM UNMAP LBA COUNT > 0 and a MAXIMUM + * UNMAP BLOCK DESCRIPTOR count > 0, then we will use UNMAP for discards. + * Otherwise we will use WRITE SAME(16) with the UNMAP bit set for discards. + * + * If a device implements the *short* version of the Block Limits VPD or does + * not have a Block Limits VPD at all, we default to using WRITE SAME(16) with + * the UNMAP bit set for discards. + * + * The possible values for provisioning_mode in sysfs are: + * + * "default" - use heuristics outlined above to decide on command + * "full" - the device does not support discard + * "unmap" - use the UNMAP command + * "writesame_16" - use the WRITE SAME(16) command with the UNMAP bit set + * "writesame_10" - use the WRITE SAME(10) command with the UNMAP bit set + * "writesame_zero" - use WRITE SAME(16) with a zeroed payload, no UNMAP bit + * "disabled" - discards disabled due to command failure + */ +static void sd_config_discard(struct scsi_disk *sdkp, enum sd_lbp_mode mode) { struct request_queue *q = sdkp->disk->queue; unsigned int logical_block_size = sdkp->device->sector_size; unsigned int max_blocks = 0; - q->limits.discard_alignment = - sdkp->unmap_alignment * logical_block_size; - q->limits.discard_granularity = - max(sdkp->physical_block_size, - sdkp->unmap_granularity * logical_block_size); - sdkp->provisioning_mode = mode; + if (mode == SD_LBP_DEFAULT && !sdkp->provisioning_override) { + if (sdkp->lbpme) { /* Logical Block Provisioning Enabled */ + if (sdkp->lbpvpd) { /* Logical Block Provisioning VPD */ + if (sdkp->lbpu && sdkp->max_unmap_blocks) + mode = SD_LBP_UNMAP; + else if (sdkp->lbpws) + mode = SD_LBP_WS16; + else if (sdkp->lbpws10) + mode = SD_LBP_WS10; + else + mode = SD_LBP_FULL; + } else if (sdkp->lblvpd) { /* Long Block Limits VPD */ + if (sdkp->max_unmap_blocks) + mode = SD_LBP_UNMAP; + else + mode = SD_LBP_WS16; + } else /* LBPME only, no VPDs supported */ + mode = SD_LBP_WS16; + } else + mode = SD_LBP_FULL; + } switch (mode) { - + case SD_LBP_DEFAULT: case SD_LBP_FULL: case SD_LBP_DISABLE: + if (mode == SD_LBP_DISABLE) + sdkp->provisioning_override = true; + sdkp->provisioning_mode = mode; + q->limits.discard_alignment = 0; + q->limits.discard_granularity = 0; blk_queue_max_discard_sectors(q, 0); blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q); return; @@ -862,6 +940,12 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) break; } + sdkp->provisioning_mode = mode; + q->limits.discard_alignment = + sdkp->unmap_alignment * logical_block_size; + q->limits.discard_granularity = + max(sdkp->physical_block_size, + sdkp->unmap_granularity * logical_block_size); blk_queue_max_discard_sectors(q, max_blocks * (logical_block_size >> 9)); blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); } @@ -2355,8 +2439,6 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, if (buffer[14] & 0x40) /* LBPRZ */ sdkp->lbprz = 1; - - sd_config_discard(sdkp, SD_LBP_WS16); } sdkp->capacity = lba + 1; @@ -2886,6 +2968,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) if (vpd->len >= 64) { unsigned int lba_count, desc_count; + sdkp->lblvpd = 1; sdkp->max_ws_blocks = (u32)get_unaligned_be64(&vpd->data[36]); if (!sdkp->lbpme) @@ -2902,24 +2985,6 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) if (vpd->data[32] & 0x80) sdkp->unmap_alignment = get_unaligned_be32(&vpd->data[32]) & ~(1 << 31); - - if (!sdkp->lbpvpd) { /* LBP VPD page not provided */ - - if (sdkp->max_unmap_blocks) - sd_config_discard(sdkp, SD_LBP_UNMAP); - else - sd_config_discard(sdkp, SD_LBP_WS16); - - } else { /* LBP VPD page tells us what to use */ - if (sdkp->lbpu && sdkp->max_unmap_blocks) - sd_config_discard(sdkp, SD_LBP_UNMAP); - else if (sdkp->lbpws) - sd_config_discard(sdkp, SD_LBP_WS16); - else if (sdkp->lbpws10) - sd_config_discard(sdkp, SD_LBP_WS10); - else - sd_config_discard(sdkp, SD_LBP_DISABLE); - } } out: @@ -3287,6 +3352,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_write_same(sdkp, buffer); sd_read_security(sdkp, buffer); sd_read_cpr(sdkp); + sd_config_discard(sdkp, SD_LBP_DEFAULT); } /* diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index f4fbca90e997..57a8241163c5 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -51,12 +51,13 @@ enum { SD_MAX_WS16_BLOCKS = 0x7fffff, }; -enum { - SD_LBP_FULL = 0, /* Full logical block provisioning */ +enum sd_lbp_mode { + SD_LBP_DEFAULT = 0, /* Select mode based on what device reports */ + SD_LBP_FULL, /* Full logical block provisioning */ SD_LBP_UNMAP, /* Use UNMAP command */ SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ SD_LBP_WS10, /* Use WRITE SAME(10) with UNMAP bit */ - SD_LBP_ZERO, /* Use WRITE SAME(10) with zero payload */ + SD_LBP_ZERO, /* Use WRITE SAME(10) with zeroed payload */ SD_LBP_DISABLE, /* Discard disabled due to failed cmd */ }; @@ -108,6 +109,8 @@ struct scsi_disk { u8 provisioning_mode; u8 zeroing_mode; u8 nr_actuators; /* Number of actuators */ + bool lblvpd; + bool provisioning_override; unsigned ATO : 1; /* state of disk ATO bit */ unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ From patchwork Wed Mar 2 05:35:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765497 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D827C43219 for ; Wed, 2 Mar 2022 05:36:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239637AbiCBFhX (ORCPT ); Wed, 2 Mar 2022 00:37:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239449AbiCBFhQ (ORCPT ); Wed, 2 Mar 2022 00:37:16 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD0A8B16D3 for ; Tue, 1 Mar 2022 21:36:33 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222eVlZ010950 for ; Wed, 2 Mar 2022 05:36:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=IXXw93fNwl3rDuAUNJtQ4WYpdJEw+RuWHMFKcGlsqqo=; b=nkbGKmXk16pdY6GybVfrLs2sAZbRW2bxmcXi/aSXywzxp8TZibomKfOi2cw6D8BeS374 GM4z/40ez4Qr53FHVBKtNgPMl3IwLE6P+99/JHSoJXFqyFR25Ljcye/R0TxLvuUkldNf BRnDrh0/Y10aQYqCslwMY2CvJkBvzAVwdFVWFkW6MnuFWtEPtY8aZ4v1CXVhRZIDCVDt Lt5jWAouUiW2QH35D7PUoVkwT0fjH64CsNnSPGz1++sZIAOLkDX6+rFsZtPdHyaU/Y/d tVQlWN6gpJZFYUynjc+lkRGrMZG+2CV+6jxfvcDvulybExAj3lkojPb2pyKHPaE7QjmP Pw== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh14bvwcm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:33 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IuEu175938 for ; Wed, 2 Mar 2022 05:36:32 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vak9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:32 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZn014395 for ; Wed, 2 Mar 2022 05:36:32 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-11; Wed, 02 Mar 2022 05:36:32 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 10/14] scsi: sd: Move WRITE_ZEROES configuration to a separate function Date: Wed, 2 Mar 2022 00:35:55 -0500 Message-Id: <20220302053559.32147-11-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: Xed0Q1r28yW4QFwbs1BcedHgI8qGi1m0 X-Proofpoint-ORIG-GUID: Xed0Q1r28yW4QFwbs1BcedHgI8qGi1m0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org In preparation for adding support for the WRITE SAME(16) NDOB flag, move configuration of the WRITE_ZEROES operation to a separate function. This is done to facilitate fetching all VPD pages before choosing the appropriate zeroing method for a given device. The deferred configuration also allows us to mirror the discard behavior and permit the user to revert a device to the kernel default configuration by echoing "default" to the sysfs file. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig --- drivers/scsi/sd.c | 56 +++++++++++++++++++++++++++++++++-------------- drivers/scsi/sd.h | 7 ++++-- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index eae5c81ae515..ee4f4aea5f0f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -101,6 +101,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC); #define SD_MINORS 16 static void sd_config_discard(struct scsi_disk *, enum sd_lbp_mode); +static void sd_config_write_zeroes(struct scsi_disk *, enum sd_zeroing_mode); static void sd_config_write_same(struct scsi_disk *); static int sd_revalidate_disk(struct gendisk *); static void sd_unlock_native_capacity(struct gendisk *disk); @@ -428,10 +429,12 @@ static DEVICE_ATTR_RW(provisioning_mode); /* sysfs_match_string() requires dense arrays */ static const char *zeroing_mode[] = { + [SD_ZERO_DEFAULT] = "default", [SD_ZERO_WRITE] = "write", [SD_ZERO_WS] = "writesame", [SD_ZERO_WS16_UNMAP] = "writesame_16_unmap", [SD_ZERO_WS10_UNMAP] = "writesame_10_unmap", + [SD_ZERO_DISABLE] = "disabled", }; static ssize_t @@ -457,7 +460,12 @@ zeroing_mode_store(struct device *dev, struct device_attribute *attr, if (mode < 0) return -EINVAL; - sdkp->zeroing_mode = mode; + if (mode == SD_ZERO_DEFAULT) + sdkp->zeroing_override = false; + else + sdkp->zeroing_override = true; + + sd_config_write_zeroes(sdkp, mode); return count; } @@ -1049,6 +1057,31 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, return scsi_alloc_sgtables(cmd); } +static void sd_config_write_zeroes(struct scsi_disk *sdkp, + enum sd_zeroing_mode mode) +{ + struct request_queue *q = sdkp->disk->queue; + unsigned int logical_block_size = sdkp->device->sector_size; + + if (mode == SD_ZERO_DEFAULT && !sdkp->zeroing_override) { + if (sdkp->lbprz && sdkp->lbpws) + mode = SD_ZERO_WS16_UNMAP; + else if (sdkp->lbprz && sdkp->lbpws10) + mode = SD_ZERO_WS10_UNMAP; + else if (sdkp->max_ws_blocks) + mode = SD_ZERO_WS; + else + mode = SD_ZERO_WRITE; + } + + if (mode == SD_ZERO_DISABLE) + sdkp->zeroing_override = true; + + sdkp->zeroing_mode = mode; + blk_queue_max_write_zeroes_sectors(q, sdkp->max_ws_blocks * + (logical_block_size >> 9)); +} + static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd) { struct request *rq = scsi_cmd_to_rq(cmd); @@ -1079,12 +1112,11 @@ static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd) static void sd_config_write_same(struct scsi_disk *sdkp) { - struct request_queue *q = sdkp->disk->queue; unsigned int logical_block_size = sdkp->device->sector_size; if (sdkp->device->no_write_same) { sdkp->max_ws_blocks = 0; - goto out; + return; } /* Some devices can not handle block counts above 0xffff despite @@ -1103,15 +1135,6 @@ static void sd_config_write_same(struct scsi_disk *sdkp) sdkp->max_ws_blocks = 0; } - if (sdkp->lbprz && sdkp->lbpws) - sdkp->zeroing_mode = SD_ZERO_WS16_UNMAP; - else if (sdkp->lbprz && sdkp->lbpws10) - sdkp->zeroing_mode = SD_ZERO_WS10_UNMAP; - else if (sdkp->max_ws_blocks) - sdkp->zeroing_mode = SD_ZERO_WS; - else - sdkp->zeroing_mode = SD_ZERO_WRITE; - if (sdkp->max_ws_blocks && sdkp->physical_block_size > logical_block_size) { /* @@ -1131,10 +1154,6 @@ static void sd_config_write_same(struct scsi_disk *sdkp) bytes_to_logical(sdkp->device, sdkp->physical_block_size)); } - -out: - blk_queue_max_write_zeroes_sectors(q, sdkp->max_ws_blocks * - (logical_block_size >> 9)); } static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd) @@ -2126,6 +2145,8 @@ static int sd_done(struct scsi_cmnd *SCpnt) case WRITE_SAME: if (SCpnt->cmnd[1] & 8) { /* UNMAP */ sd_config_discard(sdkp, SD_LBP_DISABLE); + sd_config_write_zeroes(sdkp, + SD_ZERO_DISABLE); } else { sdkp->device->no_write_same = 1; sd_config_write_same(sdkp); @@ -3352,7 +3373,9 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_write_same(sdkp, buffer); sd_read_security(sdkp, buffer); sd_read_cpr(sdkp); + sd_config_write_same(sdkp); sd_config_discard(sdkp, SD_LBP_DEFAULT); + sd_config_write_zeroes(sdkp, SD_ZERO_DEFAULT); } /* @@ -3398,7 +3421,6 @@ static int sd_revalidate_disk(struct gendisk *disk) sdkp->first_scan = 0; set_capacity_and_notify(disk, logical_to_sectors(sdp, sdkp->capacity)); - sd_config_write_same(sdkp); kfree(buffer); /* diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 57a8241163c5..e0ee4215a3b4 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -61,11 +61,13 @@ enum sd_lbp_mode { SD_LBP_DISABLE, /* Discard disabled due to failed cmd */ }; -enum { - SD_ZERO_WRITE = 0, /* Use WRITE(10/16) command */ +enum sd_zeroing_mode { + SD_ZERO_DEFAULT = 0, /* Default mode based on what device reports */ + SD_ZERO_WRITE, /* Use WRITE(10/16) command */ SD_ZERO_WS, /* Use WRITE SAME(10/16) command */ SD_ZERO_WS16_UNMAP, /* Use WRITE SAME(16) with UNMAP */ SD_ZERO_WS10_UNMAP, /* Use WRITE SAME(10) with UNMAP */ + SD_ZERO_DISABLE, /* Write Zeroes disabled due to failed cmd */ }; struct scsi_disk { @@ -111,6 +113,7 @@ struct scsi_disk { u8 nr_actuators; /* Number of actuators */ bool lblvpd; bool provisioning_override; + bool zeroing_override; unsigned ATO : 1; /* state of disk ATO bit */ unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ From patchwork Wed Mar 2 05:35:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765501 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80C1CC433FE for ; Wed, 2 Mar 2022 05:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238651AbiCBFh0 (ORCPT ); Wed, 2 Mar 2022 00:37:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239528AbiCBFhR (ORCPT ); Wed, 2 Mar 2022 00:37:17 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5FBD3B16FD for ; Tue, 1 Mar 2022 21:36:34 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222bNBb010964 for ; Wed, 2 Mar 2022 05:36:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=yNi5yyuOMZJkepAmkYj38hAa/Fa8Vy9y7z/jpgDWPgM=; b=MrPqUTJRpH7mfo7tE8koqx/M9NIOg5eYxIcAv1Hu4cLtU7IemIpCbcHX77TybF0L3cvh NP5u2NctgROA7k2ljT9+5HJVAxsrWA14SRRyPG97L6PBffer9gxZy1qMfB7hkiWebPzl ucdxHP947Z2/Lu5iRV+HYMB+fKS8sN6bbKSSxx/UERXemfPn2hAoQpKCkMdgfzgJgheL HKwTLzLo+q2gtS+5hfxWFQH43QZdi5GpMDWdywiUvTE/tRO62pftcGDOjW20k0kfbZgr YkcpQYWP2g85HNK44zxYrnYYaB0SdRvCeXJLQgcAuv7kPqEr7a7/wUYxZ9RS8nr+6DuS cQ== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh14bvwcn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:33 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225Irp6175878 for ; Wed, 2 Mar 2022 05:36:33 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vakh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:33 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZp014395 for ; Wed, 2 Mar 2022 05:36:32 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-12; Wed, 02 Mar 2022 05:36:32 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 11/14] scsi: sd: Implement support for NDOB flag in WRITE SAME(16) Date: Wed, 2 Mar 2022 00:35:56 -0500 Message-Id: <20220302053559.32147-12-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: 5rRo_iM3GoXe1Z8KrjZ2mSCZfn3vpdKM X-Proofpoint-ORIG-GUID: 5rRo_iM3GoXe1Z8KrjZ2mSCZfn3vpdKM Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The NDOB flag removes the need for a zeroed logical block in the data-out buffer when using WRITE SAME(16) to zero block ranges. Implement support for NDOB in the SCSI disk driver to mirror WRITE ZEROES in NVMe. The only way to detect whether a device supports NDOB is through REPORT SUPPORTED OPERATION CODES. Since we can't safely send that command to all devices we only attempt this if the device implements the Block Provisioning VPD page and sets the LBPWS flag. If we issue a WRITE SAME(16) we check whether NDOB is set for the device in question. If so we do not allocate a zeroed page from the pool and simply issue the command with a zero-length payload. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Reviewed-by: Johannes Thumshirn --- drivers/scsi/scsi_trace.c | 3 +- drivers/scsi/sd.c | 93 ++++++++++++++++++++++++++------------- drivers/scsi/sd.h | 4 ++ 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/scsi_trace.c b/drivers/scsi/scsi_trace.c index 41a950075913..1d1f25f689ef 100644 --- a/drivers/scsi/scsi_trace.c +++ b/drivers/scsi/scsi_trace.c @@ -83,7 +83,8 @@ scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) cdb[1] >> 5); if (cdb[0] == WRITE_SAME_16) - trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); + trace_seq_printf(p, " unmap=%u ndob=%u", cdb[1] >> 3 & 1, + cdb[1] & 1); trace_seq_putc(p, 0); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ee4f4aea5f0f..2c2e86738578 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -379,6 +379,7 @@ static const char *lbp_mode[] = { [SD_LBP_FULL] = "full", [SD_LBP_UNMAP] = "unmap", [SD_LBP_WS16] = "writesame_16", + [SD_LBP_WS16_NDOB] = "writesame_16_ndob", [SD_LBP_WS10] = "writesame_10", [SD_LBP_ZERO] = "writesame_zero", [SD_LBP_DISABLE] = "disabled", @@ -429,12 +430,14 @@ static DEVICE_ATTR_RW(provisioning_mode); /* sysfs_match_string() requires dense arrays */ static const char *zeroing_mode[] = { - [SD_ZERO_DEFAULT] = "default", - [SD_ZERO_WRITE] = "write", - [SD_ZERO_WS] = "writesame", - [SD_ZERO_WS16_UNMAP] = "writesame_16_unmap", - [SD_ZERO_WS10_UNMAP] = "writesame_10_unmap", - [SD_ZERO_DISABLE] = "disabled", + [SD_ZERO_DEFAULT] = "default", + [SD_ZERO_WRITE] = "write", + [SD_ZERO_WS] = "writesame", + [SD_ZERO_WS16_UNMAP_NDOB] = "writesame_16_unmap_ndob", + [SD_ZERO_WS16_UNMAP] = "writesame_16_unmap", + [SD_ZERO_WS10_UNMAP] = "writesame_10_unmap", + [SD_ZERO_WS16_NDOB] = "writesame_16_ndob", + [SD_ZERO_DISABLE] = "disabled", }; static ssize_t @@ -870,13 +873,14 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, * * The possible values for provisioning_mode in sysfs are: * - * "default" - use heuristics outlined above to decide on command - * "full" - the device does not support discard - * "unmap" - use the UNMAP command - * "writesame_16" - use the WRITE SAME(16) command with the UNMAP bit set - * "writesame_10" - use the WRITE SAME(10) command with the UNMAP bit set - * "writesame_zero" - use WRITE SAME(16) with a zeroed payload, no UNMAP bit - * "disabled" - discards disabled due to command failure + * "default" - use heuristics outlined above to decide on command + * "full" - the device does not support discard + * "unmap" - use the UNMAP command + * "writesame_16" - use the WRITE SAME(16) command with the UNMAP bit set + * "writesame_16_ndob" - use WRITE SAME(16) with UNMAP and NDOB bits set + * "writesame_10" - use the WRITE SAME(10) command with the UNMAP bit set + * "writesame_zero" - use WRITE SAME(16) with a zeroed payload, no UNMAP bit + * "disabled" - discards disabled due to command failure */ static void sd_config_discard(struct scsi_disk *sdkp, enum sd_lbp_mode mode) { @@ -889,9 +893,12 @@ static void sd_config_discard(struct scsi_disk *sdkp, enum sd_lbp_mode mode) if (sdkp->lbpvpd) { /* Logical Block Provisioning VPD */ if (sdkp->lbpu && sdkp->max_unmap_blocks) mode = SD_LBP_UNMAP; - else if (sdkp->lbpws) - mode = SD_LBP_WS16; - else if (sdkp->lbpws10) + else if (sdkp->lbpws) { + if (sdkp->ndob) + mode = SD_LBP_WS16_NDOB; + else + mode = SD_LBP_WS16; + } else if (sdkp->lbpws10) mode = SD_LBP_WS10; else mode = SD_LBP_FULL; @@ -925,6 +932,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, enum sd_lbp_mode mode) break; case SD_LBP_WS16: + case SD_LBP_WS16_NDOB: if (sdkp->device->unmap_limit_for_ws) max_blocks = sdkp->max_unmap_blocks; else @@ -994,7 +1002,7 @@ static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd) } static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, - bool unmap) + bool unmap, bool ndob) { struct scsi_device *sdp = cmd->device; struct request *rq = scsi_cmd_to_rq(cmd); @@ -1003,23 +1011,32 @@ static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); u32 data_len = sdp->sector_size; - rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC); - if (!rq->special_vec.bv_page) - return BLK_STS_RESOURCE; - clear_highpage(rq->special_vec.bv_page); - rq->special_vec.bv_offset = 0; - rq->special_vec.bv_len = data_len; + if (ndob) { + rq->special_vec.bv_page = NULL; + rq->special_vec.bv_len = 0; + } else { + rq->special_vec.bv_page = + mempool_alloc(sd_page_pool, GFP_ATOMIC); + if (!rq->special_vec.bv_page) + return BLK_STS_RESOURCE; + clear_highpage(rq->special_vec.bv_page); + rq->special_vec.bv_len = data_len; + } + rq->rq_flags |= RQF_SPECIAL_PAYLOAD; + rq->special_vec.bv_offset = 0; cmd->cmd_len = 16; cmd->cmnd[0] = WRITE_SAME_16; if (unmap) cmd->cmnd[1] = 0x8; /* UNMAP */ + if (ndob) + cmd->cmnd[1] |= 0x1; /* NDOB */ put_unaligned_be64(lba, &cmd->cmnd[2]); put_unaligned_be32(nr_blocks, &cmd->cmnd[10]); cmd->allowed = sdkp->max_retries; - cmd->transfersize = data_len; + cmd->transfersize = rq->special_vec.bv_len; rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT; return scsi_alloc_sgtables(cmd); @@ -1064,10 +1081,14 @@ static void sd_config_write_zeroes(struct scsi_disk *sdkp, unsigned int logical_block_size = sdkp->device->sector_size; if (mode == SD_ZERO_DEFAULT && !sdkp->zeroing_override) { - if (sdkp->lbprz && sdkp->lbpws) + if (sdkp->lbprz && sdkp->lbpws && sdkp->ndob) + mode = SD_ZERO_WS16_UNMAP_NDOB; + else if (sdkp->lbprz && sdkp->lbpws) mode = SD_ZERO_WS16_UNMAP; else if (sdkp->lbprz && sdkp->lbpws10) mode = SD_ZERO_WS10_UNMAP; + else if (sdkp->max_ws_blocks && sdkp->ndob) + mode = SD_ZERO_WS16_NDOB; else if (sdkp->max_ws_blocks) mode = SD_ZERO_WS; else @@ -1092,8 +1113,10 @@ static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd) if (!(rq->cmd_flags & REQ_NOUNMAP)) { switch (sdkp->zeroing_mode) { + case SD_ZERO_WS16_UNMAP_NDOB: + return sd_setup_write_same16_cmnd(cmd, true, true); case SD_ZERO_WS16_UNMAP: - return sd_setup_write_same16_cmnd(cmd, true); + return sd_setup_write_same16_cmnd(cmd, true, false); case SD_ZERO_WS10_UNMAP: return sd_setup_write_same10_cmnd(cmd, true); } @@ -1104,8 +1127,12 @@ static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd) return BLK_STS_TARGET; } - if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff) - return sd_setup_write_same16_cmnd(cmd, false); + if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff) { + if (sdkp->zeroing_mode == SD_ZERO_WS16_NDOB) + return sd_setup_write_same16_cmnd(cmd, false, true); + else + return sd_setup_write_same16_cmnd(cmd, false, false); + } return sd_setup_write_same10_cmnd(cmd, false); } @@ -1372,7 +1399,9 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd) case SD_LBP_UNMAP: return sd_setup_unmap_cmnd(cmd); case SD_LBP_WS16: - return sd_setup_write_same16_cmnd(cmd, true); + return sd_setup_write_same16_cmnd(cmd, true, false); + case SD_LBP_WS16_NDOB: + return sd_setup_write_same16_cmnd(cmd, true, true); case SD_LBP_WS10: return sd_setup_write_same10_cmnd(cmd, true); case SD_LBP_ZERO: @@ -3122,9 +3151,13 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) rcu_read_unlock(); } - if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16) == 1) + if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16) == 1) { sdkp->ws16 = 1; + if (get_unaligned_be16(&buffer[2]) >= 2) + sdkp->ndob = buffer[5] & 1; + } + if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME) == 1) sdkp->ws10 = 1; } diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index e0ee4215a3b4..2cef9e884b2a 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -56,6 +56,7 @@ enum sd_lbp_mode { SD_LBP_FULL, /* Full logical block provisioning */ SD_LBP_UNMAP, /* Use UNMAP command */ SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ + SD_LBP_WS16_NDOB, /* Use WRITE SAME(16) with UNMAP + NDOB bits */ SD_LBP_WS10, /* Use WRITE SAME(10) with UNMAP bit */ SD_LBP_ZERO, /* Use WRITE SAME(10) with zeroed payload */ SD_LBP_DISABLE, /* Discard disabled due to failed cmd */ @@ -65,8 +66,10 @@ enum sd_zeroing_mode { SD_ZERO_DEFAULT = 0, /* Default mode based on what device reports */ SD_ZERO_WRITE, /* Use WRITE(10/16) command */ SD_ZERO_WS, /* Use WRITE SAME(10/16) command */ + SD_ZERO_WS16_UNMAP_NDOB,/* Use WRITE SAME(16) with UNMAP + NDOB bits */ SD_ZERO_WS16_UNMAP, /* Use WRITE SAME(16) with UNMAP */ SD_ZERO_WS10_UNMAP, /* Use WRITE SAME(10) with UNMAP */ + SD_ZERO_WS16_NDOB, /* Use WRITE SAME(16) with NDOB */ SD_ZERO_DISABLE, /* Write Zeroes disabled due to failed cmd */ }; @@ -114,6 +117,7 @@ struct scsi_disk { bool lblvpd; bool provisioning_override; bool zeroing_override; + bool ndob; unsigned ATO : 1; /* state of disk ATO bit */ unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ From patchwork Wed Mar 2 05:35:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765500 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D977C433F5 for ; Wed, 2 Mar 2022 05:36:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239645AbiCBFhZ (ORCPT ); Wed, 2 Mar 2022 00:37:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239577AbiCBFhR (ORCPT ); Wed, 2 Mar 2022 00:37:17 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43203B1884 for ; Tue, 1 Mar 2022 21:36:35 -0800 (PST) Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222jYNC010945; Wed, 2 Mar 2022 05:36:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=e4MgRVQO2C71j0KKI4qbziKW4PfAOGxxVRAmI4+mhbw=; b=eT6Rh2c4r2TM/a84Jie8YpTMy6BLi42F89RTq/2oteFs9lOYJaeBScI7tYs3VOYR2wLd OZgmQPBD2TGaf3blqvIZK5geM2QV1HNe6wtHytY7Wb7JEW/p3PdU+1WqIzRB0gf7UM4l TdXBjaLa9TUn/rznV+/lRVOe1jMjsJl+Zjk6Zj2e/sLk1i9HWmkITHDuPY+UrL/bXMs8 Av5pUgAZNkoSRyTBTAKdVI9EMZsWoqwRzv1+auEZ2Kd4LKWtQSBoo2aIxxEV56YMFpLd XS8W0uckZWOj00tm9CvpF4BwsWG9rC0O+BC/t7x8MDJOiZDfPmkf09zExO3P02z9A+y9 5g== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh14bvwcq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:34 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IuqD175937; Wed, 2 Mar 2022 05:36:33 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vakx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:33 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZr014395; Wed, 2 Mar 2022 05:36:33 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-13; Wed, 02 Mar 2022 05:36:33 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" , Damien Le Moal Subject: [PATCH 12/14] scsi: sd: sd_read_cpr() requires VPD pages Date: Wed, 2 Mar 2022 00:35:57 -0500 Message-Id: <20220302053559.32147-13-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-GUID: M8wgqdDm62CkHmUwTG1nXTjMXyVYjZ81 X-Proofpoint-ORIG-GUID: M8wgqdDm62CkHmUwTG1nXTjMXyVYjZ81 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org As such it should be called inside the scsi_device_supports_vpd() conditional. Cc: Damien Le Moal Fixes: e815d36548f0 ("scsi: sd: add concurrent positioning ranges support") Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Damien Le Moal Reviewed-by: Bart Van Assche Reviewed-by: Johannes Thumshirn --- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2c2e86738578..9d6b2205339d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3396,6 +3396,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_block_limits(sdkp); sd_read_block_characteristics(sdkp); sd_zbc_read_zones(sdkp, buffer); + sd_read_cpr(sdkp); } sd_print_capacity(sdkp, old_capacity); @@ -3405,7 +3406,6 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_app_tag_own(sdkp, buffer); sd_read_write_same(sdkp, buffer); sd_read_security(sdkp, buffer); - sd_read_cpr(sdkp); sd_config_write_same(sdkp); sd_config_discard(sdkp, SD_LBP_DEFAULT); sd_config_write_zeroes(sdkp, SD_ZERO_DEFAULT); From patchwork Wed Mar 2 05:35:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765502 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 080DEC433F5 for ; Wed, 2 Mar 2022 05:36:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238953AbiCBFh1 (ORCPT ); Wed, 2 Mar 2022 00:37:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239578AbiCBFhR (ORCPT ); Wed, 2 Mar 2022 00:37:17 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76CB1B16D5 for ; Tue, 1 Mar 2022 21:36:35 -0800 (PST) Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222i1m2001868 for ; Wed, 2 Mar 2022 05:36:35 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=slvaE0koUQp1MIiLuVvatiT/eGul5UCm0GxK+8Z5dG8=; b=aaRVvFWmT4YpRtv1eNDJWL42+DEvx19a/DcqDLi4djEp5kSCO35nTN0M8i6+YkOj5Gnd y507v4b2ybJUlWNsPxGaNyzzkx3Mosca377Wn33SQ7vv4W9gqh41iNZhylIL9VUqlBaj 5m2mY8gxTIpKzozPf2DbaUiwDCA+meNqmJtE5kEX1O1ORcTl7xCKHN88LAamEcMHrqNy 0k0wOjSNxTuWp96ySypgU7mcS/o+RKI5yJ8c2zNj9a9WKRHGKhJ1K6cm4i127gUQ4Z0f 39zjrcPM3DWaBW860JF4oOXwWhDubsoJzNW4IHgB4sO7pv2NdZ2E5sH7MTyPrmG6S9EC Mg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh1k44uef-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:35 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225IqLU175868 for ; Wed, 2 Mar 2022 05:36:34 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vamb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 02 Mar 2022 05:36:34 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZt014395 for ; Wed, 2 Mar 2022 05:36:33 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-14; Wed, 02 Mar 2022 05:36:33 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 13/14] scsi: sd: Reorganize DIF/DIX code to avoid calling revalidate twice Date: Wed, 2 Mar 2022 00:35:58 -0500 Message-Id: <20220302053559.32147-14-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: kTePIZVxPRCfXVit4QJ2d9yH-wQRfxGk X-Proofpoint-GUID: kTePIZVxPRCfXVit4QJ2d9yH-wQRfxGk Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org During device discovery we ended up calling revalidate twice and thus requested the same parameters multiple times. This was originally necessary due to the request_queue and gendisk needing to be instantiated to configure the block integrity profile. Since this dependency no longer exists, reorganize the integrity probing code so it can be run once at the end of discovery and drop the superfluous revalidate call. Postponing the registration step involves splitting sd_read_protection() into two functions, one to read the device protection type and one to configure the mode of operation. As part of this cleanup, make the printing code a bit less verbose. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn --- drivers/scsi/sd.c | 62 +++++++++++++++++++++++-------------------- drivers/scsi/sd_dif.c | 8 +++--- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 9d6b2205339d..163697dd799a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2338,40 +2338,48 @@ static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer { struct scsi_device *sdp = sdkp->device; u8 type; - int ret = 0; if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) { sdkp->protection_type = 0; - return ret; + return 0; } type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ - if (type > T10_PI_TYPE3_PROTECTION) - ret = -ENODEV; - else if (scsi_host_dif_capable(sdp->host, type)) - ret = 1; - - if (sdkp->first_scan || type != sdkp->protection_type) - switch (ret) { - case -ENODEV: - sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \ - " protection type %u. Disabling disk!\n", - type); - break; - case 1: - sd_printk(KERN_NOTICE, sdkp, - "Enabling DIF Type %u protection\n", type); - break; - case 0: - sd_printk(KERN_NOTICE, sdkp, - "Disabling DIF Type %u protection\n", type); - break; - } + if (type > T10_PI_TYPE3_PROTECTION) { + sd_printk(KERN_ERR, sdkp, "formatted with unsupported" \ + " protection type %u. Disabling disk!\n", + type); + sdkp->protection_type = 0; + return -ENODEV; + } sdkp->protection_type = type; - return ret; + return 0; +} + +static void sd_config_protection(struct scsi_disk *sdkp) +{ + struct scsi_device *sdp = sdkp->device; + + if (!sdkp->first_scan) + return; + + sd_dif_config_host(sdkp); + + if (!sdkp->protection_type) + return; + + if (!scsi_host_dif_capable(sdp->host, sdkp->protection_type)) { + sd_printk(KERN_NOTICE, sdkp, + "Disabling DIF Type %u protection\n", + sdkp->protection_type); + sdkp->protection_type = 0; + } + + sd_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n", + sdkp->protection_type); } static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, @@ -3409,6 +3417,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_config_write_same(sdkp); sd_config_discard(sdkp, SD_LBP_DEFAULT); sd_config_write_zeroes(sdkp, SD_ZERO_DEFAULT); + sd_config_protection(sdkp); } /* @@ -3667,11 +3676,6 @@ static int sd_probe(struct device *dev) goto out; } - if (sdkp->capacity) - sd_dif_config_host(sdkp); - - sd_revalidate_disk(gd); - if (sdkp->security) { sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit); if (sdkp->opal_dev) diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index 349950616adc..968993ee6d5d 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c @@ -59,8 +59,6 @@ void sd_dif_config_host(struct scsi_disk *sdkp) bi.profile = &t10_pi_type1_crc; bi.tuple_size = sizeof(struct t10_pi_tuple); - sd_printk(KERN_NOTICE, sdkp, - "Enabling DIX %s protection\n", bi.profile->name); if (dif && type) { bi.flags |= BLK_INTEGRITY_DEVICE_CAPABLE; @@ -72,11 +70,11 @@ void sd_dif_config_host(struct scsi_disk *sdkp) bi.tag_size = sizeof(u16) + sizeof(u32); else bi.tag_size = sizeof(u16); - - sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n", - bi.tag_size); } + sd_printk(KERN_NOTICE, sdkp, + "Enabling DIX %s, application tag size %u bytes\n", + bi.profile->name, bi.tag_size); out: blk_integrity_register(disk, &bi); } From patchwork Wed Mar 2 05:35:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 12765503 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71226C433EF for ; Wed, 2 Mar 2022 05:36:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239577AbiCBFh2 (ORCPT ); Wed, 2 Mar 2022 00:37:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239614AbiCBFhV (ORCPT ); Wed, 2 Mar 2022 00:37:21 -0500 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B567B16D3 for ; Tue, 1 Mar 2022 21:36:39 -0800 (PST) Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 2222fNNx014942; Wed, 2 Mar 2022 05:36:36 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2021-07-09; bh=ODUHLRPROk65njViGM79XADjujxgF0BeuOWTRGyNRs0=; b=XWS62EqGwrA3qMZ2NEA1HlIo+Lk/oZRDFvoEimAcCysnRCHianJ1zlDnUgg/7AFLQgsj vemL6NgyghisCSUXr+bTeh2RWIRK3U1FrKjYl5+BZwNQd0qcKYh6zRgUMBxy0jEbTbca XQ6B7De6TC0i+403sBdo4UGHooiBo1j6RewShRehBBEZW209t/Tpg300rkVmLQrqVLSt F6gWkAfq3ASDXcKXnq8Bd8x2ObCs9aO6+RpfaW4epfx7eaaqnTnnDnvKnbPbW+tVSunp 7cbEvh9uhIweGGr9zYFK6MvEX3GW7yx8wPENz4kQOakopHOWnuqQVtVISMifjY2a5A2y 5w== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by mx0b-00069f02.pphosted.com with ESMTP id 3eh15amq8w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:35 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.1.2/8.16.1.2) with SMTP id 2225Ir3K175892; Wed, 2 Mar 2022 05:36:34 GMT Received: from pps.reinject (localhost [127.0.0.1]) by aserp3020.oracle.com with ESMTP id 3efc15vams-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 02 Mar 2022 05:36:34 +0000 Received: from aserp3020.oracle.com (aserp3020.oracle.com [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 2225aRZv014395; Wed, 2 Mar 2022 05:36:34 GMT Received: from ca-mkp.mkp.ca.oracle.com (ca-mkp.ca.oracle.com [10.156.108.201]) by aserp3020.oracle.com with ESMTP id 3efc15vaeg-15; Wed, 02 Mar 2022 05:36:34 +0000 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" , Aman Karmani , David Sebek Subject: [PATCH 14/14] scsi: sd: Enable modern protocol features on more devices Date: Wed, 2 Mar 2022 00:35:59 -0500 Message-Id: <20220302053559.32147-15-martin.petersen@oracle.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220302053559.32147-1-martin.petersen@oracle.com> References: <20220302053559.32147-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 9wSIgzvaPTglyFM5p8N9O9oppH8rP3Qc X-Proofpoint-GUID: 9wSIgzvaPTglyFM5p8N9O9oppH8rP3Qc Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Due to legacy USB devices having a tendency to either lock up or return garbage if one attempts to query device capabilities, the USB transport disables VPD pages by default. This prevents discard from being properly configured on most modern USB-attached SSDs. Introduce two additional heuristics to determine whether VPD pages should be consulted. The first heuristic fetches VPD pages if a device reports that Logical Block Provisioning is enabled. It is very unusual for a device to support thin provisioning and not provide the associated VPDs. Consequently, if a device reports that Logical Block Provisioning is enabled (LBPME) in READ CAPACITY(16) response, the scsi_device has no VPDs attached, and the reported SPC version is larger than 3, then an attempt will be made to read the VPD pages during revalidate. The second heuristic relies on the fact that almost all modern devices return a set of version descriptors in the INQUIRY response. These descriptors outline which version of various protocol features are supported. If a device manufacturer has gone through the effort of filling out compliance descriptors, it is highly unlikely that VPD pages are not supported. So if a device provides version descriptors in the INQUIRY response, the scsi_device has no VPDs attached, and the reported SBC version is larger than 2, then an attempt will be made to read the VPD pages. In addition, READ CAPACITY(16) will be preferred over READ CAPACITY(10) to facilitate accessing the LBPME flag. The benefit to relying on INQUIRY is that it is data we already have. We do not have to blindly poke the device for additional information and risk confusing it. Extracting the SBC version is done by a new helper, sd_sbc_version(). Another helper is provided to determine whether a scsi_device has VPD pages attached or not. Reported-by: Aman Karmani Tested-by: Aman Karmani Reported-by: David Sebek Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Reviewed-by: Johannes Thumshirn --- drivers/scsi/scsi.c | 1 + drivers/scsi/sd.c | 77 +++++++++++++++++++++++++++++++++++++- drivers/scsi/sd.h | 2 + include/scsi/scsi_device.h | 14 +++++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 524e03aba9ef..7183fd35e48b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -497,6 +497,7 @@ void scsi_attach_vpd(struct scsi_device *sdev) } kfree(vpd_buf); } +EXPORT_SYMBOL_GPL(scsi_attach_vpd); /** * scsi_report_opcode - Find out if a given command opcode is supported diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 163697dd799a..1f7ca9446949 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2497,6 +2497,19 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, if (buffer[14] & 0x40) /* LBPRZ */ sdkp->lbprz = 1; + /* + * If a device sets LBPME=1 then it should, in theory, support + * the Logical Block Provisioning VPD page. Assume that querying + * VPD pages is safe if logical block provisioning is enabled + * and the device claims conformance to a recent version of the + * spec. + */ + if (!sdkp->reattach_vpds && !scsi_device_has_vpd(sdp) && + sdp->scsi_level > SCSI_SPC_3) { + sd_first_printk(KERN_NOTICE, sdkp, + "Logical Block Provisioning enabled, fetching VPDs\n"); + sdkp->reattach_vpds = true; + } } sdkp->capacity = lba + 1; @@ -2563,8 +2576,10 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, return sector_size; } -static int sd_try_rc16_first(struct scsi_device *sdp) +static int sd_try_rc16_first(struct scsi_disk *sdkp) { + struct scsi_device *sdp = sdkp->device; + if (sdp->host->max_cmd_len < 16) return 0; if (sdp->try_rc_10_first) @@ -2585,7 +2600,7 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) int sector_size; struct scsi_device *sdp = sdkp->device; - if (sd_try_rc16_first(sdp)) { + if (sd_try_rc16_first(sdkp)) { sector_size = read_capacity_16(sdkp, sdp, buffer); if (sector_size == -EOVERFLOW) goto got_data; @@ -3399,6 +3414,12 @@ static int sd_revalidate_disk(struct gendisk *disk) blk_queue_flag_clear(QUEUE_FLAG_NONROT, q); blk_queue_flag_set(QUEUE_FLAG_ADD_RANDOM, q); + if (sdkp->reattach_vpds) { + sdp->try_vpd_pages = 1; + scsi_attach_vpd(sdp); + sdkp->reattach_vpds = false; + } + if (scsi_device_supports_vpd(sdp)) { sd_read_block_provisioning(sdkp); sd_read_block_limits(sdkp); @@ -3543,6 +3564,42 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen) return 0; } +enum { + INQUIRY_DESC_START = 58, + INQUIRY_DESC_END = 74, + INQUIRY_DESC_SIZE = 2, +}; + +static unsigned int sd_sbc_version(struct scsi_device *sdp) +{ + unsigned int i; + unsigned int max; + + if (sdp->inquiry_len < INQUIRY_DESC_START + INQUIRY_DESC_SIZE) + return 0; + + max = min_t(unsigned int, sdp->inquiry_len, INQUIRY_DESC_END); + max = rounddown(max, INQUIRY_DESC_SIZE); + + for (i = INQUIRY_DESC_START ; i < max ; i += INQUIRY_DESC_SIZE) { + u16 desc = get_unaligned_be16(&sdp->inquiry[i]); + + switch (desc) { + case 0x0600: + return 4; + case 0x04c0: case 0x04c3: case 0x04c5: case 0x04c8: + return 3; + case 0x0320: case 0x0322: case 0x0324: case 0x033B: + case 0x033D: case 0x033E: + return 2; + case 0x0180: case 0x019b: case 0x019c: + return 1; + } + } + + return 0; +} + /** * sd_probe - called during driver initialization and whenever a * new scsi device is attached to the system. It is called once @@ -3568,6 +3625,7 @@ static int sd_probe(struct device *dev) struct gendisk *gd; int index; int error; + unsigned int sbc_version; scsi_autopm_get_device(sdp); error = -ENODEV; @@ -3656,6 +3714,21 @@ static int sd_probe(struct device *dev) sdkp->first_scan = 1; sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; + /* + * If the device explicitly claims support for SBC version 3 + * or later, unset the LLD flags which prevent probing for + * modern protocol features and reattach VPD pages. + */ + sbc_version = sd_sbc_version(sdp); + if (!scsi_device_has_vpd(sdp) && sbc_version >= 3) { + sdkp->reattach_vpds = true; + sdp->try_rc_10_first = 0; + sdp->no_read_capacity_16 = 0; + sd_first_printk(KERN_NOTICE, sdkp, + "Detected SBC version %u, fetching VPDs\n", + sbc_version); + } + sd_revalidate_disk(gd); if (sdp->removable) { diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 2cef9e884b2a..b0b39e0ea5b3 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -108,6 +108,7 @@ struct scsi_disk { unsigned int physical_block_size; unsigned int max_medium_access_timeouts; unsigned int medium_access_timed_out; + unsigned int sbc_version; u8 media_present; u8 write_prot; u8 protection_type;/* Data Integrity Field */ @@ -118,6 +119,7 @@ struct scsi_disk { bool provisioning_override; bool zeroing_override; bool ndob; + bool reattach_vpds; unsigned ATO : 1; /* state of disk ATO bit */ unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index fd6a803ac8cd..feca18e5fe28 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -605,6 +605,20 @@ static inline int scsi_device_supports_vpd(struct scsi_device *sdev) return 0; } +static inline bool scsi_device_has_vpd(struct scsi_device *sdev) +{ + struct scsi_vpd *vpd; + bool found = false; + + rcu_read_lock(); + vpd = rcu_dereference(sdev->vpd_pg0); + if (vpd) + found = true; + rcu_read_unlock(); + + return found; +} + static inline int scsi_device_busy(struct scsi_device *sdev) { return sbitmap_weight(&sdev->budget_map);