aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-03-27 11:38:30 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-28 16:49:48 -0400
commit43279500decad66ccdddacae7948a1d23be1bef6 (patch)
tree5832fb327c95c8bb04a0aca9fcba7690e17c4dea
parentb7d47ca2fdfd3b613b800c923553a8437dd8da40 (diff)
packet: respect devices with LLTX flag in direct xmit
Quite often it can be useful to test with dummy or similar devices as a blackhole sink for skbs. Such devices are only equipped with a single txq, but marked as NETIF_F_LLTX as they do not require locking their internal queues on xmit (or implement locking themselves). Therefore, rather use HARD_TX_{UN,}LOCK API, so that NETIF_F_LLTX will be respected. trafgen mmap/TX_RING example against dummy device with config foo: { fill(0xff, 64) } results in the following performance improvements for such scenarios on an ordinary Core i7/2.80GHz: Before: Performance counter stats for 'trafgen -i foo -o du0 -n100000000' (10 runs): 160,975,944,159 instructions:k # 0.55 insns per cycle ( +- 0.09% ) 293,319,390,278 cycles:k # 0.000 GHz ( +- 0.35% ) 192,501,104 branch-misses:k ( +- 1.63% ) 831 context-switches:k ( +- 9.18% ) 7 cpu-migrations:k ( +- 7.40% ) 69,382 cache-misses:k # 0.010 % of all cache refs ( +- 2.18% ) 671,552,021 cache-references:k ( +- 1.29% ) 22.856401569 seconds time elapsed ( +- 0.33% ) After: Performance counter stats for 'trafgen -i foo -o du0 -n100000000' (10 runs): 133,788,739,692 instructions:k # 0.92 insns per cycle ( +- 0.06% ) 145,853,213,256 cycles:k # 0.000 GHz ( +- 0.17% ) 59,867,100 branch-misses:k ( +- 4.72% ) 384 context-switches:k ( +- 3.76% ) 6 cpu-migrations:k ( +- 6.28% ) 70,304 cache-misses:k # 0.077 % of all cache refs ( +- 1.73% ) 90,879,408 cache-references:k ( +- 1.35% ) 11.719372413 seconds time elapsed ( +- 0.24% ) Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Cc: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/packet/af_packet.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 097a354ec8cd..01039d2b1695 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -243,40 +243,40 @@ static int packet_direct_xmit(struct sk_buff *skb)
243 const struct net_device_ops *ops = dev->netdev_ops; 243 const struct net_device_ops *ops = dev->netdev_ops;
244 netdev_features_t features; 244 netdev_features_t features;
245 struct netdev_queue *txq; 245 struct netdev_queue *txq;
246 int ret = NETDEV_TX_BUSY;
246 u16 queue_map; 247 u16 queue_map;
247 int ret;
248 248
249 if (unlikely(!netif_running(dev) || 249 if (unlikely(!netif_running(dev) ||
250 !netif_carrier_ok(dev))) { 250 !netif_carrier_ok(dev)))
251 kfree_skb(skb); 251 goto drop;
252 return NET_XMIT_DROP;
253 }
254 252
255 features = netif_skb_features(skb); 253 features = netif_skb_features(skb);
256 if (skb_needs_linearize(skb, features) && 254 if (skb_needs_linearize(skb, features) &&
257 __skb_linearize(skb)) { 255 __skb_linearize(skb))
258 kfree_skb(skb); 256 goto drop;
259 return NET_XMIT_DROP;
260 }
261 257
262 queue_map = skb_get_queue_mapping(skb); 258 queue_map = skb_get_queue_mapping(skb);
263 txq = netdev_get_tx_queue(dev, queue_map); 259 txq = netdev_get_tx_queue(dev, queue_map);
264 260
265 __netif_tx_lock_bh(txq); 261 local_bh_disable();
266 if (unlikely(netif_xmit_frozen_or_stopped(txq))) { 262
267 ret = NETDEV_TX_BUSY; 263 HARD_TX_LOCK(dev, txq, smp_processor_id());
268 kfree_skb(skb); 264 if (!netif_xmit_frozen_or_stopped(txq)) {
269 goto out; 265 ret = ops->ndo_start_xmit(skb, dev);
266 if (ret == NETDEV_TX_OK)
267 txq_trans_update(txq);
270 } 268 }
269 HARD_TX_UNLOCK(dev, txq);
271 270
272 ret = ops->ndo_start_xmit(skb, dev); 271 local_bh_enable();
273 if (likely(dev_xmit_complete(ret))) 272
274 txq_trans_update(txq); 273 if (!dev_xmit_complete(ret))
275 else
276 kfree_skb(skb); 274 kfree_skb(skb);
277out: 275
278 __netif_tx_unlock_bh(txq);
279 return ret; 276 return ret;
277drop:
278 kfree_skb(skb);
279 return NET_XMIT_DROP;
280} 280}
281 281
282static struct net_device *packet_cached_dev_get(struct packet_sock *po) 282static struct net_device *packet_cached_dev_get(struct packet_sock *po)