From patchwork Thu Feb 28 03:57:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 10832521 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4DB531805 for ; Thu, 28 Feb 2019 03:58:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4008C2E231 for ; Thu, 28 Feb 2019 03:58:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3366D2E41A; Thu, 28 Feb 2019 03:58:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 48C662E28C for ; Thu, 28 Feb 2019 03:58:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730509AbfB1D6I (ORCPT ); Wed, 27 Feb 2019 22:58:08 -0500 Received: from aserp2130.oracle.com ([141.146.126.79]:49086 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730410AbfB1D6I (ORCPT ); Wed, 27 Feb 2019 22:58:08 -0500 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x1S3moUf178406 for ; Thu, 28 Feb 2019 03:58:07 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-2018-07-02; bh=Dka2BBagV2cxQ+J1o/k1LVG6/lpR/lSFPM4dFpVkics=; b=NpCM7AyykeF5Ll4eFckfyOi6lZqU0ivXMvlcQVmWOCnl7h8JlovUKVGzpOM7xTaca8yX NLFCCdSkZVEzq3a74AYZgFdoOm5Of6Lw/C9wf0Esl4qocbIUGduSsLOZsToFb0EIpBzj 4qBI+WYSj/kxZ/r68p7E3KGYuhXaUamKteR6VUXjVixsLKCa+dr9kPbOiayYYM/nbI4d xyK9DPTyuR01Q67zm7ytwLYhpq//s6ecBEDnWlVzXNlARXSwqja1SXGKCt3RWvRvSorX ColrU23Ydg5uHALX32QUlbKCQqVkCCCD0+uBwtHBYgRG4XjOcP36+6Yp+soyiMHZsTnN JQ== Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp2130.oracle.com with ESMTP id 2qtupeesux-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 28 Feb 2019 03:58:06 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.14.4/8.14.4) with ESMTP id x1S3w6lL010876 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 28 Feb 2019 03:58:06 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x1S3w5vY023859 for ; Thu, 28 Feb 2019 03:58:06 GMT Received: from ca-mkp.ca.oracle.com (/10.156.108.201) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 27 Feb 2019 19:57:44 -0800 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 1/2] scsi: sd: Use revalidate buffer for VPD pages Date: Wed, 27 Feb 2019 22:57:32 -0500 Message-Id: <20190228035733.19793-2-martin.petersen@oracle.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190228035733.19793-1-martin.petersen@oracle.com> References: <9f00159eacd346bbbc2aeb1708f6831f@mail.gmail.com> <20190228035733.19793-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9180 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1902280024 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP No point in allocating separate memory for the VPD pages we're querying. Use the buffer we already allocated. Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi.c | 1 + drivers/scsi/sd.c | 48 ++++++++++++++------------------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7675ff0ca2ea..1d58e466722f 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -341,6 +341,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, cmd[3] = len >> 8; cmd[4] = len & 0xff; cmd[5] = 0; /* Control byte */ + memset(buffer, 0x0, len); /* * I'm not convinced we need to try quite this hard to get VPD, but diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index cc175b78b366..df9538e57dcb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2879,16 +2879,14 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) * sd_read_block_limits - Query disk device for preferred I/O sizes. * @sdkp: disk to query */ -static void sd_read_block_limits(struct scsi_disk *sdkp) +static void sd_read_block_limits(struct scsi_disk *sdkp, unsigned char *buffer) { unsigned int sector_sz = sdkp->device->sector_size; const int vpd_len = 64; - unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); - if (!buffer || - /* Block Limits VPD */ - scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len)) - goto out; + /* Block Limits VPD */ + if (scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len)) + return; blk_queue_io_min(sdkp->disk->queue, get_unaligned_be16(&buffer[6]) * sector_sz); @@ -2902,7 +2900,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); if (!sdkp->lbpme) - goto out; + return; lba_count = get_unaligned_be32(&buffer[20]); desc_count = get_unaligned_be32(&buffer[24]); @@ -2934,28 +2932,21 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) sd_config_discard(sdkp, SD_LBP_DISABLE); } } - - out: - kfree(buffer); } /** * sd_read_block_characteristics - Query block dev. characteristics * @sdkp: disk to query */ -static void sd_read_block_characteristics(struct scsi_disk *sdkp) +static void sd_read_block_characteristics(struct scsi_disk *sdkp, unsigned char *buffer) { struct request_queue *q = sdkp->disk->queue; - unsigned char *buffer; u16 rot; const int vpd_len = 64; - buffer = kmalloc(vpd_len, GFP_KERNEL); - - if (!buffer || - /* Block Device Characteristics VPD */ - scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len)) - goto out; + /* Block Device Characteristics VPD */ + if (scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len)) + return; rot = get_unaligned_be16(&buffer[4]); @@ -2985,35 +2976,26 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) if (blk_queue_is_zoned(q) && sdkp->first_scan) sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n", q->limits.zoned == BLK_ZONED_HM ? "managed" : "aware"); - - out: - kfree(buffer); } /** * sd_read_block_provisioning - Query provisioning VPD page * @sdkp: disk to query */ -static void sd_read_block_provisioning(struct scsi_disk *sdkp) +static void sd_read_block_provisioning(struct scsi_disk *sdkp, unsigned char *buffer) { - unsigned char *buffer; const int vpd_len = 8; if (sdkp->lbpme == 0) return; - buffer = kmalloc(vpd_len, GFP_KERNEL); - - if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) - goto out; + if (scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len)) + 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); } static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) @@ -3102,9 +3084,9 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_capacity(sdkp, buffer); if (scsi_device_supports_vpd(sdp)) { - sd_read_block_provisioning(sdkp); - sd_read_block_limits(sdkp); - sd_read_block_characteristics(sdkp); + sd_read_block_provisioning(sdkp, buffer); + sd_read_block_limits(sdkp, buffer); + sd_read_block_characteristics(sdkp, buffer); sd_zbc_read_zones(sdkp, buffer); } From patchwork Thu Feb 28 03:57:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Martin K. Petersen" X-Patchwork-Id: 10832519 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C479C1399 for ; Thu, 28 Feb 2019 03:58:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B624F2E231 for ; Thu, 28 Feb 2019 03:58:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AA39C2E25C; Thu, 28 Feb 2019 03:58:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F20C2E2B6 for ; Thu, 28 Feb 2019 03:58:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730499AbfB1D6I (ORCPT ); Wed, 27 Feb 2019 22:58:08 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:34690 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730131AbfB1D6I (ORCPT ); Wed, 27 Feb 2019 22:58:08 -0500 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x1S3nUlD179774 for ; Thu, 28 Feb 2019 03:58:06 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-2018-07-02; bh=7Pc1aQljHcjyqH347InP1g02Qkmus8vkRLBxjlz4xyM=; b=4TLbQBKnqqNHXePmRS9H0PpD9ybCRxUmGsh6kEIPJgglZvHlhnp8ucWq/i48R2FP0pTv qSeJxSOrsyeqFzTm9ZPOpK5cfmF0ibKVr9X8yw6Jxwe7m+ojmL6ApMbad4dtXy6S0Qno bA5PdZt7Dt8RbDETA858iVg4KiSdkdFIl6jxnO98DS/XwEEUa0ikvIxvJCTffagr5klD uoiykj3p/prkGSkKUQoQJSiKpRWHZfWgJhYXQ69Tsnmdpugx1eu5Mi56v60XD/2i5wAh vvrXXddIuh3FvMs3G/KxBbd0oc81aO1Fw4hjvQd4/uiv/v5CasVJExoNjRL8GM90oSgR CQ== Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp2130.oracle.com with ESMTP id 2qtwkuemf8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 28 Feb 2019 03:58:06 +0000 Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id x1S3w5xW020813 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 28 Feb 2019 03:58:05 GMT Received: from abhmp0022.oracle.com (abhmp0022.oracle.com [141.146.116.28]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x1S3w5Fh018439 for ; Thu, 28 Feb 2019 03:58:05 GMT Received: from ca-mkp.ca.oracle.com (/10.156.108.201) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 27 Feb 2019 19:57:44 -0800 From: "Martin K. Petersen" To: linux-scsi@vger.kernel.org Cc: "Martin K. Petersen" Subject: [PATCH 2/2] scsi: sd: Implement support for NDOB flag in WRITE SAME(16) Date: Wed, 27 Feb 2019 22:57:33 -0500 Message-Id: <20190228035733.19793-3-martin.petersen@oracle.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190228035733.19793-1-martin.petersen@oracle.com> References: <9f00159eacd346bbbc2aeb1708f6831f@mail.gmail.com> <20190228035733.19793-1-martin.petersen@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9180 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1902280024 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The NDOB flag removes the need for a zeroed logical block in the data-out buffer when using WRITE SAME(16) to UNMAP block ranges. Implement support for NDOB in sd.c. 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) and UNMAP is requested, we check whether NDOB is set for the device in question. And if so, we do not allocate a zeroed page from the pool and simply issue the command a zero-length payload. Whether a device reports support for the NDOB bit is exposed in the sysfs ndob file. Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 53 +++++++++++++++++++++++++++++++++++++++-------- drivers/scsi/sd.h | 1 + 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index df9538e57dcb..c75b8c1b114e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -370,6 +370,15 @@ thin_provisioning_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(thin_provisioning); +static ssize_t +ndob_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return sprintf(buf, "%u\n", sdkp->ndob); +} +static DEVICE_ATTR_RO(ndob); + /* sysfs_match_string() requires dense arrays */ static const char *lbp_mode[] = { [SD_LBP_FULL] = "full", @@ -533,6 +542,7 @@ static struct attribute *sd_disk_attrs[] = { &dev_attr_app_tag_own.attr, &dev_attr_thin_provisioning.attr, &dev_attr_provisioning_mode.attr, + &dev_attr_ndob.attr, &dev_attr_zeroing_mode.attr, &dev_attr_max_write_same_blocks.attr, &dev_attr_max_medium_access_timeouts.attr, @@ -852,27 +862,38 @@ static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, { struct scsi_device *sdp = cmd->device; struct request *rq = cmd->request; + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); 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); + if (unmap && sdkp->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->special_vec.bv_offset = 0; - rq->special_vec.bv_len = data_len; rq->rq_flags |= RQF_SPECIAL_PAYLOAD; cmd->cmd_len = 16; cmd->cmnd[0] = WRITE_SAME_16; - if (unmap) + if (unmap) { cmd->cmnd[1] = 0x8; /* UNMAP */ + if (sdkp->ndob) + cmd->cmnd[1] |= 0x1; /* NDOB */ + } put_unaligned_be64(lba, &cmd->cmnd[2]); put_unaligned_be32(nr_blocks, &cmd->cmnd[10]); cmd->allowed = SD_MAX_RETRIES; - cmd->transfersize = data_len; + cmd->transfersize = rq->special_vec.bv_len; rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT; return scsi_init_io(cmd); @@ -1297,7 +1318,7 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt) struct request *rq = SCpnt->request; u8 *cmnd; - if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) + if (rq->rq_flags & RQF_SPECIAL_PAYLOAD && SCpnt->transfersize) mempool_free(rq->special_vec.bv_page, sd_page_pool); if (SCpnt->cmnd != scsi_req(rq)->cmd) { @@ -2984,7 +3005,9 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp, unsigned char */ static void sd_read_block_provisioning(struct scsi_disk *sdkp, unsigned char *buffer) { - const int vpd_len = 8; + struct scsi_device *sdev = sdkp->device; + const unsigned int vpd_len = 8; + const unsigned int rsoc_len = 20; if (sdkp->lbpme == 0) return; @@ -2996,6 +3019,18 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp, unsigned char *bu 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 */ + + if (!sdkp->lbpws) + return; + /* + * We assume that if a device supports the Block Provisioning + * VPD page, it is smart enough to implement Report Supported + * Operation Codes. We use that operation to determine whether + * the NDOB bit is supported for WRITE SAME(16). + */ + if (scsi_report_opcode(sdev, buffer, rsoc_len, WRITE_SAME_16) == 1 && + get_unaligned_be16(&buffer[2]) >= 2) + sdkp->ndob = buffer[5] & 1; } static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 5796ace76225..fda6ad03e02d 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -111,6 +111,7 @@ struct scsi_disk { unsigned lbpvpd : 1; unsigned ws10 : 1; unsigned ws16 : 1; + unsigned ndob : 1; unsigned rc_basis: 2; unsigned zoned: 2; unsigned urswrz : 1;