aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2014-03-27 18:37:28 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-29 17:58:37 -0400
commit944e294857033dbe519a136cad05dc4e2570874e (patch)
treed7d3f8a8890fc8ad488cc6e1456287416850d94d /net
parenta8779ec1c5e60548b7b661a8d74a8cecf7775690 (diff)
netpoll: Only call ndo_start_xmit from a single place
Factor out the code that needs to surround ndo_start_xmit from netpoll_send_skb_on_dev into netpoll_start_xmit. It is an unfortunate fact that as the netpoll code has been maintained the primary call site ndo_start_xmit learned how to handle vlans and timestamps but the second call of ndo_start_xmit in queue_process did not. With the introduction of netpoll_start_xmit this associated logic now happens at both call sites of ndo_start_xmit and should make it easy for that to continue into the future. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/netpoll.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 2c6379da295c..e2492d176ae7 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -69,6 +69,37 @@ module_param(carrier_timeout, uint, 0644);
69#define np_notice(np, fmt, ...) \ 69#define np_notice(np, fmt, ...) \
70 pr_notice("%s: " fmt, np->name, ##__VA_ARGS__) 70 pr_notice("%s: " fmt, np->name, ##__VA_ARGS__)
71 71
72static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev,
73 struct netdev_queue *txq)
74{
75 const struct net_device_ops *ops = dev->netdev_ops;
76 int status = NETDEV_TX_OK;
77 netdev_features_t features;
78
79 features = netif_skb_features(skb);
80
81 if (vlan_tx_tag_present(skb) &&
82 !vlan_hw_offload_capable(features, skb->vlan_proto)) {
83 skb = __vlan_put_tag(skb, skb->vlan_proto,
84 vlan_tx_tag_get(skb));
85 if (unlikely(!skb)) {
86 /* This is actually a packet drop, but we
87 * don't want the code that calls this
88 * function to try and operate on a NULL skb.
89 */
90 goto out;
91 }
92 skb->vlan_tci = 0;
93 }
94
95 status = ops->ndo_start_xmit(skb, dev);
96 if (status == NETDEV_TX_OK)
97 txq_trans_update(txq);
98
99out:
100 return status;
101}
102
72static void queue_process(struct work_struct *work) 103static void queue_process(struct work_struct *work)
73{ 104{
74 struct netpoll_info *npinfo = 105 struct netpoll_info *npinfo =
@@ -78,7 +109,6 @@ static void queue_process(struct work_struct *work)
78 109
79 while ((skb = skb_dequeue(&npinfo->txq))) { 110 while ((skb = skb_dequeue(&npinfo->txq))) {
80 struct net_device *dev = skb->dev; 111 struct net_device *dev = skb->dev;
81 const struct net_device_ops *ops = dev->netdev_ops;
82 struct netdev_queue *txq; 112 struct netdev_queue *txq;
83 113
84 if (!netif_device_present(dev) || !netif_running(dev)) { 114 if (!netif_device_present(dev) || !netif_running(dev)) {
@@ -91,7 +121,7 @@ static void queue_process(struct work_struct *work)
91 local_irq_save(flags); 121 local_irq_save(flags);
92 __netif_tx_lock(txq, smp_processor_id()); 122 __netif_tx_lock(txq, smp_processor_id());
93 if (netif_xmit_frozen_or_stopped(txq) || 123 if (netif_xmit_frozen_or_stopped(txq) ||
94 ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) { 124 netpoll_start_xmit(skb, dev, txq) != NETDEV_TX_OK) {
95 skb_queue_head(&npinfo->txq, skb); 125 skb_queue_head(&npinfo->txq, skb);
96 __netif_tx_unlock(txq); 126 __netif_tx_unlock(txq);
97 local_irq_restore(flags); 127 local_irq_restore(flags);
@@ -295,7 +325,6 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
295{ 325{
296 int status = NETDEV_TX_BUSY; 326 int status = NETDEV_TX_BUSY;
297 unsigned long tries; 327 unsigned long tries;
298 const struct net_device_ops *ops = dev->netdev_ops;
299 /* It is up to the caller to keep npinfo alive. */ 328 /* It is up to the caller to keep npinfo alive. */
300 struct netpoll_info *npinfo; 329 struct netpoll_info *npinfo;
301 330
@@ -317,27 +346,9 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
317 for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; 346 for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
318 tries > 0; --tries) { 347 tries > 0; --tries) {
319 if (__netif_tx_trylock(txq)) { 348 if (__netif_tx_trylock(txq)) {
320 if (!netif_xmit_stopped(txq)) { 349 if (!netif_xmit_stopped(txq))
321 if (vlan_tx_tag_present(skb) && 350 status = netpoll_start_xmit(skb, dev, txq);
322 !vlan_hw_offload_capable(netif_skb_features(skb), 351
323 skb->vlan_proto)) {
324 skb = __vlan_put_tag(skb, skb->vlan_proto, vlan_tx_tag_get(skb));
325 if (unlikely(!skb)) {
326 /* This is actually a packet drop, but we
327 * don't want the code at the end of this
328 * function to try and re-queue a NULL skb.
329 */
330 status = NETDEV_TX_OK;
331 goto unlock_txq;
332 }
333 skb->vlan_tci = 0;
334 }
335
336 status = ops->ndo_start_xmit(skb, dev);
337 if (status == NETDEV_TX_OK)
338 txq_trans_update(txq);
339 }
340 unlock_txq:
341 __netif_tx_unlock(txq); 352 __netif_tx_unlock(txq);
342 353
343 if (status == NETDEV_TX_OK) 354 if (status == NETDEV_TX_OK)
@@ -353,7 +364,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
353 364
354 WARN_ONCE(!irqs_disabled(), 365 WARN_ONCE(!irqs_disabled(),
355 "netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n", 366 "netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n",
356 dev->name, ops->ndo_start_xmit); 367 dev->name, dev->netdev_ops->ndo_start_xmit);
357 368
358 } 369 }
359 370