From patchwork Mon Aug 6 04:51:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Douglas Gilbert X-Patchwork-Id: 10556475 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 AB2C4174A for ; Mon, 6 Aug 2018 04:51:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99AB328FFE for ; Mon, 6 Aug 2018 04:51:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8DD7629006; Mon, 6 Aug 2018 04:51:27 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 237722902D for ; Mon, 6 Aug 2018 04:51:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726823AbeHFG6m (ORCPT ); Mon, 6 Aug 2018 02:58:42 -0400 Received: from smtp.infotech.no ([82.134.31.41]:35010 "EHLO smtp.infotech.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726449AbeHFG6m (ORCPT ); Mon, 6 Aug 2018 02:58:42 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp.infotech.no (Postfix) with ESMTP id 53A49204255; Mon, 6 Aug 2018 06:51:24 +0200 (CEST) X-Virus-Scanned: by amavisd-new-2.6.6 (20110518) (Debian) at infotech.no Received: from smtp.infotech.no ([127.0.0.1]) by localhost (smtp.infotech.no [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lqRsb4huARiP; Mon, 6 Aug 2018 06:51:22 +0200 (CEST) Received: from xtwo70.bingwo.ca (host-45-58-245-67.dyn.295.ca [45.58.245.67]) by smtp.infotech.no (Postfix) with ESMTPA id 02AC220423F; Mon, 6 Aug 2018 06:51:20 +0200 (CEST) From: Douglas Gilbert To: linux-scsi@vger.kernel.org Cc: martin.petersen@oracle.com, hare@suse.de, bart.vanassche@wdc.com, jthumshirn@suse.de Subject: [RFC PATCH 2/5] break sd_done sense processing out to own function Date: Mon, 6 Aug 2018 00:51:12 -0400 Message-Id: <20180806045115.7725-3-dgilbert@interlog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180806045115.7725-1-dgilbert@interlog.com> References: <20180806045115.7725-1-dgilbert@interlog.com> 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 Break out the sense key handling in the sd_done() (response) path into its own function. Note that the sense key only needs to be inspected when a SCSI status of Check Condition is returned. Signed-off-by: Douglas Gilbert --- No speed up here, just a clean up. There could possibly be a speed improvement (not observed in tests) from lessening the cache footprint of the sd_done() function which is on the fast path. drivers/scsi/sd.c | 112 ++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b17b8c66881d..4b1402633c36 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1898,6 +1898,62 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) return min(good_bytes, transferred); } +/* Helper for scsi_done() when there is a sense buffer */ +static int sd_done_sense(struct scsi_cmnd *SCpnt, unsigned int good_bytes, + struct scsi_sense_hdr *sshdrp) +{ + struct request *req = SCpnt->request; + struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); + + switch (sshdrp->sense_key) { + case HARDWARE_ERROR: + case MEDIUM_ERROR: + return sd_completed_bytes(SCpnt); + case RECOVERED_ERROR: + return scsi_bufflen(SCpnt); + case NO_SENSE: + /* This indicates a false check condition, so ignore it. An + * unknown amount of data was transferred so treat it as an + * error. + */ + SCpnt->result = 0; + memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + break; + case ABORTED_COMMAND: + if (sshdrp->asc == 0x10) /* DIF: Target detected corruption */ + good_bytes = sd_completed_bytes(SCpnt); + break; + case ILLEGAL_REQUEST: + switch (sshdrp->asc) { + case 0x10: /* DIX: Host detected corruption */ + good_bytes = sd_completed_bytes(SCpnt); + break; + case 0x20: /* INVALID COMMAND OPCODE */ + case 0x24: /* INVALID FIELD IN CDB */ + switch (SCpnt->cmnd[0]) { + case UNMAP: + sd_config_discard(sdkp, SD_LBP_DISABLE); + break; + case WRITE_SAME_16: + case WRITE_SAME: + if (SCpnt->cmnd[1] & 8) { /* UNMAP */ + sd_config_discard(sdkp, SD_LBP_DISABLE); + } else { + sdkp->device->no_write_same = 1; + sd_config_write_same(sdkp); + req->__data_len = blk_rq_bytes(req); + req->rq_flags |= RQF_QUIET; + } + break; + } + } + break; + default: + break; + } + return good_bytes; +} + /** * sd_done - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. @@ -1964,60 +2020,10 @@ static int sd_done(struct scsi_cmnd *SCpnt) } sdkp->medium_access_timed_out = 0; - if (driver_byte(result) != DRIVER_SENSE && - (!sense_valid || sense_deferred)) - goto out; + if (unlikely(driver_byte(result) == DRIVER_SENSE || + (sense_valid && !sense_deferred))) + good_bytes = sd_done_sense(SCpnt, good_bytes, &sshdr); - switch (sshdr.sense_key) { - case HARDWARE_ERROR: - case MEDIUM_ERROR: - good_bytes = sd_completed_bytes(SCpnt); - break; - case RECOVERED_ERROR: - good_bytes = scsi_bufflen(SCpnt); - break; - case NO_SENSE: - /* This indicates a false check condition, so ignore it. An - * unknown amount of data was transferred so treat it as an - * error. - */ - SCpnt->result = 0; - memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - break; - case ABORTED_COMMAND: - if (sshdr.asc == 0x10) /* DIF: Target detected corruption */ - good_bytes = sd_completed_bytes(SCpnt); - break; - case ILLEGAL_REQUEST: - switch (sshdr.asc) { - case 0x10: /* DIX: Host detected corruption */ - good_bytes = sd_completed_bytes(SCpnt); - break; - case 0x20: /* INVALID COMMAND OPCODE */ - case 0x24: /* INVALID FIELD IN CDB */ - switch (SCpnt->cmnd[0]) { - case UNMAP: - sd_config_discard(sdkp, SD_LBP_DISABLE); - break; - case WRITE_SAME_16: - case WRITE_SAME: - if (SCpnt->cmnd[1] & 8) { /* UNMAP */ - sd_config_discard(sdkp, SD_LBP_DISABLE); - } else { - sdkp->device->no_write_same = 1; - sd_config_write_same(sdkp); - req->__data_len = blk_rq_bytes(req); - req->rq_flags |= RQF_QUIET; - } - break; - } - } - break; - default: - break; - } - - out: if (sd_is_zoned(sdkp)) sd_zbc_complete(SCpnt, good_bytes, &sshdr);