We would like to get rid of netdev->trans_start = jiffies; that about all net
drivers have to use in their start_xmit() function, and use txq->trans_start
instead.
This can be done generically in core network, as suggested by David.
Some devices, (particularly loopback) dont need trans_start update, because
they dont have transmit watchdog. We could add a new device flag, or rely
on fact that txq->tran_start can be updated is txq->xmit_lock_owner is
different than -1. Use a helper function to hide our choice.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
        spin_unlock_bh(&txq->_xmit_lock);
 }
 
+static inline void txq_trans_update(struct netdev_queue *txq)
+{
+       if (txq->xmit_lock_owner != -1)
+               txq->trans_start = jiffies;
+}
+
 /**
  *     netif_tx_lock - grab network device transmit lock
  *     @dev: network device
 
                        skb->dst = NULL;
                }
                rc = ops->ndo_start_xmit(skb, dev);
+               if (rc == 0)
+                       txq_trans_update(txq);
                /*
                 * TODO: if skb_orphan() was called by
                 * dev->hard_start_xmit() (for example, the unmodified
                        skb->next = nskb;
                        return rc;
                }
+               txq_trans_update(txq);
                if (unlikely(netif_tx_queue_stopped(txq) && skb->next))
                        return NETDEV_TX_BUSY;
        } while (skb->next);
 
                for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
                     tries > 0; --tries) {
                        if (__netif_tx_trylock(txq)) {
-                               if (!netif_tx_queue_stopped(txq))
+                               if (!netif_tx_queue_stopped(txq)) {
                                        status = ops->ndo_start_xmit(skb, dev);
+                                       if (status == NETDEV_TX_OK)
+                                               txq_trans_update(txq);
+                               }
                                __netif_tx_unlock(txq);
 
                                if (status == NETDEV_TX_OK)
 
              retry_now:
                ret = (*xmit)(pkt_dev->skb, odev);
                if (likely(ret == NETDEV_TX_OK)) {
+                       txq_trans_update(txq);
                        pkt_dev->last_ok = 1;
                        pkt_dev->sofar++;
                        pkt_dev->seq_num++;
 
                                if (!netif_tx_queue_stopped(slave_txq) &&
                                    !netif_tx_queue_frozen(slave_txq) &&
                                    slave_ops->ndo_start_xmit(skb, slave) == 0) {
+                                       txq_trans_update(slave_txq);
                                        __netif_tx_unlock(slave_txq);
                                        master->slaves = NEXT_SLAVE(q);
                                        netif_wake_queue(dev);