Commit d1dd9119 authored by jbaron@akamai.com's avatar jbaron@akamai.com Committed by David S. Miller

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: default avatarJason Baron <jbaron@akamai.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4c979935
...@@ -407,7 +407,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) ...@@ -407,7 +407,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
const struct macvlan_dev *src; const struct macvlan_dev *src;
struct net_device *dev; struct net_device *dev;
unsigned int len = 0; unsigned int len = 0;
int ret = NET_RX_DROP; int ret;
rx_handler_result_t handle_res;
port = macvlan_port_get_rcu(skb->dev); port = macvlan_port_get_rcu(skb->dev);
if (is_multicast_ether_addr(eth->h_dest)) { 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,6 +424,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
vlan = src; vlan = src;
ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?: ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?:
netif_rx(skb); netif_rx(skb);
handle_res = RX_HANDLER_CONSUMED;
goto out; goto out;
} }
...@@ -448,17 +450,20 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) ...@@ -448,17 +450,20 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
} }
len = skb->len + ETH_HLEN; len = skb->len + ETH_HLEN;
skb = skb_share_check(skb, GFP_ATOMIC); skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb) if (!skb) {
ret = NET_RX_DROP;
handle_res = RX_HANDLER_CONSUMED;
goto out; goto out;
}
skb->dev = dev; skb->dev = dev;
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
ret = netif_rx(skb); ret = NET_RX_SUCCESS;
handle_res = RX_HANDLER_ANOTHER;
out: out:
macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false); macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false);
return RX_HANDLER_CONSUMED; return handle_res;
} }
static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment