aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2014-01-22 23:27:34 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-23 16:21:03 -0500
commit144be3d9f72fca538871b69b1f4c4af6f39d562a (patch)
tree53a4dd4093b834ce4eb4ef0ac3e421f20bf791cf /drivers/net
parent0cd8f9cc0654c06adde353c6532114c5f53a18e8 (diff)
net/cxgb4: Avoid disabling PCI device for towice
If we have EEH error happens to the adapter and we have to remove it from the system for some reasons (e.g. more than 5 EEH errors detected from the device in last hour), the adapter will be disabled for towice separately by eeh_err_detected() and remove_one(), which will incur following unexpected backtrace. The patch tries to avoid it. WARNING: at drivers/pci/pci.c:1431 CPU: 12 PID: 121 Comm: eehd Not tainted 3.13.0-rc7+ #1 task: c0000001823a3780 ti: c00000018240c000 task.ti: c00000018240c000 NIP: c0000000003c1e40 LR: c0000000003c1e3c CTR: 0000000001764c5c REGS: c00000018240f470 TRAP: 0700 Not tainted (3.13.0-rc7+) MSR: 8000000000029032 <SF,EE,ME,IR,DR,RI> CR: 28000024 XER: 00000004 CFAR: c000000000706528 SOFTE: 1 GPR00: c0000000003c1e3c c00000018240f6f0 c0000000010fe1f8 0000000000000035 GPR04: 0000000000000000 0000000000000000 00000000003ae509 0000000000000000 GPR08: 000000000000346f 0000000000000000 0000000000000000 0000000000003fef GPR12: 0000000028000022 c00000000ec93000 c0000000000c11b0 c000000184ac3e40 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR24: 0000000000000000 c0000000009398d8 c00000000101f9c0 c0000001860ae000 GPR28: c000000182ba0000 00000000000001f0 c0000001860ae6f8 c0000001860ae000 NIP [c0000000003c1e40] .pci_disable_device+0xd0/0xf0 LR [c0000000003c1e3c] .pci_disable_device+0xcc/0xf0 Call Trace: [c0000000003c1e3c] .pci_disable_device+0xcc/0xf0 (unreliable) [d0000000073881c4] .remove_one+0x174/0x320 [cxgb4] [c0000000003c57e0] .pci_device_remove+0x60/0x100 [c00000000046396c] .__device_release_driver+0x9c/0x120 [c000000000463a20] .device_release_driver+0x30/0x60 [c0000000003bcdb4] .pci_stop_bus_device+0x94/0xd0 [c0000000003bcf48] .pci_stop_and_remove_bus_device+0x18/0x30 [c00000000003f548] .pcibios_remove_pci_devices+0xa8/0x140 [c000000000035c00] .eeh_handle_normal_event+0xa0/0x3c0 [c000000000035f50] .eeh_handle_event+0x30/0x2b0 [c0000000000362c4] .eeh_event_handler+0xf4/0x1b0 [c0000000000c12b8] .kthread+0x108/0x130 [c00000000000a168] .ret_from_kernel_thread+0x5c/0x74 Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h5
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c23
2 files changed, 21 insertions, 7 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 16782b2cff49..1f4b9b30b9ed 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -387,8 +387,9 @@ struct work_struct;
387 387
388enum { /* adapter flags */ 388enum { /* adapter flags */
389 FULL_INIT_DONE = (1 << 0), 389 FULL_INIT_DONE = (1 << 0),
390 USING_MSI = (1 << 1), 390 DEV_ENABLED = (1 << 1),
391 USING_MSIX = (1 << 2), 391 USING_MSI = (1 << 2),
392 USING_MSIX = (1 << 3),
392 FW_OK = (1 << 4), 393 FW_OK = (1 << 4),
393 RSS_TNLALLLOOKUP = (1 << 5), 394 RSS_TNLALLLOOKUP = (1 << 5),
394 USING_SOFT_PARAMS = (1 << 6), 395 USING_SOFT_PARAMS = (1 << 6),
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index fff02ed1295e..c8eafbf1f51d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -5505,7 +5505,10 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev,
5505 if (adap->flags & FULL_INIT_DONE) 5505 if (adap->flags & FULL_INIT_DONE)
5506 cxgb_down(adap); 5506 cxgb_down(adap);
5507 rtnl_unlock(); 5507 rtnl_unlock();
5508 pci_disable_device(pdev); 5508 if ((adap->flags & DEV_ENABLED)) {
5509 pci_disable_device(pdev);
5510 adap->flags &= ~DEV_ENABLED;
5511 }
5509out: return state == pci_channel_io_perm_failure ? 5512out: return state == pci_channel_io_perm_failure ?
5510 PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; 5513 PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
5511} 5514}
@@ -5522,9 +5525,13 @@ static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev)
5522 return PCI_ERS_RESULT_RECOVERED; 5525 return PCI_ERS_RESULT_RECOVERED;
5523 } 5526 }
5524 5527
5525 if (pci_enable_device(pdev)) { 5528 if (!(adap->flags & DEV_ENABLED)) {
5526 dev_err(&pdev->dev, "cannot reenable PCI device after reset\n"); 5529 if (pci_enable_device(pdev)) {
5527 return PCI_ERS_RESULT_DISCONNECT; 5530 dev_err(&pdev->dev, "Cannot reenable PCI "
5531 "device after reset\n");
5532 return PCI_ERS_RESULT_DISCONNECT;
5533 }
5534 adap->flags |= DEV_ENABLED;
5528 } 5535 }
5529 5536
5530 pci_set_master(pdev); 5537 pci_set_master(pdev);
@@ -5910,6 +5917,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
5910 goto out_disable_device; 5917 goto out_disable_device;
5911 } 5918 }
5912 5919
5920 /* PCI device has been enabled */
5921 adapter->flags |= DEV_ENABLED;
5922
5913 adapter->regs = pci_ioremap_bar(pdev, 0); 5923 adapter->regs = pci_ioremap_bar(pdev, 0);
5914 if (!adapter->regs) { 5924 if (!adapter->regs) {
5915 dev_err(&pdev->dev, "cannot map device registers\n"); 5925 dev_err(&pdev->dev, "cannot map device registers\n");
@@ -6145,7 +6155,10 @@ static void remove_one(struct pci_dev *pdev)
6145 iounmap(adapter->bar2); 6155 iounmap(adapter->bar2);
6146 kfree(adapter); 6156 kfree(adapter);
6147 pci_disable_pcie_error_reporting(pdev); 6157 pci_disable_pcie_error_reporting(pdev);
6148 pci_disable_device(pdev); 6158 if ((adapter->flags & DEV_ENABLED)) {
6159 pci_disable_device(pdev);
6160 adapter->flags &= ~DEV_ENABLED;
6161 }
6149 pci_release_regions(pdev); 6162 pci_release_regions(pdev);
6150 } else 6163 } else
6151 pci_release_regions(pdev); 6164 pci_release_regions(pdev);