Message ID | 20100708192125.GB15167@exar.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
From: Jon Mason <jon.mason@exar.com> Date: Thu, 8 Jul 2010 14:21:26 -0500 > @@ -968,8 +969,10 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) > VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN); > > vxge_hw_fifo_txdl_post(fifo_hw, dtr); > + > #ifdef NETIF_F_LLTX > - dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ > + txq = netdev_get_tx_queue(dev, vpath_no); > + txq->trans_start = jiffies; > #endif This comment was placed there not just for it's artistic value, you should heed what it's saying when making changes like this. NETIF_F_LLTX drivers cannot use the per-txq trans_start mechanism, because doing so is racy. The dev_watchdog() timer, which checks these ->trans_start values, can only synchornize with the driver by the traditional means, which is by taking the spinlock on the TX queue. This is bypassed by NETIF_F_LLTX drivers, so the driver can be in it's TX handler while the watchdog timer is trying to evaluate the trans_start state. This is one of a many reasons why NETIF_F_LLTX is a bad idea and you should convert your driver away from it. -- 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/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index e78703d..b8eed71 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -802,6 +802,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags = 0; int vpath_no = 0; int do_spin_tx_lock = 1; + struct netdev_queue *txq; vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", dev->name, __func__, __LINE__); @@ -968,8 +969,10 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN); vxge_hw_fifo_txdl_post(fifo_hw, dtr); + #ifdef NETIF_F_LLTX - dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ + txq = netdev_get_tx_queue(dev, vpath_no); + txq->trans_start = jiffies; #endif spin_unlock_irqrestore(&fifo->tx_lock, flags);