scsi: hisi_sas: Fix some issues related to asd_sas_port->phy_list
Most places that use asd_sas_port->phy_list are protected by spinlock asd_sas_port->phy_list_lock, however there are still some places which miss grabbing the lock. Add it in function hisi_sas_refresh_port_id() when accessing asd_sas_port->phy_list. This carries a risk that list mutates while at the same time dropping the lock in function hisi_sas_send_ata_reset_each_phy(). Read asd_sas_port->phy_mask instead of accessing asd_sas_port->phy_list to avoid this risk. Link: https://lore.kernel.org/r/1639999298-244569-6-git-send-email-chenxiang66@hisilicon.com Acked-by: John Garry <john.garry@huawei.com> Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
42159d3c8d
commit
29e2bac874
@ -1428,11 +1428,13 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
|
||||
sas_port = device->port;
|
||||
port = to_hisi_sas_port(sas_port);
|
||||
|
||||
spin_lock(&sas_port->phy_list_lock);
|
||||
list_for_each_entry(sas_phy, &sas_port->phy_list, port_phy_el)
|
||||
if (state & BIT(sas_phy->id)) {
|
||||
phy = sas_phy->lldd_phy;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&sas_port->phy_list_lock);
|
||||
|
||||
if (phy) {
|
||||
port->id = phy->port_id;
|
||||
@ -1509,22 +1511,25 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba,
|
||||
struct ata_link *link;
|
||||
u8 fis[20] = {0};
|
||||
u32 state;
|
||||
int i;
|
||||
|
||||
state = hisi_hba->hw->get_phys_state(hisi_hba);
|
||||
list_for_each_entry(sas_phy, &sas_port->phy_list, port_phy_el) {
|
||||
for (i = 0; i < hisi_hba->n_phy; i++) {
|
||||
if (!(state & BIT(sas_phy->id)))
|
||||
continue;
|
||||
if (!(sas_port->phy_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
ata_for_each_link(link, ap, EDGE) {
|
||||
int pmp = sata_srst_pmp(link);
|
||||
|
||||
tmf_task.phy_id = sas_phy->id;
|
||||
tmf_task.phy_id = i;
|
||||
hisi_sas_fill_ata_reset_cmd(link->device, 1, pmp, fis);
|
||||
rc = hisi_sas_exec_internal_tmf_task(device, fis, s,
|
||||
&tmf_task);
|
||||
if (rc != TMF_RESP_FUNC_COMPLETE) {
|
||||
dev_err(dev, "phy%d ata reset failed rc=%d\n",
|
||||
sas_phy->id, rc);
|
||||
i, rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user