From: Doug Ledford <dledford@redhat.com> Date: Fri, 3 Sep 2010 21:20:20 -0400 Subject: [net] cxgb3: don't flush workqueue if called from wq Message-id: <2cbc915fb574c4671a7771d82a149490d905fa09.1283548506.git.dledford@redhat.com> Patchwork-id: 28141 O-Subject: [Patch RHEL5.6 4/4] cxgb3: don't flush the workqueue if we are called from the workqueue Bugzilla: 630124 RH-Acked-by: David S. Miller <davem@redhat.com> RH-Acked-by: Neil Horman <nhorman@redhat.com> Related: bz630124 Signed-off-by: Doug Ledford <dledford@redhat.com> diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index ea533f8..2d78754 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1176,7 +1176,7 @@ irq_err: /* * Release resources when all the ports and offloading have been stopped. */ -static void cxgb_down(struct adapter *adapter) +static void cxgb_down(struct adapter *adapter, int on_wq) { t3_sge_stop(adapter); spin_lock_irq(&adapter->work_lock); /* sync with PHY intr task */ @@ -1185,7 +1185,8 @@ static void cxgb_down(struct adapter *adapter) free_irq_resources(adapter); quiesce_rx(adapter); - flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ + if (!on_wq) + flush_workqueue(cxgb3_wq);/* wait for external IRQ handler */ } static void schedule_chk_task(struct adapter *adap) @@ -1263,7 +1264,7 @@ static int offload_close(struct t3cdev *tdev) clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); if (!adapter->open_device_map) - cxgb_down(adapter); + cxgb_down(adapter, 0); cxgb3_offload_deactivate(adapter); return 0; @@ -1296,7 +1297,7 @@ static int cxgb_open(struct net_device *dev) return 0; } -static int cxgb_close(struct net_device *dev) +static int __cxgb_close(struct net_device *dev, int on_wq) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; @@ -1323,11 +1324,16 @@ static int cxgb_close(struct net_device *dev) cancel_delayed_work_sync(&adapter->adap_check_task); if (!adapter->open_device_map) - cxgb_down(adapter); + cxgb_down(adapter, on_wq); return 0; } +static int cxgb_close(struct net_device *dev) +{ + return __cxgb_close(dev, 0); +} + static struct net_device_stats *cxgb_get_stats(struct net_device *dev) { struct port_info *pi = netdev_priv(dev); @@ -2767,7 +2773,7 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id) spin_unlock(&adapter->work_lock); } -static int t3_adapter_error(struct adapter *adapter, int reset) +static int t3_adapter_error(struct adapter *adapter, int reset, int on_wq) { int i, ret = 0; @@ -2782,7 +2788,7 @@ static int t3_adapter_error(struct adapter *adapter, int reset) struct net_device *netdev = adapter->port[i]; if (netif_running(netdev)) - cxgb_close(netdev); + __cxgb_close(netdev, on_wq); } /* Stop SGE timers */ @@ -2852,7 +2858,7 @@ static void fatal_error_task(struct work_struct *work) int err = 0; rtnl_lock(); - err = t3_adapter_error(adapter, 1); + err = t3_adapter_error(adapter, 1, 1); if (!err) err = t3_reenable_adapter(adapter); if (!err) @@ -2902,7 +2908,7 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - ret = t3_adapter_error(adapter, 0); + ret = t3_adapter_error(adapter, 0, 0); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET;