Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: lpfc: Trigger SLI4 firmware dump before doing driver cleanup

Extraneous teardown routines are present in the firmware dump path causing
altered states in firmware captures.

When a firmware dump is requested via sysfs, trigger the dump immediately
without tearing down structures and changing adapter state.

The driver shall rely on pre-existing firmware error state clean up
handlers to restore the adapter.

Link: https://lore.kernel.org/r/20211204002644.116455-6-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

James Smart and committed by
Martin K. Petersen
7dd2e2a9 8ed190a9

+51 -33
+1 -1
drivers/scsi/lpfc/lpfc.h
··· 1021 1021 #define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */ 1022 1022 #define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ 1023 1023 #define HBA_IOQ_FLUSH 0x8000 /* FCP/NVME I/O queues being flushed */ 1024 - #define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */ 1025 1024 #define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */ 1026 1025 #define HBA_FORCED_LINK_SPEED 0x40000 /* 1027 1026 * Firmware supports Forced Link Speed ··· 1037 1038 #define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */ 1038 1039 #define HBA_FLOGI_OUTSTANDING 0x10000000 /* FLOGI is outstanding */ 1039 1040 1041 + struct completion *fw_dump_cmpl; /* cmpl event tracker for fw_dump */ 1040 1042 uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ 1041 1043 struct lpfc_dmabuf slim2p; 1042 1044
+43 -25
drivers/scsi/lpfc/lpfc_attr.c
··· 1709 1709 before_fc_flag = phba->pport->fc_flag; 1710 1710 sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn; 1711 1711 1712 - /* Disable SR-IOV virtual functions if enabled */ 1713 - if (phba->cfg_sriov_nr_virtfn) { 1714 - pci_disable_sriov(pdev); 1715 - phba->cfg_sriov_nr_virtfn = 0; 1712 + if (opcode == LPFC_FW_DUMP) { 1713 + init_completion(&online_compl); 1714 + phba->fw_dump_cmpl = &online_compl; 1715 + } else { 1716 + /* Disable SR-IOV virtual functions if enabled */ 1717 + if (phba->cfg_sriov_nr_virtfn) { 1718 + pci_disable_sriov(pdev); 1719 + phba->cfg_sriov_nr_virtfn = 0; 1720 + } 1721 + 1722 + status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); 1723 + 1724 + if (status != 0) 1725 + return status; 1726 + 1727 + /* wait for the device to be quiesced before firmware reset */ 1728 + msleep(100); 1716 1729 } 1717 - 1718 - if (opcode == LPFC_FW_DUMP) 1719 - phba->hba_flag |= HBA_FW_DUMP_OP; 1720 - 1721 - status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); 1722 - 1723 - if (status != 0) { 1724 - phba->hba_flag &= ~HBA_FW_DUMP_OP; 1725 - return status; 1726 - } 1727 - 1728 - /* wait for the device to be quiesced before firmware reset */ 1729 - msleep(100); 1730 1730 1731 1731 reg_val = readl(phba->sli4_hba.conf_regs_memmap_p + 1732 1732 LPFC_CTL_PDEV_CTL_OFFSET); ··· 1756 1756 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 1757 1757 "3153 Fail to perform the requested " 1758 1758 "access: x%x\n", reg_val); 1759 + if (phba->fw_dump_cmpl) 1760 + phba->fw_dump_cmpl = NULL; 1759 1761 return rc; 1760 1762 } 1761 1763 1762 1764 /* keep the original port state */ 1763 - if (before_fc_flag & FC_OFFLINE_MODE) 1765 + if (before_fc_flag & FC_OFFLINE_MODE) { 1766 + if (phba->fw_dump_cmpl) 1767 + phba->fw_dump_cmpl = NULL; 1764 1768 goto out; 1769 + } 1765 1770 1766 - init_completion(&online_compl); 1767 - job_posted = lpfc_workq_post_event(phba, &status, &online_compl, 1768 - LPFC_EVT_ONLINE); 1769 - if (!job_posted) 1770 - goto out; 1771 + /* Firmware dump will trigger an HA_ERATT event, and 1772 + * lpfc_handle_eratt_s4 routine already handles bringing the port back 1773 + * online. 1774 + */ 1775 + if (opcode == LPFC_FW_DUMP) { 1776 + wait_for_completion(phba->fw_dump_cmpl); 1777 + } else { 1778 + init_completion(&online_compl); 1779 + job_posted = lpfc_workq_post_event(phba, &status, &online_compl, 1780 + LPFC_EVT_ONLINE); 1781 + if (!job_posted) 1782 + goto out; 1771 1783 1772 - wait_for_completion(&online_compl); 1773 - 1784 + wait_for_completion(&online_compl); 1785 + } 1774 1786 out: 1775 1787 /* in any case, restore the virtual functions enabled as before */ 1776 1788 if (sriov_nr_virtfn) { 1789 + /* If fw_dump was performed, first disable to clean up */ 1790 + if (opcode == LPFC_FW_DUMP) { 1791 + pci_disable_sriov(pdev); 1792 + phba->cfg_sriov_nr_virtfn = 0; 1793 + } 1794 + 1777 1795 sriov_err = 1778 1796 lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn); 1779 1797 if (!sriov_err)
+7 -1
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 869 869 if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) 870 870 lpfc_sli4_post_async_mbox(phba); 871 871 872 - if (ha_copy & HA_ERATT) 872 + if (ha_copy & HA_ERATT) { 873 873 /* Handle the error attention event */ 874 874 lpfc_handle_eratt(phba); 875 + 876 + if (phba->fw_dump_cmpl) { 877 + complete(phba->fw_dump_cmpl); 878 + phba->fw_dump_cmpl = NULL; 879 + } 880 + } 875 881 876 882 if (ha_copy & HA_MBATT) 877 883 lpfc_sli_handle_mb_event(phba);
-6
drivers/scsi/lpfc/lpfc_sli.c
··· 5046 5046 phba->fcf.fcf_flag = 0; 5047 5047 spin_unlock_irq(&phba->hbalock); 5048 5048 5049 - /* SLI4 INTF 2: if FW dump is being taken skip INIT_PORT */ 5050 - if (phba->hba_flag & HBA_FW_DUMP_OP) { 5051 - phba->hba_flag &= ~HBA_FW_DUMP_OP; 5052 - return rc; 5053 - } 5054 - 5055 5049 /* Now physically reset the device */ 5056 5050 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 5057 5051 "0389 Performing PCI function reset!\n");