Message ID | 20090417222117.8504.11164.stgit@speedy5 |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Divy Le Ray <divy@chelsio.com> Date: Fri, 17 Apr 2009 15:21:17 -0700 > The fatal error task can be scheduled while processing an offload packet > in NAPI context when the connection handle is bogus. this can race > with the ports being brought down and the cxgb3 workqueue being flushed. > Stop napi processing before flushing the work queue. > > The ULP drivers (iSCSI, iWARP) might also schedule a task on keventd_wk > while releasing a connection handle (cxgb3_offload.c::cxgb3_queue_tid_release()). > The driver however does not flush any work on keventd_wq while being unloaded. > This patch also fixes this. > > Also call cancel_delayed_work_sync in place of the the deprecated > cancel_rearming_delayed_workqueue. > > Signed-off-by: Divy Le Ray <divy@chelsio.com> Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 9fdfe0b..99b5032 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1117,8 +1117,8 @@ static void cxgb_down(struct adapter *adapter) spin_unlock_irq(&adapter->work_lock); free_irq_resources(adapter); - flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ quiesce_rx(adapter); + flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ } static void schedule_chk_task(struct adapter *adap) @@ -1187,6 +1187,9 @@ static int offload_close(struct t3cdev *tdev) sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); + /* Flush work scheduled while releasing TIDs */ + flush_scheduled_work(); + tdev->lldev = NULL; cxgb3_set_dummy_ops(tdev); t3_tp_set_offload_mode(adapter, 0); @@ -1247,8 +1250,7 @@ static int cxgb_close(struct net_device *dev) spin_unlock_irq(&adapter->work_lock); if (!(adapter->open_device_map & PORT_MASK)) - cancel_rearming_delayed_workqueue(cxgb3_wq, - &adapter->adap_check_task); + cancel_delayed_work_sync(&adapter->adap_check_task); if (!adapter->open_device_map) cxgb_down(adapter);