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;