diff --git a/commit.log b/commit.log new file mode 100644 index 0000000000000000000000000000000000000000..0613d466713404834eca2d5360c4b6404836a2f0 --- /dev/null +++ b/commit.log @@ -0,0 +1,29 @@ +mainline inclusion +from mainline-v6.6 +commit 82b2fb52d6ecc3c902b46b3f9bb4325ab3f6d50d +category: bugfix +bugzilla: https://gitee.com/openeuler/kernel/issues/ID2S6E + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=82b2fb52d6ecc3c902b46b3f9bb4325ab3f6d50d + +-------------------------------- + +scsi: mpi3mr: Split off bus_reset function from host_reset +SCSI EH host reset is the final callback in the escalation chain; once we +reach this we need to reset the controller. As such it defeats the purpose +to skip controller reset if no I/Os are pending and the RAID device is to +be reset; especially after kexec there might be stale commands pending in +firmware for which we have no reference whatsoever. So this patch splits +off the check for pending I/O into a 'bus_reset' function, and leaves the +actual controller reset to the host reset. + +Signed-off-by: Hannes Reinecke +Link: https://lore.kernel.org/r/20231002154328.43718-19-hare@suse.de +Cc: Kashyap Desai +Cc: Sathya Prakash Veerichetty +Cc: Sumit Saxena +Cc: Sreekanth Reddy +Reviewed-by: Christoph Hellwig +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: yongkang diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index 7022435c21e9fcd9310fed108a15b540bf662262..b905e32b21733f4ad2b968083d2b22ad361d5436 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -504,7 +504,7 @@ struct mpi3mr_sas_port { u8 num_phys; u8 marked_responding; int lowest_phy; - u32 phy_mask; + u64 phy_mask; struct mpi3mr_hba_port *hba_port; struct sas_identify remote_identify; struct sas_rphy *rphy; diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c index 0072bbdb265b8cb8587a8d49eccbcb020ae94c06..5d261c2f2d20051087a6c8af6b7e70f18f990d30 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c @@ -1597,7 +1597,7 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, */ struct host_port { u64 sas_address; - u32 phy_mask; + u64 phy_mask; u16 handle; u8 iounit_port_id; u8 used; @@ -1621,7 +1621,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, struct mpi3mr_sas_port *mr_sas_port) { struct mpi3mr_sas_phy *mr_sas_phy; - u32 phy_mask_xor; + u64 phy_mask_xor; u64 phys_to_be_added, phys_to_be_removed; int i; @@ -1629,7 +1629,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, mr_sas_port->marked_responding = 1; dev_info(&mr_sas_port->port->dev, - "sas_address(0x%016llx), old: port_id %d phy_mask 0x%x, new: port_id %d phy_mask:0x%x\n", + "sas_address(0x%016llx), old: port_id %d phy_mask 0x%llx, new: port_id %d phy_mask:0x%llx\n", mr_sas_port->remote_identify.sas_address, mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, h_port->iounit_port_id, h_port->phy_mask); @@ -1647,7 +1647,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, * if these phys are previously registered with another port * then delete these phys from that port first. */ - for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u32)) { + for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u64)) { mr_sas_phy = &mrioc->sas_hba.phy[i]; if (mr_sas_phy->phy_belongs_to_port) mpi3mr_del_phy_from_an_existing_port(mrioc, @@ -1659,7 +1659,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, } /* Delete the phys which are not part of current mr_sas_port's port. */ - for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u32)) { + for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u64)) { mr_sas_phy = &mrioc->sas_hba.phy[i]; if (mr_sas_phy->phy_belongs_to_port) mpi3mr_del_phy_from_an_existing_port(mrioc, @@ -1681,7 +1681,7 @@ mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, void mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) { - struct host_port h_port[32]; + struct host_port *h_port = NULL; int i, j, found, host_port_count = 0, port_idx; u16 sz, attached_handle, ioc_status; struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL; @@ -1695,6 +1695,10 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); if (!sas_io_unit_pg0) return; + h_port = kcalloc(64, sizeof(struct host_port), GFP_KERNEL); + if (!h_port) + goto out; + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { ioc_err(mrioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -1752,7 +1756,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, port_list) { ioc_info(mrioc, - "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", + "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n", mr_sas_port->hba_port->port_id, mr_sas_port->remote_identify.sas_address, mr_sas_port->phy_mask, mr_sas_port->lowest_phy); @@ -1761,7 +1765,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) ioc_info(mrioc, "Host port details after reset\n"); for (i = 0; i < host_port_count; i++) { ioc_info(mrioc, - "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", + "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%llx), lowest phy id:%d\n", h_port[i].iounit_port_id, h_port[i].sas_address, h_port[i].phy_mask, h_port[i].lowest_phy); } @@ -1824,6 +1828,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) } } out: + kfree(h_port); kfree(sas_io_unit_pg0); }