mpt2sas: driver fails to recover from injected PCIe bus errors
PATCH 1/1 mpt2sas: driver fails to recover from injected PCIe bus errors
fixes surrounding PCIe enhanced error handling:
(1) We need to reject all request generated internaly inside the driver as well as request arriving from the scsi mid layer when PCIe EEH is active. The fix is to add a per adapter flag called pci_error_recovery which is checked thru out the driver when request are generated.
(2) We don't need to call the pci_driver->remove directly from the PCIe callbacks becuase its already called from the PCIe EEH code. In its place we are shutting down the watchdog timer, and flushing back all pending IO.
(3) We need to save and restore the pci state across PCIe EEH handling.
drivers/scsi/mpt2sas/mpt2sas_base.c +13 -0
@@ -1311,6 +1311,9 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)printk (MPT2SAS_INFO_FMT "ioport(0x%016llx), size(%d)\n" , ioc->name, (unsigned long long )pio_chip, pio_sz); +/* Save PCI configuration state for recovery from PCI AER/EEH errors */ +pci_save_state (pdev); +return 0 ; out_fail:
@@ -3407,6 +3410,9 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,dinitprintk (ioc,printk (MPT2SAS_INFO_FMT "%s\n" , ioc->name, __func__)); +if (ioc->pci_error_recovery) +return 0 ; + ioc_state =mpt2sas_base_get_iocstate (ioc,0 );dhsprintk (ioc,printk (MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n" , ioc->name, __func__, ioc_state));
@@ -3869,6 +3875,13 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,dtmprintk (ioc,printk (MPT2SAS_INFO_FMT "%s: enter\n" , ioc->name, __func__)); +if (ioc->pci_error_recovery) { +printk (MPT2SAS_ERR_FMT "%s: pci error recovery reset\n" , + ioc->name, __func__); + r =0 ; + goto out; + } +if (mpt2sas_fwfault_debug)mpt2sas_halt_firmware (ioc);
drivers/scsi/mpt2sas/mpt2sas_base.h +2 -0
@@ -477,6 +477,7 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);* @ioc_link_reset_in_progress: phy/hard reset in progress * @ignore_loginfos: ignore loginfos during task managment * @remove_host: flag for when driver unloads, to avoid sending dev resets +* @pci_error_recovery: flag to prevent ioc access until slot reset completes * @wait_for_port_enable_to_complete: * @msix_enable: flag indicating msix is enabled * @msix_vector_count: number msix vectors
@@ -617,6 +618,7 @@ struct MPT2SAS_ADAPTER {u8 ignore_loginfos;u8 remove_host; +u8 pci_error_recovery;u8 wait_for_port_enable_to_complete;u8 msix_enable;
drivers/scsi/mpt2sas/mpt2sas_config.c +1 -1
@@ -401,7 +401,7 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_tif (ioc->config_cmds.smid == smid)mpt2sas_base_free_smid (ioc, smid);if ((ioc->shost_recovery) || (ioc->config_cmds.status & -MPT2_CMD_RESET )) +MPT2_CMD_RESET ) || ioc->pci_error_recovery) goto retry_config; issue_host_reset =1 ; r = -EFAULT ;
drivers/scsi/mpt2sas/mpt2sas_ctl.c +2 -2
@@ -2156,7 +2156,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg) !ioc)return -ENODEV ; -if (ioc->shost_recovery) +if (ioc->shost_recovery || ioc->pci_error_recovery)return -EAGAIN ;if (_IOC_SIZE (cmd) ==sizeof (struct mpt2_ioctl_command )) {
@@ -2275,7 +2275,7 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)if (_ctl_verify_adapter (karg32.hdr.ioc_number, &ioc) ==-1 || !ioc)return -ENODEV ; -if (ioc->shost_recovery) +if (ioc->shost_recovery || ioc->pci_error_recovery)return -EAGAIN ;memset (&karg,0 ,sizeof (struct mpt2_ioctl_command ));
drivers/scsi/mpt2sas/mpt2sas_scsih.c +35 -12
137 lines not on this page · raw message
drivers/scsi/mpt2sas/mpt2sas_transport.c +4 -4
@@ -140,7 +140,7 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,u32 device_info;u32 ioc_status; -if (ioc->shost_recovery) { +if (ioc->shost_recovery || ioc->pci_error_recovery) {printk (MPT2SAS_INFO_FMT "%s: host reset in progress!\n" , __func__, ioc->name);return -EFAULT ;
@@ -302,7 +302,7 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,u64 *sas_address_le;u16 wait_state_count; -if (ioc->shost_recovery) { +if (ioc->shost_recovery || ioc->pci_error_recovery) {printk (MPT2SAS_INFO_FMT "%s: host reset in progress!\n" , __func__, ioc->name);return -EFAULT ;
@@ -894,7 +894,7 @@ mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,struct _sas_node *sas_node;struct _sas_phy *mpt2sas_phy; -if (ioc->shost_recovery) +if (ioc->shost_recovery || ioc->pci_error_recovery)return ;spin_lock_irqsave (&ioc->sas_node_lock, flags);
@@ -997,7 +997,7 @@ _transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc,u64 *sas_address_le;u16 wait_state_count; -if (ioc->shost_recovery) { +if (ioc->shost_recovery || ioc->pci_error_recovery) {printk (MPT2SAS_INFO_FMT "%s: host reset in progress!\n" , __func__, ioc->name);return -EFAULT ;
drivers/scsi/mpt2sas/mpt2sas_base.c
Quoted 18 lines · Eric Moore
fixes surrounding PCIe enhanced error handling:
(1) We need to reject all request generated internaly inside the driver as well as request arriving from the scsi mid layer when PCIe EEH is active. The fix is to add a per adapter flag called
pci_error_recoverywhich is checked thru out the driver when request are generated.(2) We don't need to call the
pci_driver->removedirectly from the PCIe callbacks becuase its already called from the PCIe EEH code. In its place we are shutting down the watchdog timer, and flushing back all pending IO.(3) We need to save and restore the pci state across PCIe EEH handling.
Signed-off-by Eric Moore <[email protected]>drivers/scsi/mpt2sas/mpt2sas_base.c +0
-0
Will you watch this type of thing, please? This changes all the file modes to executable. Linus particularly watches for this and will go into a kill frenzy if he sees it.
I've fixed it up this time.
James