This series contains some misc patches for next, broadly divided into two
areas:
- Revert hack to limit max HW sectors for v3 HW since we now that we a
proper solution in the core SCSI and DMA IOMMU code
- Deal with SATA disks being lost during controller reset
Thanks in advance,
John
John Garry (5):
scsi: hisi_sas: Revert change to limit max hw sectors for v3 HW
scsi: hisi_sas: Clear HISI_SAS_HW_FAULT_BIT earlier
scsi: hisi_sas: Drain bcast events in hisi_sas_rescan_topology()
scsi: hisi_sas: Add helper to process bcast events
scsi: hisi_sas: Don't send bcast events from HW during nexus HA reset
drivers/scsi/hisi_sas/hisi_sas.h | 1 +
drivers/scsi/hisi_sas/hisi_sas_main.c | 37 ++++++++++++++++++++++----
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 | 14 ++--------
5 files changed, 38 insertions(+), 25 deletions(-)
--
2.35.3
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.
Signed-off-by: John Garry <[email protected]>
---
drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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;
--
2.35.3
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.
Signed-off-by: John Garry <[email protected]>
---
drivers/scsi/hisi_sas/hisi_sas_main.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
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);
--
2.35.3
Add a helper for bcast processing to reduce duplication.
Signed-off-by: John Garry <[email protected]>
---
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(-)
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);
--
2.35.3
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.
Signed-off-by: John Garry <[email protected]>
---
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 -------
1 file changed, 7 deletions(-)
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;
}
--
2.35.3
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.
Signed-off-by: John Garry <[email protected]>
---
drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++++
1 file changed, 7 insertions(+)
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)
--
2.35.3
John,
> This series contains some misc patches for next, broadly divided into two
> areas:
> - Revert hack to limit max HW sectors for v3 HW since we now that we a
> proper solution in the core SCSI and DMA IOMMU code
> - Deal with SATA disks being lost during controller reset
Applied to 6.1/scsi-staging, thanks!
--
Martin K. Petersen Oracle Linux Engineering