Commit 08baf561 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

net: txq_trans_update() helper

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: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 65ac8851
...@@ -1674,6 +1674,12 @@ static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) ...@@ -1674,6 +1674,12 @@ static inline void __netif_tx_unlock_bh(struct netdev_queue *txq)
spin_unlock_bh(&txq->_xmit_lock); 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 * netif_tx_lock - grab network device transmit lock
* @dev: network device * @dev: network device
......
...@@ -1698,6 +1698,8 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, ...@@ -1698,6 +1698,8 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
skb->dst = NULL; skb->dst = NULL;
} }
rc = ops->ndo_start_xmit(skb, dev); rc = ops->ndo_start_xmit(skb, dev);
if (rc == 0)
txq_trans_update(txq);
/* /*
* TODO: if skb_orphan() was called by * TODO: if skb_orphan() was called by
* dev->hard_start_xmit() (for example, the unmodified * dev->hard_start_xmit() (for example, the unmodified
...@@ -1727,6 +1729,7 @@ gso: ...@@ -1727,6 +1729,7 @@ gso:
skb->next = nskb; skb->next = nskb;
return rc; return rc;
} }
txq_trans_update(txq);
if (unlikely(netif_tx_queue_stopped(txq) && skb->next)) if (unlikely(netif_tx_queue_stopped(txq) && skb->next))
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} while (skb->next); } while (skb->next);
......
...@@ -302,8 +302,11 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) ...@@ -302,8 +302,11 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
tries > 0; --tries) { tries > 0; --tries) {
if (__netif_tx_trylock(txq)) { if (__netif_tx_trylock(txq)) {
if (!netif_tx_queue_stopped(txq)) if (!netif_tx_queue_stopped(txq)) {
status = ops->ndo_start_xmit(skb, dev); status = ops->ndo_start_xmit(skb, dev);
if (status == NETDEV_TX_OK)
txq_trans_update(txq);
}
__netif_tx_unlock(txq); __netif_tx_unlock(txq);
if (status == NETDEV_TX_OK) if (status == NETDEV_TX_OK)
......
...@@ -3438,6 +3438,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev) ...@@ -3438,6 +3438,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
retry_now: retry_now:
ret = (*xmit)(pkt_dev->skb, odev); ret = (*xmit)(pkt_dev->skb, odev);
if (likely(ret == NETDEV_TX_OK)) { if (likely(ret == NETDEV_TX_OK)) {
txq_trans_update(txq);
pkt_dev->last_ok = 1; pkt_dev->last_ok = 1;
pkt_dev->sofar++; pkt_dev->sofar++;
pkt_dev->seq_num++; pkt_dev->seq_num++;
......
...@@ -308,6 +308,7 @@ restart: ...@@ -308,6 +308,7 @@ restart:
if (!netif_tx_queue_stopped(slave_txq) && if (!netif_tx_queue_stopped(slave_txq) &&
!netif_tx_queue_frozen(slave_txq) && !netif_tx_queue_frozen(slave_txq) &&
slave_ops->ndo_start_xmit(skb, slave) == 0) { slave_ops->ndo_start_xmit(skb, slave) == 0) {
txq_trans_update(slave_txq);
__netif_tx_unlock(slave_txq); __netif_tx_unlock(slave_txq);
master->slaves = NEXT_SLAVE(q); master->slaves = NEXT_SLAVE(q);
netif_wake_queue(dev); netif_wake_queue(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment