aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjbaron@akamai.com <jbaron@akamai.com>2014-10-09 23:13:31 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-10 15:09:47 -0400
commitd1dd911930885659420421cfe123957610c54299 (patch)
treeca97b979d908b286cc28449dfa887bbb9071ee58
parent4c9799359bc691becc888f97a4b5bb035cb206f9 (diff)
macvlan: optimize the receive path
The netif_rx() call on the fast path of macvlan_handle_frame() appears to be there to ensure that we properly throttle incoming packets. However, it would appear as though the proper throttling is already in place for all possible ingress paths, and that the call is redundant. If packets are arriving from the physical NIC, we've already throttled them by this point. Otherwise, if they are coming via macvlan_queue_xmit(), it calls either 'dev_forward_skb()', which ends up calling netif_rx_internal(), or else in the broadcast case, we are throttling via macvlan_broadcast_enqueue(). The test results below are from off the box to an lxc instance running macvlan. Once the tranactions/sec stop increasing, the cpu idle time has gone to 0. Results are from a quad core Intel E3-1270 V2@3.50GHz box with bnx2x 10G card. for i in {10,100,200,300,400,500}; do super_netperf $i -H $ip -t TCP_RR; done Average of 5 runs. trans/sec trans/sec (3.17-rc7-net-next) (3.17-rc7-net-next + this patch) ---------- ---------- 208101 211534 (+1.6%) 839493 850162 (+1.3%) 845071 844053 (-.12%) 816330 819623 (+.4%) 778700 789938 (+1.4%) 735984 754408 (+2.5%) Signed-off-by: Jason Baron <jbaron@akamai.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/macvlan.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index c7c58aff1ff7..29b3bb410781 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -407,7 +407,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
407 const struct macvlan_dev *src; 407 const struct macvlan_dev *src;
408 struct net_device *dev; 408 struct net_device *dev;
409 unsigned int len = 0; 409 unsigned int len = 0;
410 int ret = NET_RX_DROP; 410 int ret;
411 rx_handler_result_t handle_res;
411 412
412 port = macvlan_port_get_rcu(skb->dev); 413 port = macvlan_port_get_rcu(skb->dev);
413 if (is_multicast_ether_addr(eth->h_dest)) { 414 if (is_multicast_ether_addr(eth->h_dest)) {
@@ -423,6 +424,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
423 vlan = src; 424 vlan = src;
424 ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?: 425 ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?:
425 netif_rx(skb); 426 netif_rx(skb);
427 handle_res = RX_HANDLER_CONSUMED;
426 goto out; 428 goto out;
427 } 429 }
428 430
@@ -448,17 +450,20 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
448 } 450 }
449 len = skb->len + ETH_HLEN; 451 len = skb->len + ETH_HLEN;
450 skb = skb_share_check(skb, GFP_ATOMIC); 452 skb = skb_share_check(skb, GFP_ATOMIC);
451 if (!skb) 453 if (!skb) {
454 ret = NET_RX_DROP;
455 handle_res = RX_HANDLER_CONSUMED;
452 goto out; 456 goto out;
457 }
453 458
454 skb->dev = dev; 459 skb->dev = dev;
455 skb->pkt_type = PACKET_HOST; 460 skb->pkt_type = PACKET_HOST;
456 461
457 ret = netif_rx(skb); 462 ret = NET_RX_SUCCESS;
458 463 handle_res = RX_HANDLER_ANOTHER;
459out: 464out:
460 macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false); 465 macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false);
461 return RX_HANDLER_CONSUMED; 466 return handle_res;
462} 467}
463 468
464static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) 469static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)