aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Mason <jon.mason@exar.com>2010-12-10 09:02:59 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-10 19:08:23 -0500
commit2e41f6449c561e6e3f572e11d0f2240bd51104db (patch)
treeef85460cfe71e67cd76cc764c7f48ee88a8005ab
parentdc66daa9be40369ead5a4ee33c6bcfb44cb3c8ee (diff)
vxge: transmit timeout deadlock
Use a workqueue to handle the device reset during a transmit timeout, as there can be a deadlock during bringup. Also, set the netif carrier off before the watchdog reset is started to prevent the timeout from reoccurring while still processing the first. Signed-off-by: Jon Mason <jon.mason@exar.com> Signed-off-by: Ram Vepa <ram.vepa@exar.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxge/vxge-main.c19
-rw-r--r--drivers/net/vxge/vxge-main.h1
2 files changed, 15 insertions, 5 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index faebffb02d12..3ec80684cd5f 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -1606,12 +1606,16 @@ static int do_vxge_reset(struct vxgedev *vdev, int event)
1606 } 1606 }
1607 1607
1608 if (event == VXGE_LL_FULL_RESET) { 1608 if (event == VXGE_LL_FULL_RESET) {
1609 netif_carrier_off(vdev->ndev);
1610
1609 /* wait for all the vpath reset to complete */ 1611 /* wait for all the vpath reset to complete */
1610 for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { 1612 for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
1611 while (test_bit(vp_id, &vdev->vp_reset)) 1613 while (test_bit(vp_id, &vdev->vp_reset))
1612 msleep(50); 1614 msleep(50);
1613 } 1615 }
1614 1616
1617 netif_carrier_on(vdev->ndev);
1618
1615 /* if execution mode is set to debug, don't reset the adapter */ 1619 /* if execution mode is set to debug, don't reset the adapter */
1616 if (unlikely(vdev->exec_mode)) { 1620 if (unlikely(vdev->exec_mode)) {
1617 vxge_debug_init(VXGE_ERR, 1621 vxge_debug_init(VXGE_ERR,
@@ -1765,9 +1769,14 @@ out:
1765 * 1769 *
1766 * driver may reset the chip on events of serr, eccerr, etc 1770 * driver may reset the chip on events of serr, eccerr, etc
1767 */ 1771 */
1768static int vxge_reset(struct vxgedev *vdev) 1772static void vxge_reset(struct work_struct *work)
1769{ 1773{
1770 return do_vxge_reset(vdev, VXGE_LL_FULL_RESET); 1774 struct vxgedev *vdev = container_of(work, struct vxgedev, reset_task);
1775
1776 if (!netif_running(vdev->ndev))
1777 return;
1778
1779 do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
1771} 1780}
1772 1781
1773/** 1782/**
@@ -3111,8 +3120,7 @@ static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3111 * This function is triggered if the Tx Queue is stopped 3120 * This function is triggered if the Tx Queue is stopped
3112 * for a pre-defined amount of time when the Interface is still up. 3121 * for a pre-defined amount of time when the Interface is still up.
3113 */ 3122 */
3114static void 3123static void vxge_tx_watchdog(struct net_device *dev)
3115vxge_tx_watchdog(struct net_device *dev)
3116{ 3124{
3117 struct vxgedev *vdev; 3125 struct vxgedev *vdev;
3118 3126
@@ -3122,7 +3130,7 @@ vxge_tx_watchdog(struct net_device *dev)
3122 3130
3123 vdev->cric_err_event = VXGE_HW_EVENT_RESET_START; 3131 vdev->cric_err_event = VXGE_HW_EVENT_RESET_START;
3124 3132
3125 vxge_reset(vdev); 3133 schedule_work(&vdev->reset_task);
3126 vxge_debug_entryexit(VXGE_TRACE, 3134 vxge_debug_entryexit(VXGE_TRACE,
3127 "%s:%d Exiting...", __func__, __LINE__); 3135 "%s:%d Exiting...", __func__, __LINE__);
3128} 3136}
@@ -3324,6 +3332,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
3324 ndev->netdev_ops = &vxge_netdev_ops; 3332 ndev->netdev_ops = &vxge_netdev_ops;
3325 3333
3326 ndev->watchdog_timeo = VXGE_LL_WATCH_DOG_TIMEOUT; 3334 ndev->watchdog_timeo = VXGE_LL_WATCH_DOG_TIMEOUT;
3335 INIT_WORK(&vdev->reset_task, vxge_reset);
3327 3336
3328 vxge_initialize_ethtool_ops(ndev); 3337 vxge_initialize_ethtool_ops(ndev);
3329 3338
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 256d5b406a67..5746fedc356f 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -395,6 +395,7 @@ struct vxgedev {
395 u32 level_err; 395 u32 level_err;
396 u32 level_trace; 396 u32 level_trace;
397 char fw_version[VXGE_HW_FW_STRLEN]; 397 char fw_version[VXGE_HW_FW_STRLEN];
398 struct work_struct reset_task;
398}; 399};
399 400
400struct vxge_rx_priv { 401struct vxge_rx_priv {