From patchwork Mon Nov 16 03:04:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 324979 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60427C6379D for ; Mon, 16 Nov 2020 03:05:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 29F8A22384 for ; Mon, 16 Nov 2020 03:05:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726739AbgKPDFN (ORCPT ); Sun, 15 Nov 2020 22:05:13 -0500 Received: from mail-pg1-f193.google.com ([209.85.215.193]:39845 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726692AbgKPDFM (ORCPT ); Sun, 15 Nov 2020 22:05:12 -0500 Received: by mail-pg1-f193.google.com with SMTP id p68so1415628pga.6; Sun, 15 Nov 2020 19:05:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WBxpkiMjxwD+IRn41vyX5xWhB8DClldowR9a4K9oHbk=; b=eLDl1MlWT7z6cIUDS9CGNoiT1v1sWg2OTnrpBI+lZ40MRfdqBWuH9p+yK8PF4GSTfT 1fnRqU54g2vXBCr9oAr1TWZ5+iBpfPcgPMLxFJRfA6R99ggGVwAgzYLxekSWoiaiX9jQ HOjR/kC80qVILba9RYCUAgaDbjV8yxLGw60d+J8xRtLR7eYqTd+YbNfcm4s8w0q7q6sc e2g9YMTinQLB52s8EDJjLC/HOQ92CM/wBUxM4Ync9oTafJbl6yMryXGuCIw6boVBzR/c Phz5pKODuXuExstUrGTb65HkbSoo2ytRnQO8GIbiOW+IWFydUzJytO6qejoz+tjv8o9b JtCw== X-Gm-Message-State: AOAM530KHhk3cG6KwVm0/iLoZoFWpOFiwYchFvCOjFoEUEQjxBRJTg+z gDyFZb3mpdQhyvLJdL6WuDw= X-Google-Smtp-Source: ABdhPJxhg5qQ69TckhvT+TZCfSAVkm0WCWj/uHzz6NuQWHDL7LjRtj7uWuM0emzFQO92Ds8oA93zkw== X-Received: by 2002:a63:540c:: with SMTP id i12mr11677491pgb.32.1605495911820; Sun, 15 Nov 2020 19:05:11 -0800 (PST) Received: from asus.hsd1.ca.comcast.net (c-73-241-217-19.hsd1.ca.comcast.net. [73.241.217.19]) by smtp.gmail.com with ESMTPSA id r3sm17148131pjl.23.2020.11.15.19.05.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Nov 2020 19:05:10 -0800 (PST) From: Bart Van Assche To: "Martin K . Petersen" Cc: "James E . J . Bottomley" , Jens Axboe , Christoph Hellwig , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, Bart Van Assche , "David S . Miller" , Alan Stern , Can Guo , Stanley Chu , Ming Lei , "Rafael J . Wysocki" Subject: [PATCH v2 2/9] ide: Do not set the RQF_PREEMPT flag for sense requests Date: Sun, 15 Nov 2020 19:04:52 -0800 Message-Id: <20201116030459.13963-3-bvanassche@acm.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201116030459.13963-1-bvanassche@acm.org> References: <20201116030459.13963-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org RQF_PREEMPT is used for two different purposes in the legacy IDE code: 1. To mark power management requests. 2. To mark requests that should preempt another request. An (old) explanation of that feature is as follows: "The IDE driver in the Linux kernel normally uses a series of busywait delays during its initialization. When the driver executes these busywaits, the kernel does nothing for the duration of the wait. The time spent in these waits could be used for other initialization activities, if they could be run concurrently with these waits. More specifically, busywait-style delays such as udelay() in module init functions inhibit kernel preemption because the Big Kernel Lock is held, while yielding APIs such as schedule_timeout() allow preemption. This is true because the kernel handles the BKL specially and releases and reacquires it across reschedules allowed by the current thread. This IDE-preempt specification requires that the driver eliminate these busywaits and replace them with a mechanism that allows other work to proceed while the IDE driver is initializing." Since I haven't found an implementation of (2), do not set the PREEMPT flag for sense requests. This patch causes sense requests to be postponed while a drive is suspended instead of being submitted to ide_queue_rq(). If it would ever be necessary to restore the IDE PREEMPT functionality, that can be done by introducing a new flag in struct ide_request. This patch is a first step towards removing the PREEMPT flag from the block layer. Cc: David S. Miller Cc: Alan Stern Cc: Can Guo Cc: Stanley Chu Cc: Ming Lei Cc: Rafael J. Wysocki Signed-off-by: Bart Van Assche --- drivers/ide/ide-atapi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2162bc80f09e..013ad33fbbc8 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -223,7 +223,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) sense_rq->rq_disk = rq->rq_disk; sense_rq->cmd_flags = REQ_OP_DRV_IN; ide_req(sense_rq)->type = ATA_PRIV_SENSE; - sense_rq->rq_flags |= RQF_PREEMPT; req->cmd[0] = GPCMD_REQUEST_SENSE; req->cmd[4] = cmd_len; From patchwork Mon Nov 16 03:04:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 324978 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A35CDC63699 for ; Mon, 16 Nov 2020 03:05:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 715BB22284 for ; Mon, 16 Nov 2020 03:05:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726742AbgKPDFP (ORCPT ); Sun, 15 Nov 2020 22:05:15 -0500 Received: from mail-pl1-f193.google.com ([209.85.214.193]:33747 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726692AbgKPDFO (ORCPT ); Sun, 15 Nov 2020 22:05:14 -0500 Received: by mail-pl1-f193.google.com with SMTP id t18so7684258plo.0; Sun, 15 Nov 2020 19:05:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mZIHmdfI6VuvHQbFk9elE6LcTPI0DIedaaHe1HmoEWQ=; b=aVfDMxUSJl3Ye3FqLMgBVE00iYf71oJGEXA0siXjzihcfpTHXrDrFj/1cDONE3X6+Y pt1FRmsFWCNbZoAisjkh8FS9xBN5cJe1s0T4gGxismfrOogMydQXKxh2gXRK/mXImR4y BqygnR5PDQYT7Qj3HbkVZ+4DoRza+mtvWLcbeOWV2iV655kpI4U7nysDmjdV1AtIdx7O eAshjCAOQPwPzQNxeOJ/xoFJURWnid7wPLyyWZmcbcr8gCy6oOladNe1GXQqPdKWJqN7 qCx48RkNqu93Ldr3QK+xXw+PGedBkjsbg4r7qbdphgJo7SgQTuy2TBB5fz/RpaHM+8ss Ct6w== X-Gm-Message-State: AOAM531KYi99i1a1hCil0Ni3AUrB/fFHuhEJrgbG7Qfc1tLtU+uYE8Ak 7p1gL1IQ9cMj1yb9TVl1VlQmW9KxSBw= X-Google-Smtp-Source: ABdhPJx/6VW6L7Lds24w5+sY39CJEbCX/iKl6RazpeIUgulPPS7RPBD5bhsbOyWRCgGGqTH1ubNGxg== X-Received: by 2002:a17:902:8206:b029:d8:de70:7f7a with SMTP id x6-20020a1709028206b02900d8de707f7amr8537425pln.39.1605495913828; Sun, 15 Nov 2020 19:05:13 -0800 (PST) Received: from asus.hsd1.ca.comcast.net (c-73-241-217-19.hsd1.ca.comcast.net. [73.241.217.19]) by smtp.gmail.com with ESMTPSA id r3sm17148131pjl.23.2020.11.15.19.05.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Nov 2020 19:05:13 -0800 (PST) From: Bart Van Assche To: "Martin K . Petersen" Cc: "James E . J . Bottomley" , Jens Axboe , Christoph Hellwig , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, Bart Van Assche , Alan Stern , Can Guo , Stanley Chu , Ming Lei , "Rafael J . Wysocki" Subject: [PATCH v2 3/9] scsi: Pass a request queue pointer to __scsi_execute() Date: Sun, 15 Nov 2020 19:04:53 -0800 Message-Id: <20201116030459.13963-4-bvanassche@acm.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201116030459.13963-1-bvanassche@acm.org> References: <20201116030459.13963-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org This patch does not change any functionality but makes a later patch easier to read. Cc: Martin K. Petersen Reviewed-by: Alan Stern Cc: Can Guo Cc: Stanley Chu Cc: Ming Lei Cc: Rafael J. Wysocki Signed-off-by: Bart Van Assche Reviewed-by: Can Guo --- drivers/scsi/scsi_lib.c | 12 +++++------- include/scsi/scsi_device.h | 8 ++++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 855e48c7514f..e4f9ed355be6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -221,7 +221,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) /** * __scsi_execute - insert request and wait for the result - * @sdev: scsi device + * @q: queue to insert the request into * @cmd: scsi command * @data_direction: data direction * @buffer: data buffer @@ -237,7 +237,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) * Returns the scsi_cmnd result field if a command was executed, or a negative * Linux error code if we didn't get that far. */ -int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, +int __scsi_execute(struct request_queue *q, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, unsigned char *sense, struct scsi_sense_hdr *sshdr, int timeout, int retries, u64 flags, req_flags_t rq_flags, @@ -247,15 +247,13 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, struct scsi_request *rq; int ret = DRIVER_ERROR << 24; - req = blk_get_request(sdev->request_queue, - data_direction == DMA_TO_DEVICE ? + req = blk_get_request(q, data_direction == DMA_TO_DEVICE ? REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, BLK_MQ_REQ_PREEMPT); if (IS_ERR(req)) return ret; rq = scsi_req(req); - if (bufflen && blk_rq_map_kern(sdev->request_queue, req, - buffer, bufflen, GFP_NOIO)) + if (bufflen && blk_rq_map_kern(q, req, buffer, bufflen, GFP_NOIO)) goto out; rq->cmd_len = COMMAND_SIZE(cmd[0]); @@ -268,7 +266,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, /* * head injection *required* here otherwise quiesce won't work */ - blk_execute_rq(req->q, NULL, req, 1); + blk_execute_rq(q, NULL, req, 1); /* * Some devices (USB mass-storage in particular) may transfer diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 1a5c9a3df6d6..f47fdf9cf788 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -438,7 +438,7 @@ extern const char *scsi_device_state_name(enum scsi_device_state); extern int scsi_is_sdev_device(const struct device *); extern int scsi_is_target_device(const struct device *); extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); -extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, +extern int __scsi_execute(struct request_queue *q, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, unsigned char *sense, struct scsi_sense_hdr *sshdr, int timeout, int retries, u64 flags, @@ -449,9 +449,9 @@ extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, ({ \ BUILD_BUG_ON((sense) != NULL && \ sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \ - __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \ - sense, sshdr, timeout, retries, flags, rq_flags, \ - resid); \ + __scsi_execute(sdev->request_queue, cmd, data_direction, \ + buffer, bufflen, sense, sshdr, timeout, retries, \ + flags, rq_flags, resid); \ }) static inline int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, From patchwork Mon Nov 16 03:04:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 324977 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4131FC64E7D for ; Mon, 16 Nov 2020 03:05:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 20BC122263 for ; Mon, 16 Nov 2020 03:05:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726756AbgKPDFV (ORCPT ); Sun, 15 Nov 2020 22:05:21 -0500 Received: from mail-pg1-f195.google.com ([209.85.215.195]:33800 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726743AbgKPDFU (ORCPT ); Sun, 15 Nov 2020 22:05:20 -0500 Received: by mail-pg1-f195.google.com with SMTP id q28so1364778pgk.1; Sun, 15 Nov 2020 19:05:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4lL6vtFKiVUNQedwWNXwimQfa6IpxlhzDyO01IkoXtQ=; b=sFXqY5iGcxh9h7NiH17Lv4fYKx47scGlWeaqh0AGUtp+yvN2AH18RFodh6F7AB/ECl l2KqLZ3fp62s9nQwPInXxe54SGKF9vccQ+8OG3oT59v5mnlD8OaVewOSf0KMzaLQiiF8 jstsHrXhGQ9XB7/d7HjHWvTO+LkdZJcjSkQaajwq+g6hfSS/f69gkCNes9SOsCcK5lTr 3qaAp7SdL9nQ+utT3eyqBprIQZHHRyBxaFCltsNbZ8FMZmQOS2KHQfo4ZspF+MpMr48+ Uq/OquDW8FsqFc0JIsghIuXT4NGSoEeAptJ3bRxz1PBWO+r9oRKCU8QRQ+Oy7Rmzn81S 1pJw== X-Gm-Message-State: AOAM531xUgqstGRHtHOVYYrEYh7TtM9TZ546uivpz/tyjJGYnOdWZ/k9 rC2qE2VqTZjq9iN6INFQdzQ= X-Google-Smtp-Source: ABdhPJzR5LHhVDMBi15Etvxgh73jkFXouF4onROJgxReI2DBslVdt2X9K1NO1aipoownq1M1NDT/mw== X-Received: by 2002:a63:486:: with SMTP id 128mr10746685pge.200.1605495919864; Sun, 15 Nov 2020 19:05:19 -0800 (PST) Received: from asus.hsd1.ca.comcast.net (c-73-241-217-19.hsd1.ca.comcast.net. [73.241.217.19]) by smtp.gmail.com with ESMTPSA id r3sm17148131pjl.23.2020.11.15.19.05.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Nov 2020 19:05:19 -0800 (PST) From: Bart Van Assche To: "Martin K . Petersen" Cc: "James E . J . Bottomley" , Jens Axboe , Christoph Hellwig , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, Bart Van Assche , James Bottomley , Woody Suwalski , Alan Stern , Can Guo , Stanley Chu , Ming Lei , "Rafael J . Wysocki" , Stan Johnson Subject: [PATCH v2 6/9] scsi_transport_spi: Make spi_execute() accept a request queue pointer Date: Sun, 15 Nov 2020 19:04:56 -0800 Message-Id: <20201116030459.13963-7-bvanassche@acm.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201116030459.13963-1-bvanassche@acm.org> References: <20201116030459.13963-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Passing a request queue pointer to spi_execute() instead of a SCSI device pointer will allow a later patch to associate two request queues with a SCSI device. Additionally, instead of assuming that the device state is SDEV_QUIESCE before domain validation starts, read the device state. This patch does not change any functionality but makes a later patch easier to read. Cc: James Bottomley Cc: Martin K. Petersen Cc: Woody Suwalski Reviewed-by: Alan Stern Cc: Can Guo Cc: Stanley Chu Cc: Ming Lei Cc: Rafael J. Wysocki Tested-by: Stan Johnson Signed-off-by: Bart Van Assche --- drivers/scsi/scsi_transport_spi.c | 69 ++++++++++++++++--------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index f3d5b1bbd5aa..959990f66865 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -104,7 +104,7 @@ static int sprint_frac(char *dest, int value, int denom) return result; } -static int spi_execute(struct scsi_device *sdev, const void *cmd, +static int spi_execute(struct request_queue *q, const void *cmd, enum dma_data_direction dir, void *buffer, unsigned bufflen, struct scsi_sense_hdr *sshdr) @@ -117,7 +117,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, sshdr = &sshdr_tmp; for(i = 0; i < DV_RETRIES; i++) { - result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, + result = __scsi_execute(q, cmd, dir, buffer, bufflen, sense, sshdr, DV_TIMEOUT, /* retries */ 1, REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | @@ -620,13 +620,14 @@ enum spi_compare_returns { /* This is for read/write Domain Validation: If the device supports * an echo buffer, we do read/write tests to it */ static enum spi_compare_returns -spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, - u8 *ptr, const int retries) +spi_dv_device_echo_buffer(struct scsi_device *sdev, struct request_queue *q, + u8 *buffer, u8 *ptr, const int retries) { int len = ptr - buffer; int j, k, r, result; unsigned int pattern = 0x0000ffff; struct scsi_sense_hdr sshdr; + enum scsi_device_state sdev_state = sdev->sdev_state; const char spi_write_buffer[] = { WRITE_BUFFER, 0x0a, 0, 0, 0, 0, 0, len >> 8, len & 0xff, 0 @@ -671,11 +672,10 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, } for (r = 0; r < retries; r++) { - result = spi_execute(sdev, spi_write_buffer, DMA_TO_DEVICE, + result = spi_execute(q, spi_write_buffer, DMA_TO_DEVICE, buffer, len, &sshdr); if(result || !scsi_device_online(sdev)) { - - scsi_device_set_state(sdev, SDEV_QUIESCE); + scsi_device_set_state(sdev, sdev_state); if (scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST /* INVALID FIELD IN CDB */ @@ -693,9 +693,9 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, } memset(ptr, 0, len); - spi_execute(sdev, spi_read_buffer, DMA_FROM_DEVICE, - ptr, len, NULL); - scsi_device_set_state(sdev, SDEV_QUIESCE); + spi_execute(q, spi_read_buffer, DMA_FROM_DEVICE, ptr, len, + NULL); + scsi_device_set_state(sdev, sdev_state); if (memcmp(buffer, ptr, len) != 0) return SPI_COMPARE_FAILURE; @@ -706,11 +706,12 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, /* This is for the simplest form of Domain Validation: a read test * on the inquiry data from the device */ static enum spi_compare_returns -spi_dv_device_compare_inquiry(struct scsi_device *sdev, u8 *buffer, - u8 *ptr, const int retries) +spi_dv_device_compare_inquiry(struct scsi_device *sdev, struct request_queue *q, + u8 *buffer, u8 *ptr, const int retries) { int r, result; const int len = sdev->inquiry_len; + enum scsi_device_state sdev_state = sdev->sdev_state; const char spi_inquiry[] = { INQUIRY, 0, 0, 0, len, 0 }; @@ -718,11 +719,11 @@ spi_dv_device_compare_inquiry(struct scsi_device *sdev, u8 *buffer, for (r = 0; r < retries; r++) { memset(ptr, 0, len); - result = spi_execute(sdev, spi_inquiry, DMA_FROM_DEVICE, - ptr, len, NULL); + result = spi_execute(q, spi_inquiry, DMA_FROM_DEVICE, ptr, len, + NULL); if(result || !scsi_device_online(sdev)) { - scsi_device_set_state(sdev, SDEV_QUIESCE); + scsi_device_set_state(sdev, sdev_state); return SPI_COMPARE_FAILURE; } @@ -742,9 +743,10 @@ spi_dv_device_compare_inquiry(struct scsi_device *sdev, u8 *buffer, } static enum spi_compare_returns -spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr, - enum spi_compare_returns - (*compare_fn)(struct scsi_device *, u8 *, u8 *, int)) +spi_dv_retrain(struct scsi_device *sdev, struct request_queue *q, u8 *buffer, + u8 *ptr, enum spi_compare_returns + (*compare_fn)(struct scsi_device *, struct request_queue *, + u8 *, u8 *, int)) { struct spi_internal *i = to_spi_internal(sdev->host->transportt); struct scsi_target *starget = sdev->sdev_target; @@ -754,7 +756,7 @@ spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr, for (;;) { int newperiod; - retval = compare_fn(sdev, buffer, ptr, DV_LOOPS); + retval = compare_fn(sdev, q, buffer, ptr, DV_LOOPS); if (retval == SPI_COMPARE_SUCCESS || retval == SPI_COMPARE_SKIP_TEST) @@ -800,7 +802,8 @@ spi_dv_retrain(struct scsi_device *sdev, u8 *buffer, u8 *ptr, } static int -spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer) +spi_dv_device_get_echo_buffer(struct scsi_device *sdev, + struct request_queue *q, u8 *buffer) { int l, result; @@ -824,8 +827,8 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer) * (reservation conflict, device not ready, etc) just * skip the write tests */ for (l = 0; ; l++) { - result = spi_execute(sdev, spi_test_unit_ready, DMA_NONE, - NULL, 0, NULL); + result = spi_execute(q, spi_test_unit_ready, DMA_NONE, NULL, 0, + NULL); if(result) { if(l >= 3) @@ -836,8 +839,8 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer) } } - result = spi_execute(sdev, spi_read_buffer_descriptor, - DMA_FROM_DEVICE, buffer, 4, NULL); + result = spi_execute(q, spi_read_buffer_descriptor, DMA_FROM_DEVICE, + buffer, 4, NULL); if (result) /* Device has no echo buffer */ @@ -847,7 +850,8 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer) } static void -spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) +spi_dv_device_internal(struct scsi_device *sdev, struct request_queue *q, + u8 *buffer) { struct spi_internal *i = to_spi_internal(sdev->host->transportt); struct scsi_target *starget = sdev->sdev_target; @@ -859,7 +863,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) DV_SET(offset, 0); DV_SET(width, 0); - if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS) + if (spi_dv_device_compare_inquiry(sdev, q, buffer, buffer, DV_LOOPS) != SPI_COMPARE_SUCCESS) { starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n"); /* FIXME: should probably offline the device here? */ @@ -875,9 +879,8 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) if (i->f->set_width && max_width) { i->f->set_width(starget, 1); - if (spi_dv_device_compare_inquiry(sdev, buffer, - buffer + len, - DV_LOOPS) + if (spi_dv_device_compare_inquiry(sdev, q, buffer, buffer + len, + DV_LOOPS) != SPI_COMPARE_SUCCESS) { starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n"); i->f->set_width(starget, 0); @@ -946,7 +949,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) DV_SET(width, max_width); /* Do the read only INQUIRY tests */ - spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, + spi_dv_retrain(sdev, q, buffer, buffer + sdev->inquiry_len, spi_dv_device_compare_inquiry); /* See if we actually managed to negotiate and sustain DT */ if (i->f->get_dt) @@ -958,7 +961,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) * negotiated DT */ if (len == -1 && spi_dt(starget)) - len = spi_dv_device_get_echo_buffer(sdev, buffer); + len = spi_dv_device_get_echo_buffer(sdev, q, buffer); if (len <= 0) { starget_printk(KERN_INFO, starget, "Domain Validation skipping write tests\n"); @@ -970,7 +973,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) len = SPI_MAX_ECHO_BUFFER_SIZE; } - if (spi_dv_retrain(sdev, buffer, buffer + len, + if (spi_dv_retrain(sdev, q, buffer, buffer + len, spi_dv_device_echo_buffer) == SPI_COMPARE_SKIP_TEST) { /* OK, the stupid drive can't do a write echo buffer @@ -1030,7 +1033,7 @@ spi_dv_device(struct scsi_device *sdev) starget_printk(KERN_INFO, starget, "Beginning Domain Validation\n"); - spi_dv_device_internal(sdev, buffer); + spi_dv_device_internal(sdev, sdev->request_queue, buffer); starget_printk(KERN_INFO, starget, "Ending Domain Validation\n"); From patchwork Mon Nov 16 03:04:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 324976 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB60CC83008 for ; Mon, 16 Nov 2020 03:05:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A8308222B8 for ; Mon, 16 Nov 2020 03:05:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726788AbgKPDF1 (ORCPT ); Sun, 15 Nov 2020 22:05:27 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:44591 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726759AbgKPDF1 (ORCPT ); Sun, 15 Nov 2020 22:05:27 -0500 Received: by mail-pl1-f196.google.com with SMTP id b3so7648412pls.11; Sun, 15 Nov 2020 19:05:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qRKRjS62RKtDoHWQs4RID8UCcBBixKzfvMA3W55OBZ0=; b=PFvukmo0NJn+eVTIbS9NSou4q7HvvA1aNHLi4BXjXqDDYfRwdMfvmSb4A1U9i8rK/N xlhtgwWsakV0Z8z2NkpyKmBD1zP3GGjVhUkTfAeZQy96igw6g0OC35tS5F2/H/Fynv9Q 73yppVEkv7dkqUEzfnRZH76xGhSRB9HRhzYQMctJBfbsPNy1SvzYRFk7XW79QD4ST8Nb PTo3apQFA+7uWFz4DxIgFPQB/7/ECbUbi968QLIcmWhxBiP+wIR/4TfBOIqRxH3BWe7K fhoWgGqoY166Y6sPchY6bm0uvF2Oh8UHkk69Trd346vyhAX/jDWdRvVuofvJi/rz2Bwn 0UFg== X-Gm-Message-State: AOAM532xwNSu6Z2ckGcQnOTmP1/q1rKrczihnNBmJB9r5zwvyarJQWww dJM+UuMdhg/5QOEJ7jpyNVs= X-Google-Smtp-Source: ABdhPJxQOrZRBaKFIsiabwJFhagwWIEM6IkIfozTICIcENxpdTCCM5dKaESke61vHRatnCMNV5iqaA== X-Received: by 2002:a17:902:aa06:b029:d6:da66:5048 with SMTP id be6-20020a170902aa06b02900d6da665048mr11772296plb.5.1605495926223; Sun, 15 Nov 2020 19:05:26 -0800 (PST) Received: from asus.hsd1.ca.comcast.net (c-73-241-217-19.hsd1.ca.comcast.net. [73.241.217.19]) by smtp.gmail.com with ESMTPSA id r3sm17148131pjl.23.2020.11.15.19.05.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Nov 2020 19:05:25 -0800 (PST) From: Bart Van Assche To: "Martin K . Petersen" Cc: "James E . J . Bottomley" , Jens Axboe , Christoph Hellwig , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, Bart Van Assche , Alan Stern , Can Guo , Stanley Chu , Ming Lei , "Rafael J . Wysocki" , Martin Kepplinger Subject: [PATCH v2 9/9] block: Do not accept any requests while suspended Date: Sun, 15 Nov 2020 19:04:59 -0800 Message-Id: <20201116030459.13963-10-bvanassche@acm.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201116030459.13963-1-bvanassche@acm.org> References: <20201116030459.13963-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Alan Stern blk_queue_enter() accepts BLK_MQ_REQ_PREEMPT independent of the runtime power management state. Since SCSI domain validation no longer depends on this behavior, modify the behavior of blk_queue_enter() as follows: - Do not accept any requests while suspended. - Only process power management requests while suspending or resuming. Submitting BLK_MQ_REQ_PREEMPT requests to a device that is runtime- suspended causes runtime-suspended block devices not to resume as they should. The request which should cause a runtime resume instead gets issued directly, without resuming the device first. Of course the device can't handle it properly, the I/O fails, and the device remains suspended. The problem is fixed by checking that the queue's runtime-PM status isn't RPM_SUSPENDED before allowing a request to be issued, and queuing a runtime-resume request if it is. In particular, the inline blk_pm_request_resume() routine is renamed blk_pm_resume_queue() and the code is unified by merging the surrounding checks into the routine. If the queue isn't set up for runtime PM, or there currently is no restriction on allowed requests, the request is allowed. Likewise if the BLK_MQ_REQ_PREEMPT flag is set and the status isn't RPM_SUSPENDED. Otherwise a runtime resume is queued and the request is blocked until conditions are more suitable. Cc: Can Guo Cc: Stanley Chu Cc: Ming Lei Cc: Rafael J. Wysocki Reported-and-tested-by: Martin Kepplinger Signed-off-by: Alan Stern Signed-off-by: Bart Van Assche [ bvanassche: modified commit message and removed Cc: stable because without the previous patches from this series this patch would break parallel SCSI domain validation ] Reviewed-by: Can Guo Reviewed-by: Stanley Chu --- block/blk-core.c | 6 +++--- block/blk-pm.h | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index a00bce9f46d8..230880cbf8c8 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -440,7 +440,8 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) * responsible for ensuring that that counter is * globally visible before the queue is unfrozen. */ - if (pm || !blk_queue_pm_only(q)) { + if ((pm && q->rpm_status != RPM_SUSPENDED) || + !blk_queue_pm_only(q)) { success = true; } else { percpu_ref_put(&q->q_usage_counter); @@ -465,8 +466,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) wait_event(q->mq_freeze_wq, (!q->mq_freeze_depth && - (pm || (blk_pm_request_resume(q), - !blk_queue_pm_only(q)))) || + blk_pm_resume_queue(pm, q)) || blk_queue_dying(q)); if (blk_queue_dying(q)) return -ENODEV; diff --git a/block/blk-pm.h b/block/blk-pm.h index ea5507d23e75..a2283cc9f716 100644 --- a/block/blk-pm.h +++ b/block/blk-pm.h @@ -6,11 +6,14 @@ #include #ifdef CONFIG_PM -static inline void blk_pm_request_resume(struct request_queue *q) +static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) { - if (q->dev && (q->rpm_status == RPM_SUSPENDED || - q->rpm_status == RPM_SUSPENDING)) - pm_request_resume(q->dev); + if (!q->dev || !blk_queue_pm_only(q)) + return 1; /* Nothing to do */ + if (pm && q->rpm_status != RPM_SUSPENDED) + return 1; /* Request allowed */ + pm_request_resume(q->dev); + return 0; } static inline void blk_pm_mark_last_busy(struct request *rq) @@ -44,8 +47,9 @@ static inline void blk_pm_put_request(struct request *rq) --rq->q->nr_pending; } #else -static inline void blk_pm_request_resume(struct request_queue *q) +static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) { + return 1; } static inline void blk_pm_mark_last_busy(struct request *rq)