Loading include/linux/netdevice.h +5 −0 Original line number Diff line number Diff line Loading @@ -2108,6 +2108,7 @@ void dev_disable_lro(struct net_device *dev); int dev_loopback_xmit(struct sk_buff *newskb); int dev_queue_xmit(struct sk_buff *skb); int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv); int dev_queue_xmit_list(struct sk_buff *skb); int register_netdevice(struct net_device *dev); void unregister_netdevice_queue(struct net_device *dev, struct list_head *head); void unregister_netdevice_many(struct list_head *head); Loading Loading @@ -2879,6 +2880,10 @@ int dev_get_phys_port_id(struct net_device *dev, struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev); struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq, int *ret); struct sk_buff *dev_hard_start_xmit_list(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq, int *ret); int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb); int dev_forward_skb(struct net_device *dev, struct sk_buff *skb); bool is_skb_forwardable(struct net_device *dev, struct sk_buff *skb); Loading net/core/dev.c +69 −4 Original line number Diff line number Diff line Loading @@ -2631,6 +2631,37 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev, return rc; } static int xmit_list(struct sk_buff *list, struct net_device *dev, struct netdev_queue *txq) { unsigned int len; int rc; struct sk_buff *skb = list, *head = list; /* Call the taps for individual skb's in the list. */ if (!list_empty(&ptype_all)) { while (skb) { struct sk_buff *next = skb->next; skb->next = NULL; dev_queue_xmit_nit(skb, dev); skb = next; /* Keep the original list intact. */ head->next = skb; head = head->next; } } len = list->len; trace_net_dev_start_xmit(list, dev); rc = netdev_start_xmit(list, dev, txq, false); trace_net_dev_xmit(list, rc, dev, len); return rc; } struct sk_buff *dev_hard_start_xmit(struct sk_buff *first, struct net_device *dev, struct netdev_queue *txq, int *ret) { Loading Loading @@ -2659,6 +2690,25 @@ out: return skb; } struct sk_buff *dev_hard_start_xmit_list(struct sk_buff *first, struct net_device *dev, struct netdev_queue *txq, int *ret) { struct sk_buff *skb = first; int rc = NETDEV_TX_OK; if (skb) { rc = xmit_list(skb, dev, txq); if (unlikely(!dev_xmit_complete(rc))) goto out; skb = NULL; } out: *ret = rc; return skb; } static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb, netdev_features_t features) { Loading Loading @@ -2879,6 +2929,7 @@ EXPORT_SYMBOL(dev_loopback_xmit); * __dev_queue_xmit - transmit a buffer * @skb: buffer to transmit * @accel_priv: private data used for L2 forwarding offload * @skb_list: Boolean used for skb list processing. * * Queue a buffer for transmission to a network device. The caller must * have set the device and priority and built the buffer before calling Loading @@ -2901,7 +2952,8 @@ EXPORT_SYMBOL(dev_loopback_xmit); * the BH enable code must have IRQs enabled so that it will not deadlock. * --BLG */ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv, bool skb_list) { struct net_device *dev = skb->dev; struct netdev_queue *txq; Loading Loading @@ -2968,7 +3020,14 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) if (!netif_xmit_stopped(txq)) { __this_cpu_inc(xmit_recursion); skb = dev_hard_start_xmit(skb, dev, txq, &rc); if (likely(!skb_list)) skb = dev_hard_start_xmit(skb, dev, txq, &rc); else skb = dev_hard_start_xmit_list(skb, dev, txq, &rc); __this_cpu_dec(xmit_recursion); if (dev_xmit_complete(rc)) { HARD_TX_UNLOCK(dev, txq); Loading Loading @@ -3002,16 +3061,22 @@ out: int dev_queue_xmit(struct sk_buff *skb) { return __dev_queue_xmit(skb, NULL); return __dev_queue_xmit(skb, NULL, false); } EXPORT_SYMBOL(dev_queue_xmit); int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv) { return __dev_queue_xmit(skb, accel_priv); return __dev_queue_xmit(skb, accel_priv, false); } EXPORT_SYMBOL(dev_queue_xmit_accel); int dev_queue_xmit_list(struct sk_buff *skb) { return __dev_queue_xmit(skb, NULL, true); } EXPORT_SYMBOL(dev_queue_xmit_list); /*======================================================================= Receiver routines Loading net/sched/sch_generic.c +7 −2 Original line number Diff line number Diff line Loading @@ -161,8 +161,13 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, if (skb) { HARD_TX_LOCK(dev, txq, smp_processor_id()); if (!netif_xmit_frozen_or_stopped(txq)) if (!netif_xmit_frozen_or_stopped(txq)) { if (unlikely(skb->fast_forwarded)) skb = dev_hard_start_xmit_list(skb, dev, txq, &ret); else skb = dev_hard_start_xmit(skb, dev, txq, &ret); } HARD_TX_UNLOCK(dev, txq); } Loading Loading
include/linux/netdevice.h +5 −0 Original line number Diff line number Diff line Loading @@ -2108,6 +2108,7 @@ void dev_disable_lro(struct net_device *dev); int dev_loopback_xmit(struct sk_buff *newskb); int dev_queue_xmit(struct sk_buff *skb); int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv); int dev_queue_xmit_list(struct sk_buff *skb); int register_netdevice(struct net_device *dev); void unregister_netdevice_queue(struct net_device *dev, struct list_head *head); void unregister_netdevice_many(struct list_head *head); Loading Loading @@ -2879,6 +2880,10 @@ int dev_get_phys_port_id(struct net_device *dev, struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev); struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq, int *ret); struct sk_buff *dev_hard_start_xmit_list(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq, int *ret); int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb); int dev_forward_skb(struct net_device *dev, struct sk_buff *skb); bool is_skb_forwardable(struct net_device *dev, struct sk_buff *skb); Loading
net/core/dev.c +69 −4 Original line number Diff line number Diff line Loading @@ -2631,6 +2631,37 @@ static int xmit_one(struct sk_buff *skb, struct net_device *dev, return rc; } static int xmit_list(struct sk_buff *list, struct net_device *dev, struct netdev_queue *txq) { unsigned int len; int rc; struct sk_buff *skb = list, *head = list; /* Call the taps for individual skb's in the list. */ if (!list_empty(&ptype_all)) { while (skb) { struct sk_buff *next = skb->next; skb->next = NULL; dev_queue_xmit_nit(skb, dev); skb = next; /* Keep the original list intact. */ head->next = skb; head = head->next; } } len = list->len; trace_net_dev_start_xmit(list, dev); rc = netdev_start_xmit(list, dev, txq, false); trace_net_dev_xmit(list, rc, dev, len); return rc; } struct sk_buff *dev_hard_start_xmit(struct sk_buff *first, struct net_device *dev, struct netdev_queue *txq, int *ret) { Loading Loading @@ -2659,6 +2690,25 @@ out: return skb; } struct sk_buff *dev_hard_start_xmit_list(struct sk_buff *first, struct net_device *dev, struct netdev_queue *txq, int *ret) { struct sk_buff *skb = first; int rc = NETDEV_TX_OK; if (skb) { rc = xmit_list(skb, dev, txq); if (unlikely(!dev_xmit_complete(rc))) goto out; skb = NULL; } out: *ret = rc; return skb; } static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb, netdev_features_t features) { Loading Loading @@ -2879,6 +2929,7 @@ EXPORT_SYMBOL(dev_loopback_xmit); * __dev_queue_xmit - transmit a buffer * @skb: buffer to transmit * @accel_priv: private data used for L2 forwarding offload * @skb_list: Boolean used for skb list processing. * * Queue a buffer for transmission to a network device. The caller must * have set the device and priority and built the buffer before calling Loading @@ -2901,7 +2952,8 @@ EXPORT_SYMBOL(dev_loopback_xmit); * the BH enable code must have IRQs enabled so that it will not deadlock. * --BLG */ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv, bool skb_list) { struct net_device *dev = skb->dev; struct netdev_queue *txq; Loading Loading @@ -2968,7 +3020,14 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) if (!netif_xmit_stopped(txq)) { __this_cpu_inc(xmit_recursion); skb = dev_hard_start_xmit(skb, dev, txq, &rc); if (likely(!skb_list)) skb = dev_hard_start_xmit(skb, dev, txq, &rc); else skb = dev_hard_start_xmit_list(skb, dev, txq, &rc); __this_cpu_dec(xmit_recursion); if (dev_xmit_complete(rc)) { HARD_TX_UNLOCK(dev, txq); Loading Loading @@ -3002,16 +3061,22 @@ out: int dev_queue_xmit(struct sk_buff *skb) { return __dev_queue_xmit(skb, NULL); return __dev_queue_xmit(skb, NULL, false); } EXPORT_SYMBOL(dev_queue_xmit); int dev_queue_xmit_accel(struct sk_buff *skb, void *accel_priv) { return __dev_queue_xmit(skb, accel_priv); return __dev_queue_xmit(skb, accel_priv, false); } EXPORT_SYMBOL(dev_queue_xmit_accel); int dev_queue_xmit_list(struct sk_buff *skb) { return __dev_queue_xmit(skb, NULL, true); } EXPORT_SYMBOL(dev_queue_xmit_list); /*======================================================================= Receiver routines Loading
net/sched/sch_generic.c +7 −2 Original line number Diff line number Diff line Loading @@ -161,8 +161,13 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, if (skb) { HARD_TX_LOCK(dev, txq, smp_processor_id()); if (!netif_xmit_frozen_or_stopped(txq)) if (!netif_xmit_frozen_or_stopped(txq)) { if (unlikely(skb->fast_forwarded)) skb = dev_hard_start_xmit_list(skb, dev, txq, &ret); else skb = dev_hard_start_xmit(skb, dev, txq, &ret); } HARD_TX_UNLOCK(dev, txq); } Loading