From patchwork Tue Oct 25 10:32:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019005 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 9F9F3FA3740 for ; Tue, 25 Oct 2022 10:11:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232308AbiJYKLP (ORCPT ); Tue, 25 Oct 2022 06:11:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232289AbiJYKKg (ORCPT ); Tue, 25 Oct 2022 06:10:36 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79FE3112ABB; Tue, 25 Oct 2022 03:03:21 -0700 (PDT) Received: from fraeml709-chm.china.huawei.com (unknown [172.18.147.200]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxS906YwQz67ZwS; Tue, 25 Oct 2022 17:59:48 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml709-chm.china.huawei.com (10.206.15.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:19 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:15 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 1/7] ata: libata-scsi: Add ata_scsi_queue_internal() Date: Tue, 25 Oct 2022 18:32:50 +0800 Message-ID: <1666693976-181094-2-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Add a function to handle queued ATA internal SCSI cmnds - does much the same as ata_exec_internal_sg() does (which will be fixed up later to actually queue internal cmnds through this function). Signed-off-by: John Garry --- drivers/ata/libata-sata.c | 3 +++ drivers/ata/libata-scsi.c | 43 +++++++++++++++++++++++++++++++++++++++ drivers/ata/libata.h | 3 ++- include/linux/libata.h | 6 ++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index b6806d41a8c5..e8b828c56542 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -1258,6 +1258,9 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) { int rc = 0; + if (blk_mq_is_reserved_rq(scsi_cmd_to_rq(cmd))) + return ata_scsi_queue_internal(cmd, ap->link.device); + if (likely(ata_dev_enabled(ap->link.device))) rc = __ata_scsi_queuecmd(cmd, ap->link.device); else { diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 476e0ef4bd29..30d7c90b0c35 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3965,6 +3965,49 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) return NULL; } +unsigned int ata_scsi_queue_internal(struct scsi_cmnd *scmd, + struct ata_device *dev) +{ + struct ata_link *link = dev->link; + struct ata_port *ap = link->ap; + struct ata_queued_cmd *qc; + + /* no internal command while frozen */ + if (ap->pflags & ATA_PFLAG_FROZEN) + goto did_err; + + /* initialize internal qc */ + qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL); + link->preempted_tag = link->active_tag; + link->preempted_sactive = link->sactive; + ap->preempted_qc_active = ap->qc_active; + ap->preempted_nr_active_links = ap->nr_active_links; + link->active_tag = ATA_TAG_POISON; + link->sactive = 0; + ap->qc_active = 0; + ap->nr_active_links = 0; + + if (qc->dma_dir != DMA_NONE) { + int n_elem; + + n_elem = 1; + qc->n_elem = n_elem; + qc->sg = scsi_sglist(scmd); + qc->nbytes = qc->sg->length; + ata_sg_init(qc, qc->sg, n_elem); + } + + scmd->submitter = SUBMITTED_BY_BLOCK_LAYER; + + ata_qc_issue(qc); + + return 0; +did_err: + scmd->result = (DID_ERROR << 16); + scsi_done(scmd); + return 0; +} + int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) { u8 scsi_op = scmd->cmnd[0]; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 0c2df1e60768..15cd1cd618b8 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -82,7 +82,6 @@ extern int ata_port_probe(struct ata_port *ap); extern void __ata_port_probe(struct ata_port *ap); extern unsigned int ata_read_log_page(struct ata_device *dev, u8 log, u8 page, void *buf, unsigned int sectors); - #define to_ata_port(d) container_of(d, struct ata_port, tdev) /* libata-acpi.c */ @@ -130,6 +129,8 @@ extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, void ata_scsi_sdev_config(struct scsi_device *sdev); int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev); int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev); +unsigned int ata_scsi_queue_internal(struct scsi_cmnd *scmd, + struct ata_device *dev); /* libata-eh.c */ extern unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd); diff --git a/include/linux/libata.h b/include/linux/libata.h index 827d5838cd23..8938b584520f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -764,7 +764,9 @@ struct ata_link { struct device tdev; unsigned int active_tag; /* active tag on this link */ + unsigned int preempted_tag; u32 sactive; /* active NCQ commands */ + u32 preempted_sactive; unsigned int flags; /* ATA_LFLAG_xxx */ @@ -857,6 +859,10 @@ struct ata_port { #ifdef CONFIG_ATA_ACPI struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ #endif + + u64 preempted_qc_active; + int preempted_nr_active_links; + /* owned by EH */ u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; }; From patchwork Tue Oct 25 10:32:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019006 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 69D60C38A2D for ; Tue, 25 Oct 2022 10:11:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231599AbiJYKLT (ORCPT ); Tue, 25 Oct 2022 06:11:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230046AbiJYKKi (ORCPT ); Tue, 25 Oct 2022 06:10:38 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6976B11F487; Tue, 25 Oct 2022 03:03:24 -0700 (PDT) Received: from fraeml708-chm.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxS942Vhvz689yL; Tue, 25 Oct 2022 17:59:52 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml708-chm.china.huawei.com (10.206.15.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:22 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:19 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 2/7] ata: libata-scsi: Add ata_internal_queuecommand() Date: Tue, 25 Oct 2022 18:32:51 +0800 Message-ID: <1666693976-181094-3-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Add callback to queue reserved commands - call it "internal" as this is what libata uses. Also add it to the base ATA SHT. Signed-off-by: John Garry --- drivers/ata/libata-scsi.c | 14 ++++++++++++++ include/linux/libata.h | 5 ++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 30d7c90b0c35..0d6f37d80137 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1118,6 +1118,20 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) return 0; } +int ata_internal_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd) +{ + struct ata_port *ap; + int res; + + ap = ata_shost_to_port(shost); + spin_lock_irq(ap->lock); + res = ata_sas_queuecmd(scmd, ap); + spin_unlock_irq(ap->lock); + + return res; +} +EXPORT_SYMBOL_GPL(ata_internal_queuecommand); + /** * ata_scsi_slave_config - Set SCSI device attributes * @sdev: SCSI device to examine diff --git a/include/linux/libata.h b/include/linux/libata.h index 8938b584520f..f09c5dca16ce 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1141,6 +1141,8 @@ extern int ata_std_bios_param(struct scsi_device *sdev, sector_t capacity, int geom[]); extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); +extern int ata_internal_queuecommand(struct Scsi_Host *shost, + struct scsi_cmnd *scmd); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth); @@ -1391,7 +1393,8 @@ extern const struct attribute_group *ata_common_sdev_groups[]; .slave_destroy = ata_scsi_slave_destroy, \ .bios_param = ata_std_bios_param, \ .unlock_native_capacity = ata_scsi_unlock_native_capacity,\ - .max_sectors = ATA_MAX_SECTORS_LBA48 + .max_sectors = ATA_MAX_SECTORS_LBA48,\ + .reserved_queuecommand = ata_internal_queuecommand #define ATA_SUBBASE_SHT(drv_name) \ __ATA_BASE_SHT(drv_name), \ From patchwork Tue Oct 25 10:32:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019007 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 E4F16C38A2D for ; Tue, 25 Oct 2022 10:11:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232289AbiJYKLV (ORCPT ); Tue, 25 Oct 2022 06:11:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231704AbiJYKKj (ORCPT ); Tue, 25 Oct 2022 06:10:39 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE0CF1211C5; Tue, 25 Oct 2022 03:03:27 -0700 (PDT) Received: from fraeml706-chm.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxSC12RFXz6H73T; Tue, 25 Oct 2022 18:01:33 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml706-chm.china.huawei.com (10.206.15.55) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:26 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:22 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 3/7] ata: libata: Make space for ATA queue command in scmd payload Date: Tue, 25 Oct 2022 18:32:52 +0800 Message-ID: <1666693976-181094-4-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Prepare to put the ATA queue command in a scmd payload by using priv space per driver which uses libata. The end goal is to remove ata_port.qcmd[]. Suggested-by: Hannes Reinecke Signed-off-by: John Garry --- drivers/ata/libata-scsi.c | 6 ++++++ drivers/scsi/aic94xx/aic94xx_init.c | 2 ++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 ++ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 ++ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 ++ drivers/scsi/isci/init.c | 2 ++ drivers/scsi/mvsas/mv_init.c | 2 ++ drivers/scsi/pm8001/pm8001_init.c | 2 ++ include/linux/libata.h | 5 ++++- 9 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0d6f37d80137..18c60addf943 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1118,6 +1118,12 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) return 0; } +int ata_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd) +{ + return 0; +} +EXPORT_SYMBOL_GPL(ata_init_cmd_priv); + int ata_internal_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd) { struct ata_port *ap; diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 70b735cedeb3..e2c99c74f73e 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -63,6 +63,8 @@ static struct scsi_host_template aic94xx_sht = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; static int asd_map_memio(struct asd_ha_struct *asd_ha) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 438e8a963782..aec13a46de6e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1763,6 +1763,8 @@ static struct scsi_host_template sht_v1_hw = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; static const struct hisi_sas_hw hisi_sas_v1_hw = { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index b733eb18864c..cb057b3a84ac 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3581,6 +3581,8 @@ static struct scsi_host_template sht_v2_hw = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; static const struct hisi_sas_hw hisi_sas_v2_hw = { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index d703af7985b0..4caf07306b24 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -3248,6 +3248,8 @@ static struct scsi_host_template sht_v3_hw = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; static const struct hisi_sas_hw hisi_sas_v3_hw = { diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index c07d89451bb6..0d0b8ef71c65 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -180,6 +180,8 @@ static struct scsi_host_template isci_sht = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; static struct sas_domain_function_template isci_transport_ops = { diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 07e6c5d6c46d..e1b6cc196cef 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -57,6 +57,8 @@ static struct scsi_host_template mvs_sht = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; static struct sas_domain_function_template mvs_transport_ops = { diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index e37e8898afaa..fe55cc9765ae 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -126,6 +126,8 @@ static struct scsi_host_template pm8001_sht = { .reserved_queuecommand = sas_queuecommand_internal, .reserved_timedout = sas_internal_timeout, .nr_reserved_cmds = 2, + .init_cmd_priv = ata_init_cmd_priv, + .cmd_size = sizeof(struct ata_queued_cmd), }; /* diff --git a/include/linux/libata.h b/include/linux/libata.h index f09c5dca16ce..1a03c7fbb4e6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1143,6 +1143,7 @@ extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); extern int ata_internal_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd); +extern int ata_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth); @@ -1394,7 +1395,9 @@ extern const struct attribute_group *ata_common_sdev_groups[]; .bios_param = ata_std_bios_param, \ .unlock_native_capacity = ata_scsi_unlock_native_capacity,\ .max_sectors = ATA_MAX_SECTORS_LBA48,\ - .reserved_queuecommand = ata_internal_queuecommand + .reserved_queuecommand = ata_internal_queuecommand,\ + .cmd_size = sizeof(struct ata_queued_cmd),\ + .init_cmd_priv = ata_init_cmd_priv #define ATA_SUBBASE_SHT(drv_name) \ __ATA_BASE_SHT(drv_name), \ From patchwork Tue Oct 25 10:32:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019008 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 674C9C04A95 for ; Tue, 25 Oct 2022 10:11:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232339AbiJYKL2 (ORCPT ); Tue, 25 Oct 2022 06:11:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47630 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231945AbiJYKKl (ORCPT ); Tue, 25 Oct 2022 06:10:41 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D19A21213D0; Tue, 25 Oct 2022 03:03:31 -0700 (PDT) Received: from fraeml704-chm.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxS9C4SwBz6H6m1; Tue, 25 Oct 2022 17:59:59 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml704-chm.china.huawei.com (10.206.15.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:29 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:26 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 4/7] ata: libata: Add ata_internal_timeout() Date: Tue, 25 Oct 2022 18:32:53 +0800 Message-ID: <1666693976-181094-5-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Add a internal command timeout handler. Also hook into libsas timeout handler. Signed-off-by: John Garry --- drivers/ata/libata-scsi.c | 10 ++++++++++ drivers/scsi/libsas/sas_scsi_host.c | 5 +++++ include/linux/libata.h | 2 ++ 3 files changed, 17 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 18c60addf943..cbf266c9d4c2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1138,6 +1138,16 @@ int ata_internal_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd) } EXPORT_SYMBOL_GPL(ata_internal_queuecommand); +enum blk_eh_timer_return ata_internal_timeout(struct scsi_cmnd *scmd) +{ + struct request *rq = blk_mq_rq_from_pdu(scmd); + struct completion *wait = rq->end_io_data; + + complete(wait); + return BLK_EH_DONE; +} +EXPORT_SYMBOL_GPL(ata_internal_timeout); + /** * ata_scsi_slave_config - Set SCSI device attributes * @sdev: SCSI device to examine diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 4fdd84868ac2..9d2122e65fba 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -921,10 +921,15 @@ void sas_task_complete_internal(struct sas_task *task) enum blk_eh_timer_return sas_internal_timeout(struct scsi_cmnd *scmd) { + struct domain_device *dev = cmd_to_domain_dev(scmd); struct sas_task *task = TO_SAS_TASK(scmd); bool is_completed = true; unsigned long flags; + /* Handle libata internal command */ + if (dev_is_sata(dev) && !task->slow_task) + return ata_internal_timeout(scmd); + spin_lock_irqsave(&task->task_state_lock, flags); if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { task->task_state_flags |= SAS_TASK_STATE_ABORTED; diff --git a/include/linux/libata.h b/include/linux/libata.h index 1a03c7fbb4e6..d5a15d1a5c4d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1143,6 +1143,7 @@ extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); extern int ata_internal_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd); +extern enum blk_eh_timer_return ata_internal_timeout(struct scsi_cmnd *scmd); extern int ata_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, @@ -1397,6 +1398,7 @@ extern const struct attribute_group *ata_common_sdev_groups[]; .max_sectors = ATA_MAX_SECTORS_LBA48,\ .reserved_queuecommand = ata_internal_queuecommand,\ .cmd_size = sizeof(struct ata_queued_cmd),\ + .reserved_timedout = ata_internal_timeout,\ .init_cmd_priv = ata_init_cmd_priv #define ATA_SUBBASE_SHT(drv_name) \ From patchwork Tue Oct 25 10:32:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019009 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 E6086FA373E for ; Tue, 25 Oct 2022 10:11:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232068AbiJYKLe (ORCPT ); Tue, 25 Oct 2022 06:11:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232072AbiJYKKn (ORCPT ); Tue, 25 Oct 2022 06:10:43 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F385122BF8; Tue, 25 Oct 2022 03:03:35 -0700 (PDT) Received: from fraeml703-chm.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxSCm4KSQz67mY4; Tue, 25 Oct 2022 18:02:12 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml703-chm.china.huawei.com (10.206.15.52) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:33 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:30 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 5/7] ata: libata: Queue ATA internal commands as requests Date: Tue, 25 Oct 2022 18:32:54 +0800 Message-ID: <1666693976-181094-6-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Follow the normal path for requests and queue through the block layer. Since we now have a scsi_cmnd for every ATA queued command, we can delete ata_port.qcmd[]. The ATA queue command iterators are fixed to use the blk-mq tagset iters. For libsas it's hard to differentiate between a reserved request which is a libata internal command and SATA "tmf". Normally we can use the sas_task "is dev sata" check, but that does not work. For now just check the rq->end_io pointer. At this point all libsas sas_task should have a rq associated, so let's WARN just in case. Signed-off-by: John Garry --- drivers/ata/libata-core.c | 141 +++++++++++++++------------- drivers/ata/libata-eh.c | 11 ++- drivers/ata/libata-sata.c | 2 +- drivers/ata/libata-scsi.c | 5 +- drivers/scsi/libsas/sas_scsi_host.c | 15 ++- include/linux/libata.h | 48 +++++++++- include/scsi/libsas.h | 8 +- 7 files changed, 151 insertions(+), 79 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d3ce5c383f3a..72bb1b629264 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1440,9 +1440,21 @@ EXPORT_SYMBOL_GPL(ata_id_xfermask); static void ata_qc_complete_internal(struct ata_queued_cmd *qc) { - struct completion *waiting = qc->private_data; + struct scsi_cmnd *scmd = qc->scsicmd; + + scsi_done(scmd); +} + +static enum rq_end_io_ret ata_internal_end_rq(struct request *rq, + blk_status_t error) +{ + struct completion *waiting = rq->end_io_data; + + rq->end_io_data = (void *)(uintptr_t)error; complete(waiting); + + return RQ_END_IO_NONE; } /** @@ -1450,9 +1462,9 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) * @dev: Device to which the command is sent * @tf: Taskfile registers for the command and the result * @cdb: CDB for packet command + * @buf: Data buffer of the command + * @buflen: Length of data buffer * @dma_dir: Data transfer direction of the command - * @sgl: sg list for the data buffer of the command - * @n_elem: Number of sg entries * @timeout: Timeout in msecs (0 for default) * * Executes libata internal command with timeout. @tf contains @@ -1469,50 +1481,65 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) */ static unsigned ata_exec_internal_sg(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, - int dma_dir, struct scatterlist *sgl, - unsigned int n_elem, unsigned int timeout) + int dma_dir, void *buf, + unsigned int buflen, unsigned int timeout) { struct ata_link *link = dev->link; struct ata_port *ap = link->ap; + struct scsi_device *sdev = dev->sdev; u8 command = tf->command; int auto_timeout = 0; struct ata_queued_cmd *qc; - unsigned int preempted_tag; - u32 preempted_sactive; - u64 preempted_qc_active; - int preempted_nr_active_links; DECLARE_COMPLETION_ONSTACK(wait); unsigned long flags; unsigned int err_mask; - int rc; + struct scsi_cmnd *scmd; + struct request *rq; - spin_lock_irqsave(ap->lock, flags); + if (!sdev) + return AC_ERR_OTHER; - /* no internal command while frozen */ - if (ap->pflags & ATA_PFLAG_FROZEN) { - spin_unlock_irqrestore(ap->lock, flags); - return AC_ERR_SYSTEM; + rq = scsi_alloc_request(sdev->request_queue, + dma_dir == DMA_TO_DEVICE ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, + BLK_MQ_REQ_RESERVED); + if (IS_ERR(rq)) + return AC_ERR_OTHER; + + + if (!timeout) { + if (ata_probe_timeout) + timeout = ata_probe_timeout * 1000; + else { + timeout = ata_internal_cmd_timeout(dev, command); + auto_timeout = 1; + } } - /* initialize internal qc */ - qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL); + scmd = blk_mq_rq_to_pdu(rq); + scmd->allowed = 0; + rq->timeout = msecs_to_jiffies(timeout); + rq->rq_flags |= RQF_QUIET; + scmd->device = sdev; + + qc = ata_scmd_to_qc(scmd); + + if (buflen) { + int ret = blk_rq_map_kern(sdev->request_queue, rq, + buf, buflen, GFP_NOIO); + if (ret) { + blk_mq_free_request(rq); + return AC_ERR_OTHER; + } + } qc->tag = ATA_TAG_INTERNAL; qc->hw_tag = 0; - qc->scsicmd = NULL; + qc->scsicmd = scmd; qc->ap = ap; qc->dev = dev; ata_qc_reinit(qc); - preempted_tag = link->active_tag; - preempted_sactive = link->sactive; - preempted_qc_active = ap->qc_active; - preempted_nr_active_links = ap->nr_active_links; - link->active_tag = ATA_TAG_POISON; - link->sactive = 0; - ap->qc_active = 0; - ap->nr_active_links = 0; - /* prepare & issue qc */ qc->tf = *tf; if (cdb) @@ -1525,44 +1552,26 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, qc->flags |= ATA_QCFLAG_RESULT_TF; qc->dma_dir = dma_dir; - if (dma_dir != DMA_NONE) { - unsigned int i, buflen = 0; - struct scatterlist *sg; - - for_each_sg(sgl, sg, n_elem, i) - buflen += sg->length; - ata_sg_init(qc, sgl, n_elem); - qc->nbytes = buflen; - } - - qc->private_data = &wait; + qc->private_data = ap; qc->complete_fn = ata_qc_complete_internal; - ata_qc_issue(qc); + rq->end_io_data = &wait; + rq->end_io = ata_internal_end_rq; - spin_unlock_irqrestore(ap->lock, flags); - - if (!timeout) { - if (ata_probe_timeout) - timeout = ata_probe_timeout * 1000; - else { - timeout = ata_internal_cmd_timeout(dev, command); - auto_timeout = 1; - } - } + blk_execute_rq_nowait(rq, true); if (ap->ops->error_handler) ata_eh_release(ap); - rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout)); + wait_for_completion(&wait); if (ap->ops->error_handler) ata_eh_acquire(ap); ata_sff_flush_pio_task(ap); - if (!rc) { + if (rq->rq_flags & RQF_TIMED_OUT) { spin_lock_irqsave(ap->lock, flags); /* We're racing with irq here. If we lose, the @@ -1610,13 +1619,15 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev, err_mask = qc->err_mask; ata_qc_free(qc); - link->active_tag = preempted_tag; - link->sactive = preempted_sactive; - ap->qc_active = preempted_qc_active; - ap->nr_active_links = preempted_nr_active_links; + link->active_tag = link->preempted_tag; + link->sactive = link->preempted_sactive; + ap->qc_active = ap->preempted_qc_active; + ap->nr_active_links = ap->preempted_nr_active_links; spin_unlock_irqrestore(ap->lock, flags); + blk_mq_free_request(rq); + if ((err_mask & AC_ERR_TIMEOUT) && auto_timeout) ata_internal_cmd_timed_out(dev, command); @@ -1647,18 +1658,20 @@ unsigned ata_exec_internal(struct ata_device *dev, int dma_dir, void *buf, unsigned int buflen, unsigned int timeout) { - struct scatterlist *psg = NULL, sg; - unsigned int n_elem = 0; + /* buf may not be aligned, so copy to/from an aligned buffer */ + void *tmpbuf = kmemdup(buf, buflen, GFP_KERNEL); + unsigned res; - if (dma_dir != DMA_NONE) { - WARN_ON(!buf); - sg_init_one(&sg, buf, buflen); - psg = &sg; - n_elem++; - } + if (!tmpbuf) + return AC_ERR_OTHER; - return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem, + res = ata_exec_internal_sg(dev, tf, cdb, dma_dir, tmpbuf, buflen, timeout); + + memcpy(buf, tmpbuf, buflen); + kfree(tmpbuf); + + return res; } /** diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 1ed5b1b64792..f25f60dff5a2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -604,6 +604,9 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct ata_queued_cmd *qc; ata_qc_for_each_raw(ap, qc, i) { + if (!qc) + continue; + if (qc->flags & ATA_QCFLAG_ACTIVE && qc->scsicmd == scmd) break; @@ -1946,7 +1949,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) all_err_mask |= ehc->i.err_mask; ata_qc_for_each_raw(ap, qc, tag) { - if (!(qc->flags & ATA_QCFLAG_FAILED) || + if (!qc || (qc->flags & ATA_QCFLAG_FAILED) || ata_dev_phys_link(qc->dev) != link) continue; @@ -2223,7 +2226,7 @@ static void ata_eh_link_report(struct ata_link *link) desc = ehc->i.desc; ata_qc_for_each_raw(ap, qc, tag) { - if (!(qc->flags & ATA_QCFLAG_FAILED) || + if (!qc || !(qc->flags & ATA_QCFLAG_FAILED) || ata_dev_phys_link(qc->dev) != link || ((qc->flags & ATA_QCFLAG_QUIET) && qc->err_mask == AC_ERR_DEV)) @@ -2289,7 +2292,7 @@ static void ata_eh_link_report(struct ata_link *link) char data_buf[20] = ""; char cdb_buf[70] = ""; - if (!(qc->flags & ATA_QCFLAG_FAILED) || + if (!qc || !(qc->flags & ATA_QCFLAG_FAILED) || ata_dev_phys_link(qc->dev) != link || !qc->err_mask) continue; @@ -3795,7 +3798,7 @@ void ata_eh_finish(struct ata_port *ap) /* retry or finish qcs */ ata_qc_for_each_raw(ap, qc, tag) { - if (!(qc->flags & ATA_QCFLAG_FAILED)) + if (!qc || !(qc->flags & ATA_QCFLAG_FAILED)) continue; if (qc->err_mask) { diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index e8b828c56542..f03feccb22df 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -1432,7 +1432,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) /* has LLDD analyzed already? */ ata_qc_for_each_raw(ap, qc, tag) { - if (!(qc->flags & ATA_QCFLAG_FAILED)) + if (!qc || !(qc->flags & ATA_QCFLAG_FAILED)) continue; if (qc->err_mask) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index cbf266c9d4c2..64c6ab33cdc8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -657,7 +657,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, tag = scsi_cmd_to_rq(cmd)->tag; } - qc = __ata_qc_from_tag(ap, tag); + qc = ata_scmd_to_qc(cmd); qc->tag = qc->hw_tag = tag; qc->ap = ap; qc->dev = dev; @@ -4007,7 +4007,8 @@ unsigned int ata_scsi_queue_internal(struct scsi_cmnd *scmd, goto did_err; /* initialize internal qc */ - qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL); + qc = ata_scmd_to_qc(scmd); + qc->scsicmd = scmd; link->preempted_tag = link->active_tag; link->preempted_sactive = link->sactive; ap->preempted_qc_active = ap->qc_active; diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 9d2122e65fba..008f57931a57 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -163,8 +163,21 @@ int sas_queuecommand_internal(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); struct sas_internal *i = to_sas_internal(ha->core.shost->transportt); struct request *rq = blk_mq_rq_from_pdu(cmnd); - struct sas_task *task = rq->end_io_data; + struct sas_task *task; + + /* uh, I can't see a better check for now */ + if (rq->end_io != sas_blk_end_sync_rq) { + struct ata_queued_cmd *qc = ata_scmd_to_qc(cmnd); + struct ata_port *ap = qc->ap; + int res; + + spin_lock_irq(ap->lock); + res = ata_sas_queuecmd(cmnd, ap); + spin_unlock_irq(ap->lock); + return res; + } + task = rq->end_io_data; ASSIGN_SAS_TASK(cmnd, task); return i->dft->lldd_execute_task(task, GFP_KERNEL); diff --git a/include/linux/libata.h b/include/linux/libata.h index d5a15d1a5c4d..613a8b644306 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -818,7 +819,6 @@ struct ata_port { unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ - struct ata_queued_cmd qcmd[ATA_MAX_QUEUE + 1]; u64 qc_active; int nr_active_links; /* #links with active qcs */ @@ -1398,6 +1398,7 @@ extern const struct attribute_group *ata_common_sdev_groups[]; .max_sectors = ATA_MAX_SECTORS_LBA48,\ .reserved_queuecommand = ata_internal_queuecommand,\ .cmd_size = sizeof(struct ata_queued_cmd),\ + .nr_reserved_cmds = 1,\ .reserved_timedout = ata_internal_timeout,\ .init_cmd_priv = ata_init_cmd_priv @@ -1750,11 +1751,52 @@ static inline void ata_qc_set_polling(struct ata_queued_cmd *qc) qc->tf.ctl |= ATA_NIEN; } +static inline struct ata_queued_cmd *ata_scmd_to_qc(struct scsi_cmnd *scmd) +{ + return (struct ata_queued_cmd *)(scmd + 1); +} + +struct ata_iter_data { + unsigned int tag; + struct ata_queued_cmd **qc; +}; + +static inline bool ata_check_qc_inflight(struct request *rq, void *priv) +{ + struct ata_iter_data *data = priv; + struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq); + struct ata_queued_cmd *qc = ata_scmd_to_qc(scmd); + + if (qc->tag == data->tag) { + *(data->qc) = qc; + return false; + } + + return true; +} + static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap, unsigned int tag) { - if (ata_tag_valid(tag)) - return &ap->qcmd[tag]; + struct ata_link *link; + struct Scsi_Host *shost = ap->scsi_host; + + ata_for_each_link(link, ap, EDGE) { + struct ata_device *dev; + + ata_for_each_dev(dev, link, ALL) { + struct ata_queued_cmd *qc = NULL; + struct ata_iter_data data = { + .tag = tag, + .qc = &qc, + }; + blk_mq_tagset_busy_iter(&shost->tag_set, + ata_check_qc_inflight, &data); + if (qc) + return qc; + } + } + return NULL; } diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index f903be5895a9..0272116d73fc 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -644,15 +644,15 @@ static inline struct request *sas_task_find_rq(struct sas_task *task) { struct scsi_cmnd *scmd; - if (!task->slow_task && task->task_proto & SAS_PROTOCOL_STP_ALL) { + if (task->slow_task || !(task->task_proto & SAS_PROTOCOL_STP_ALL)) { + scmd = task->uldd_task; + } else { struct ata_queued_cmd *qc = task->uldd_task; scmd = qc ? qc->scsicmd : NULL; - } else { - scmd = task->uldd_task; } - if (!scmd) + if (WARN_ON_ONCE(!scmd)) return NULL; return scsi_cmd_to_rq(scmd); From patchwork Tue Oct 25 10:32:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019010 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 08995C38A2D for ; Tue, 25 Oct 2022 10:11:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232135AbiJYKLv (ORCPT ); Tue, 25 Oct 2022 06:11:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230361AbiJYKKq (ORCPT ); Tue, 25 Oct 2022 06:10:46 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6018F12741E; Tue, 25 Oct 2022 03:03:39 -0700 (PDT) Received: from fraeml702-chm.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxS9L6lMFz67MQZ; Tue, 25 Oct 2022 18:00:06 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml702-chm.china.huawei.com (10.206.15.51) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:37 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:33 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 6/7] scsi: mvsas: Remove internal tag handling Date: Tue, 25 Oct 2022 18:32:55 +0800 Message-ID: <1666693976-181094-7-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Now that any sas_task which we're sent has a request associated, delete internal tag management. Signed-off-by: John Garry --- drivers/scsi/mvsas/mv_init.c | 11 -------- drivers/scsi/mvsas/mv_sas.c | 55 ++---------------------------------- drivers/scsi/mvsas/mv_sas.h | 1 - 3 files changed, 2 insertions(+), 65 deletions(-) diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index e1b6cc196cef..9cb8d5b315db 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -147,7 +147,6 @@ static void mvs_free(struct mvs_info *mvi) scsi_host_put(mvi->shost); list_for_each_entry(mwq, &mvi->wq_list, entry) cancel_delayed_work(&mwq->work_q); - kfree(mvi->rsvd_tags); kfree(mvi); } @@ -371,10 +370,6 @@ static struct mvs_info *mvs_pci_alloc(struct pci_dev *pdev, mvi->sas = sha; mvi->shost = shost; - mvi->rsvd_tags = bitmap_zalloc(MVS_RSVD_SLOTS, GFP_KERNEL); - if (!mvi->rsvd_tags) - goto err_out; - if (MVS_CHIP_DISP->chip_ioremap(mvi)) goto err_out; if (!mvs_alloc(mvi, shost)) @@ -473,12 +468,6 @@ static void mvs_post_sas_ha_init(struct Scsi_Host *shost, else can_queue = MVS_CHIP_SLOT_SZ; - /* - * Carve out MVS_RSVD_SLOTS slots internally until every sas_task we're sent - * has a request associated. - */ - can_queue -= MVS_RSVD_SLOTS; - shost->sg_tablesize = min_t(u16, SG_ALL, MVS_MAX_SG); shost->can_queue = can_queue; mvi->shost->cmd_per_lun = MVS_QUEUE_SIZE; diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 9978c424214c..3c92fc48680d 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -20,40 +20,6 @@ static int mvs_find_tag(struct mvs_info *mvi, struct sas_task *task, u32 *tag) return 0; } -static void mvs_tag_clear(struct mvs_info *mvi, u32 tag) -{ - void *bitmap = mvi->rsvd_tags; - clear_bit(tag, bitmap); -} - -static void mvs_tag_free(struct mvs_info *mvi, u32 tag) -{ - if (tag >= MVS_RSVD_SLOTS) - return; - - mvs_tag_clear(mvi, tag); -} - -static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) -{ - void *bitmap = mvi->rsvd_tags; - set_bit(tag, bitmap); -} - -static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) -{ - unsigned int index, tag; - void *bitmap = mvi->rsvd_tags; - - index = find_first_zero_bit(bitmap, MVS_RSVD_SLOTS); - tag = index; - if (tag >= MVS_RSVD_SLOTS) - return -SAS_QUEUE_FULL; - mvs_tag_set(mvi, tag); - *tag_out = tag; - return 0; -} - static struct mvs_info *mvs_find_dev_mvi(struct domain_device *dev) { unsigned long i = 0, j = 0, hi = 0; @@ -765,13 +731,7 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf } rq = sas_task_find_rq(task); - if (rq) { - tag = rq->tag + MVS_RSVD_SLOTS; - } else { - rc = mvs_tag_alloc(mvi, &tag); - if (rc) - goto err_out; - } + tag = rq->tag; slot = &mvi->slot_info[tag]; @@ -782,7 +742,7 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf slot->buf = dma_pool_zalloc(mvi->dma_pool, GFP_ATOMIC, &slot->buf_dma); if (!slot->buf) { rc = -ENOMEM; - goto err_out_tag; + goto err_out; } tei.task = task; @@ -826,8 +786,6 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf err_out_slot_buf: dma_pool_free(mvi->dma_pool, slot->buf, slot->buf_dma); -err_out_tag: - mvs_tag_free(mvi, tag); err_out: dev_printk(KERN_ERR, mvi->dev, "mvsas prep failed[%d]!\n", rc); @@ -863,12 +821,6 @@ int mvs_queue_command(struct sas_task *task, gfp_t gfp_flags) return rc; } -static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc) -{ - u32 slot_idx = rx_desc & RXQ_SLOT_MASK; - mvs_tag_free(mvi, slot_idx); -} - static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, struct mvs_slot_info *slot, u32 slot_idx) { @@ -906,7 +858,6 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, slot->task = NULL; slot->port = NULL; slot->slot_tag = 0xFFFFFFFF; - mvs_slot_free(mvi, slot_idx); } static void mvs_update_wideport(struct mvs_info *mvi, int phy_no) @@ -1913,8 +1864,6 @@ int mvs_int_rx(struct mvs_info *mvi, bool self_clear) } else if (rx_desc & RXQ_ERR) { if (!(rx_desc & RXQ_DONE)) mvs_slot_complete(mvi, rx_desc, 0); - } else if (rx_desc & RXQ_SLOT_RESET) { - mvs_slot_free(mvi, rx_desc); } } diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 68df771e2975..bc3b5711fc07 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -370,7 +370,6 @@ struct mvs_info { u32 chip_id; const struct mvs_chip_info *chip; - unsigned long *rsvd_tags; /* further per-slot information */ struct mvs_phy phy[MVS_MAX_PHYS]; struct mvs_port port[MVS_MAX_PHYS]; From patchwork Tue Oct 25 10:32:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 13019019 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 2B7B9C04A95 for ; Tue, 25 Oct 2022 10:12:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232153AbiJYKMJ (ORCPT ); Tue, 25 Oct 2022 06:12:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232171AbiJYKKt (ORCPT ); Tue, 25 Oct 2022 06:10:49 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8806013669F; Tue, 25 Oct 2022 03:03:42 -0700 (PDT) Received: from fraeml701-chm.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4MxS9Q390vz67brF; Tue, 25 Oct 2022 18:00:10 +0800 (CST) Received: from lhrpeml500003.china.huawei.com (7.191.162.67) by fraeml701-chm.china.huawei.com (10.206.15.50) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2375.31; Tue, 25 Oct 2022 12:03:40 +0200 Received: from localhost.localdomain (10.69.192.58) by lhrpeml500003.china.huawei.com (7.191.162.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 25 Oct 2022 11:03:37 +0100 From: John Garry To: , , , , , , , CC: , , , , , , , John Garry Subject: [PATCH RFC v3 7/7] scsi: hisi_sas: Remove internal tag handling for reserved commands Date: Tue, 25 Oct 2022 18:32:56 +0800 Message-ID: <1666693976-181094-8-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1666693976-181094-1-git-send-email-john.garry@huawei.com> References: <1666693976-181094-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To lhrpeml500003.china.huawei.com (7.191.162.67) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Now that any sas_task which we're sent has a request associated, we can use the request tag for slot IPTT. However, since v2 HW has its own slot IPTT allocation scheme due to badly broken HW, continue to use it. Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 3 - drivers/scsi/hisi_sas/hisi_sas_main.c | 82 +++++--------------------- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 9 +-- 3 files changed, 17 insertions(+), 77 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 6f8a52a1b808..8cd238f75066 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -39,9 +39,6 @@ #define HISI_SAS_PM_BIT 2 #define HISI_SAS_HW_FAULT_BIT 3 #define HISI_SAS_MAX_COMMANDS (HISI_SAS_QUEUE_SLOTS) -#define HISI_SAS_RESERVED_IPTT 96 -#define HISI_SAS_UNRESERVED_IPTT \ - (HISI_SAS_MAX_COMMANDS - HISI_SAS_RESERVED_IPTT) #define HISI_SAS_IOST_ITCT_CACHE_NUM 64 #define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 65475775c844..7f784cdacf9f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -161,49 +161,13 @@ static void hisi_sas_slot_index_clear(struct hisi_hba *hisi_hba, int slot_idx) static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) { - if (hisi_hba->hw->slot_index_alloc || - slot_idx >= HISI_SAS_UNRESERVED_IPTT) { + if (hisi_hba->hw->slot_index_alloc) { spin_lock(&hisi_hba->lock); hisi_sas_slot_index_clear(hisi_hba, slot_idx); spin_unlock(&hisi_hba->lock); } } -static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx) -{ - void *bitmap = hisi_hba->slot_index_tags; - - __set_bit(slot_idx, bitmap); -} - -static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, - struct request *rq) -{ - int index; - void *bitmap = hisi_hba->slot_index_tags; - - if (rq) - return rq->tag + HISI_SAS_RESERVED_IPTT; - - spin_lock(&hisi_hba->lock); - index = find_next_zero_bit(bitmap, HISI_SAS_RESERVED_IPTT, - hisi_hba->last_slot_index + 1); - if (index >= HISI_SAS_RESERVED_IPTT) { - index = find_next_zero_bit(bitmap, - HISI_SAS_RESERVED_IPTT, - 0); - if (index >= HISI_SAS_RESERVED_IPTT) { - spin_unlock(&hisi_hba->lock); - return -SAS_QUEUE_FULL; - } - } - hisi_sas_slot_index_set(hisi_hba, index); - hisi_hba->last_slot_index = index; - spin_unlock(&hisi_hba->lock); - - return index; -} - void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot) { @@ -465,8 +429,10 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) struct hisi_sas_port *port; struct hisi_hba *hisi_hba; struct hisi_sas_slot *slot; + unsigned int dq_index; struct request *rq; struct device *dev; + u32 blk_tag; int rc; if (!sas_port) { @@ -486,20 +452,9 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) hisi_hba = dev_to_hisi_hba(device); dev = hisi_hba->dev; rq = sas_task_find_rq(task); - if (rq) { - unsigned int dq_index; - u32 blk_tag; - - blk_tag = blk_mq_unique_tag(rq); - dq_index = blk_mq_unique_tag_to_hwq(blk_tag); - dq = &hisi_hba->dq[dq_index]; - } else { - struct Scsi_Host *shost = hisi_hba->shost; - struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; - int queue = qmap->mq_map[raw_smp_processor_id()]; - - dq = &hisi_hba->dq[queue]; - } + blk_tag = blk_mq_unique_tag(rq); + dq_index = blk_mq_unique_tag_to_hwq(blk_tag); + dq = &hisi_hba->dq[dq_index]; switch (task->task_proto) { case SAS_PROTOCOL_SSP: @@ -563,13 +518,13 @@ static int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) goto err_out_dma_unmap; } - if (!internal_abort && hisi_hba->hw->slot_index_alloc) + if (hisi_hba->hw->slot_index_alloc) { rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device); - else - rc = hisi_sas_slot_index_alloc(hisi_hba, rq); - - if (rc < 0) - goto err_out_dif_dma_unmap; + if (rc < 0) + goto err_out_dif_dma_unmap; + } else { + rc = rq->tag; + } slot = &hisi_hba->slot_info[rc]; slot->n_elem = n_elem; @@ -2434,17 +2389,8 @@ int hisi_sas_probe(struct platform_device *pdev, shost->max_lun = ~0; shost->max_channel = 1; shost->max_cmd_len = 16; - if (hisi_hba->hw->slot_index_alloc) { - shost->can_queue = HISI_SAS_MAX_COMMANDS; - shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS; - } else { - /* - * Intentionally use HISI_SAS_UNRESERVED_IPTT for .can_queue until - * every sas_task we're sent has a request associated. - */ - shost->can_queue = HISI_SAS_UNRESERVED_IPTT; - shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; - } + shost->can_queue = HISI_SAS_MAX_COMMANDS; + shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS; sha->sas_ha_name = DRV_NAME; sha->dev = hisi_hba->dev; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 4caf07306b24..c7963ae8ad50 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -4862,12 +4862,9 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) shost->max_lun = ~0; shost->max_channel = 1; shost->max_cmd_len = 16; - /* - * Intentionally use HISI_SAS_UNRESERVED_IPTT for .can_queue until - * every sas_task we're sent has a request associated. - */ - shost->can_queue = HISI_SAS_UNRESERVED_IPTT; - shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; + + shost->can_queue = HISI_SAS_MAX_COMMANDS; + shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS; sha->sas_ha_name = DRV_NAME; sha->dev = dev;