From 245050af5d15a4f518c130e896cb597a263a070b Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 5 Sep 2022 19:48:45 +0800 Subject: scsi: hisi_sas: Revert change to limit max hw sectors for v3 HW Now that libsas and the SCSI core code limits the default sectors from commit 4cbfca5f7750 ("scsi: scsi_transport_sas: cap shost opt_sectors according to DMA optimal limit") and commit 608128d391fa ("scsi: sd: allow max_sectors be capped at DMA optimal size limit"), there is no need for the hack to limit the max HW sectors. Link: https://lore.kernel.org/r/1662378529-101489-2-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/scsi/hisi_sas') diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index efe8c5be5870..1710f479a896 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2786,7 +2786,6 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) struct hisi_hba *hisi_hba = shost_priv(shost); int ret = hisi_sas_slave_configure(sdev); struct device *dev = hisi_hba->dev; - unsigned int max_sectors; if (ret) return ret; @@ -2802,12 +2801,6 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) } } - /* Set according to IOMMU IOVA caching limit */ - max_sectors = min_t(size_t, queue_max_hw_sectors(sdev->request_queue), - (PAGE_SIZE * 32) >> SECTOR_SHIFT); - - blk_queue_max_hw_sectors(sdev->request_queue, max_sectors); - return 0; } -- cgit v1.2.3 From bc5551157a747d463247a54b611e5a8464677c6f Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 5 Sep 2022 19:48:46 +0800 Subject: scsi: hisi_sas: Clear HISI_SAS_HW_FAULT_BIT earlier Once the controller HW has been reset then we can unset flag HISI_SAS_HW_FAULT_BIT. In clearing this flag earlier we can now successfully execute commands in hisi_sas_controller_reset_done(), like bcast processing. Link: https://lore.kernel.org/r/1662378529-101489-3-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/hisi_sas') diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 33af5b8dede2..a33d46a5d7cd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1527,9 +1527,9 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags); return rc; } + clear_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags); hisi_sas_controller_reset_done(hisi_hba); - clear_bit(HISI_SAS_HW_FAULT_BIT, &hisi_hba->flags); dev_info(dev, "controller reset complete\n"); return 0; -- cgit v1.2.3 From 11ff0c98fca35df16c84d4eee52008faecaf10a6 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 5 Sep 2022 19:48:47 +0800 Subject: scsi: hisi_sas: Drain bcast events in hisi_sas_rescan_topology() In resetting the controller, SATA devices may be lost. The issue is that when we insert the bcast events to rescan the topology in hisi_sas_rescan_topology(), when we subsequently nexus reset the SATA devices in hisi_sas_async_I_T_nexus_reset(), there is a small timing window in which the remote phy is down and we process the bcast event (meaning that libsas judges that the disk is lost). Ensure that all bcast events are processed prior to the nexus reset to close this window. Link: https://lore.kernel.org/r/1662378529-101489-4-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/scsi/hisi_sas') diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index a33d46a5d7cd..2edadd4008c0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1341,6 +1341,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba) static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) { + struct sas_ha_struct *sas_ha = &hisi_hba->sha; struct asd_sas_port *_sas_port = NULL; int phy_no; @@ -1369,6 +1370,12 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state) hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL); } } + /* + * Ensure any bcast events are processed prior to calling async nexus + * reset calls from hisi_sas_clear_nexus_ha() -> + * hisi_sas_async_I_T_nexus_reset() + */ + sas_drain_work(sas_ha); } static void hisi_sas_reset_init_all_devices(struct hisi_hba *hisi_hba) -- cgit v1.2.3 From e9b6bada980957e0ada6613a749875e133a0327d Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 5 Sep 2022 19:48:48 +0800 Subject: scsi: hisi_sas: Add helper to process bcast events Add a helper for bcast processing to reduce duplication. Link: https://lore.kernel.org/r/1662378529-101489-5-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +--- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 7 ++----- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ++----- 5 files changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers/scsi/hisi_sas') diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 24c83bc4f5dc..9aebf4a26b13 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -649,6 +649,7 @@ extern void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no, int enable); extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy, gfp_t gfp_flags); +extern void hisi_sas_phy_bcast(struct hisi_sas_phy *phy); extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot); diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 2edadd4008c0..32fa775e7d37 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1989,6 +1989,18 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy, } EXPORT_SYMBOL_GPL(hisi_sas_phy_down); +void hisi_sas_phy_bcast(struct hisi_sas_phy *phy) +{ + struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct hisi_hba *hisi_hba = phy->hisi_hba; + + if (test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) + return; + + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); +} +EXPORT_SYMBOL_GPL(hisi_sas_phy_bcast); + void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba) { int i; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 349546bacb2b..d643c5a49aa9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1412,9 +1412,7 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p) goto end; } - if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) - sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, - GFP_ATOMIC); + hisi_sas_phy_bcast(phy); end: hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 70e401fd432a..a9c16428906c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2811,15 +2811,12 @@ static irqreturn_t int_phy_updown_v2_hw(int irq_no, void *p) static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; - struct asd_sas_phy *sas_phy = &phy->sas_phy; u32 bcast_status; hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); - if ((bcast_status & RX_BCAST_CHG_MSK) && - !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) - sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, - GFP_ATOMIC); + if (bcast_status & RX_BCAST_CHG_MSK) + hisi_sas_phy_bcast(phy); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_RX_BCST_ACK_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 1710f479a896..10b55cef5cf5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1626,15 +1626,12 @@ static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) { struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; - struct asd_sas_phy *sas_phy = &phy->sas_phy; u32 bcast_status; hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1); bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS); - if ((bcast_status & RX_BCAST_CHG_MSK) && - !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) - sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, - GFP_ATOMIC); + if (bcast_status & RX_BCAST_CHG_MSK) + hisi_sas_phy_bcast(phy); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_SL_RX_BCST_ACK_MSK); hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); -- cgit v1.2.3 From f5f2a2716055ad8c0c4ff83e51d667646c6c5d8a Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 5 Sep 2022 19:48:49 +0800 Subject: scsi: hisi_sas: Don't send bcast events from HW during nexus HA reset Remote devices may go missing from the per-device nexus reset part of the HA nexus, i.e after the controller reset. This is because libsas may find the devices to be gone as the phy may be temporarily down when processing the bcast event generated from the nexus reset. Filter out bcast events during this time to stop the devices being lost. Link: https://lore.kernel.org/r/1662378529-101489-6-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/hisi_sas') diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 32fa775e7d37..699b07abb6b0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1823,12 +1823,14 @@ static int hisi_sas_clear_nexus_ha(struct sas_ha_struct *sas_ha) struct hisi_hba *hisi_hba = sas_ha->lldd_ha; HISI_SAS_DECLARE_RST_WORK_ON_STACK(r); ASYNC_DOMAIN_EXCLUSIVE(async); - int i; + int i, ret; queue_work(hisi_hba->wq, &r.work); wait_for_completion(r.completion); - if (!r.done) - return TMF_RESP_FUNC_FAILED; + if (!r.done) { + ret = TMF_RESP_FUNC_FAILED; + goto out; + } for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { struct hisi_sas_device *sas_dev = &hisi_hba->devices[i]; @@ -1845,7 +1847,9 @@ static int hisi_sas_clear_nexus_ha(struct sas_ha_struct *sas_ha) async_synchronize_full_domain(&async); hisi_sas_release_tasks(hisi_hba); - return TMF_RESP_FUNC_COMPLETE; + ret = TMF_RESP_FUNC_COMPLETE; +out: + return ret; } static int hisi_sas_query_task(struct sas_task *task) @@ -1993,10 +1997,14 @@ void hisi_sas_phy_bcast(struct hisi_sas_phy *phy) { struct asd_sas_phy *sas_phy = &phy->sas_phy; struct hisi_hba *hisi_hba = phy->hisi_hba; + struct sas_ha_struct *sha = &hisi_hba->sha; if (test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) return; + if (test_bit(SAS_HA_FROZEN, &sha->state)) + return; + sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD, GFP_ATOMIC); } EXPORT_SYMBOL_GPL(hisi_sas_phy_bcast); -- cgit v1.2.3