提交 b37987e8 编写于 作者: H Hariprasad Shenai 提交者: David S. Miller

cxgb4: Disable interrupts and napi before unregistering netdev

Disable interrupts and quiesce rx before unregistering net device to avoid crash
while unloading driver when traffic is flowing through.

Based on original work by Shameem Khalid <shameem@chelsio.com>
Signed-off-by: NHariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 4b8e27a8
...@@ -934,6 +934,21 @@ static void quiesce_rx(struct adapter *adap) ...@@ -934,6 +934,21 @@ static void quiesce_rx(struct adapter *adap)
} }
} }
/* Disable interrupt and napi handler */
static void disable_interrupts(struct adapter *adap)
{
if (adap->flags & FULL_INIT_DONE) {
t4_intr_disable(adap);
if (adap->flags & USING_MSIX) {
free_msix_queue_irqs(adap);
free_irq(adap->msix_info[0].vec, adap);
} else {
free_irq(adap->pdev->irq, adap);
}
quiesce_rx(adap);
}
}
/* /*
* Enable NAPI scheduling and interrupt generation for all Rx queues. * Enable NAPI scheduling and interrupt generation for all Rx queues.
*/ */
...@@ -4257,19 +4272,12 @@ static int cxgb_up(struct adapter *adap) ...@@ -4257,19 +4272,12 @@ static int cxgb_up(struct adapter *adap)
static void cxgb_down(struct adapter *adapter) static void cxgb_down(struct adapter *adapter)
{ {
t4_intr_disable(adapter);
cancel_work_sync(&adapter->tid_release_task); cancel_work_sync(&adapter->tid_release_task);
cancel_work_sync(&adapter->db_full_task); cancel_work_sync(&adapter->db_full_task);
cancel_work_sync(&adapter->db_drop_task); cancel_work_sync(&adapter->db_drop_task);
adapter->tid_release_task_busy = false; adapter->tid_release_task_busy = false;
adapter->tid_release_head = NULL; adapter->tid_release_head = NULL;
if (adapter->flags & USING_MSIX) {
free_msix_queue_irqs(adapter);
free_irq(adapter->msix_info[0].vec, adapter);
} else
free_irq(adapter->pdev->irq, adapter);
quiesce_rx(adapter);
t4_sge_stop(adapter); t4_sge_stop(adapter);
t4_free_sge_resources(adapter); t4_free_sge_resources(adapter);
adapter->flags &= ~FULL_INIT_DONE; adapter->flags &= ~FULL_INIT_DONE;
...@@ -5591,6 +5599,7 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev, ...@@ -5591,6 +5599,7 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev,
netif_carrier_off(dev); netif_carrier_off(dev);
} }
spin_unlock(&adap->stats_lock); spin_unlock(&adap->stats_lock);
disable_interrupts(adap);
if (adap->flags & FULL_INIT_DONE) if (adap->flags & FULL_INIT_DONE)
cxgb_down(adap); cxgb_down(adap);
rtnl_unlock(); rtnl_unlock();
...@@ -6304,6 +6313,8 @@ static void remove_one(struct pci_dev *pdev) ...@@ -6304,6 +6313,8 @@ static void remove_one(struct pci_dev *pdev)
if (is_offload(adapter)) if (is_offload(adapter))
detach_ulds(adapter); detach_ulds(adapter);
disable_interrupts(adapter);
for_each_port(adapter, i) for_each_port(adapter, i)
if (adapter->port[i]->reg_state == NETREG_REGISTERED) if (adapter->port[i]->reg_state == NETREG_REGISTERED)
unregister_netdev(adapter->port[i]); unregister_netdev(adapter->port[i]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册