net: Optimize hard_start_xmit() return checking
Recent changes in the TX error propagation require additional checking and masking of values returned from hard_start_xmit(), mainly to separate cases where skb was consumed. This aim can be simplified by changing the order of NETDEV_TX and NET_XMIT codes, because the latter are treated similarly to negative (ERRNO) values. After this change much simpler dev_xmit_complete() is also used in sch_direct_xmit(), so it is moved to netdevice.h. Additionally NET_RX definitions in netdevice.h are moved up from between TX codes to avoid confusion while reading the TX comment. Signed-off-by: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
此提交包含在:
@@ -119,39 +119,26 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
|
||||
spin_unlock(root_lock);
|
||||
|
||||
HARD_TX_LOCK(dev, txq, smp_processor_id());
|
||||
if (!netif_tx_queue_stopped(txq) &&
|
||||
!netif_tx_queue_frozen(txq)) {
|
||||
if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
|
||||
ret = dev_hard_start_xmit(skb, dev, txq);
|
||||
|
||||
/* an error implies that the skb was consumed */
|
||||
if (ret < 0)
|
||||
ret = NETDEV_TX_OK;
|
||||
/* all NET_XMIT codes map to NETDEV_TX_OK */
|
||||
ret &= ~NET_XMIT_MASK;
|
||||
}
|
||||
HARD_TX_UNLOCK(dev, txq);
|
||||
|
||||
spin_lock(root_lock);
|
||||
|
||||
switch (ret) {
|
||||
case NETDEV_TX_OK:
|
||||
/* Driver sent out skb successfully */
|
||||
if (dev_xmit_complete(ret)) {
|
||||
/* Driver sent out skb successfully or skb was consumed */
|
||||
ret = qdisc_qlen(q);
|
||||
break;
|
||||
|
||||
case NETDEV_TX_LOCKED:
|
||||
} else if (ret == NETDEV_TX_LOCKED) {
|
||||
/* Driver try lock failed */
|
||||
ret = handle_dev_cpu_collision(skb, txq, q);
|
||||
break;
|
||||
|
||||
default:
|
||||
} else {
|
||||
/* Driver returned NETDEV_TX_BUSY - requeue skb */
|
||||
if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
|
||||
printk(KERN_WARNING "BUG %s code %d qlen %d\n",
|
||||
dev->name, ret, q->q.qlen);
|
||||
|
||||
ret = dev_requeue_skb(skb, q);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret && (netif_tx_queue_stopped(txq) ||
|
||||
|
新增問題並參考
封鎖使用者