Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dev: Makes sure netif_rx() can be invoked in any context.

Dave suggested a while ago (eleven years by now) "Let's make netif_rx()
work in all contexts and get rid of netif_rx_ni()". Eric agreed and
pointed out that modern devices should use netif_receive_skb() to avoid
the overhead.
In the meantime someone added another variant, netif_rx_any_context(),
which behaves as suggested.

netif_rx() must be invoked with disabled bottom halves to ensure that
pending softirqs, which were raised within the function, are handled.
netif_rx_ni() can be invoked only from process context (bottom halves
must be enabled) because the function handles pending softirqs without
checking if bottom halves were disabled or not.
netif_rx_any_context() invokes on the former functions by checking
in_interrupts().

netif_rx() could be taught to handle both cases (disabled and enabled
bottom halves) by simply disabling bottom halves while invoking
netif_rx_internal(). The local_bh_enable() invocation will then invoke
pending softirqs only if the BH-disable counter drops to zero.

Eric is concerned about the overhead of BH-disable+enable especially in
regard to the loopback driver. As critical as this driver is, it will
receive a shortcut to avoid the additional overhead which is not needed.

Add a local_bh_disable() section in netif_rx() to ensure softirqs are
handled if needed.
Provide __netif_rx() which does not disable BH and has a lockdep assert
to ensure that interrupts are disabled. Use this shortcut in the
loopback driver and in drivers/net/*.c.
Make netif_rx_ni() and netif_rx_any_context() invoke netif_rx() so they
can be removed once they are no more users left.

Link: https://lkml.kernel.org/r/20100415.020246.218622820.davem@davemloft.net
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sebastian Andrzej Siewior and committed by
David S. Miller
baebdf48 f234ae29

+60 -73
+2 -2
drivers/net/amt.c
··· 2373 2373 skb->pkt_type = PACKET_MULTICAST; 2374 2374 skb->ip_summed = CHECKSUM_NONE; 2375 2375 len = skb->len; 2376 - if (netif_rx(skb) == NET_RX_SUCCESS) { 2376 + if (__netif_rx(skb) == NET_RX_SUCCESS) { 2377 2377 amt_update_gw_status(amt, AMT_STATUS_RECEIVED_QUERY, true); 2378 2378 dev_sw_netstats_rx_add(amt->dev, len); 2379 2379 } else { ··· 2470 2470 skb->pkt_type = PACKET_MULTICAST; 2471 2471 skb->ip_summed = CHECKSUM_NONE; 2472 2472 len = skb->len; 2473 - if (netif_rx(skb) == NET_RX_SUCCESS) { 2473 + if (__netif_rx(skb) == NET_RX_SUCCESS) { 2474 2474 amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_UPDATE, 2475 2475 true); 2476 2476 dev_sw_netstats_rx_add(amt->dev, len);
+2 -2
drivers/net/geneve.c
··· 925 925 } 926 926 927 927 skb->protocol = eth_type_trans(skb, geneve->dev); 928 - netif_rx(skb); 928 + __netif_rx(skb); 929 929 dst_release(&rt->dst); 930 930 return -EMSGSIZE; 931 931 } ··· 1021 1021 } 1022 1022 1023 1023 skb->protocol = eth_type_trans(skb, geneve->dev); 1024 - netif_rx(skb); 1024 + __netif_rx(skb); 1025 1025 dst_release(dst); 1026 1026 return -EMSGSIZE; 1027 1027 }
+1 -1
drivers/net/gtp.c
··· 207 207 208 208 dev_sw_netstats_rx_add(pctx->dev, skb->len); 209 209 210 - netif_rx(skb); 210 + __netif_rx(skb); 211 211 return 0; 212 212 213 213 err:
+2 -2
drivers/net/loopback.c
··· 78 78 79 79 skb_orphan(skb); 80 80 81 - /* Before queueing this packet to netif_rx(), 81 + /* Before queueing this packet to __netif_rx(), 82 82 * make sure dst is refcounted. 83 83 */ 84 84 skb_dst_force(skb); ··· 86 86 skb->protocol = eth_type_trans(skb, dev); 87 87 88 88 len = skb->len; 89 - if (likely(netif_rx(skb) == NET_RX_SUCCESS)) 89 + if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) 90 90 dev_lstats_add(dev, len); 91 91 92 92 return NETDEV_TX_OK;
+3 -3
drivers/net/macsec.c
··· 1033 1033 else 1034 1034 nskb->pkt_type = PACKET_MULTICAST; 1035 1035 1036 - netif_rx(nskb); 1036 + __netif_rx(nskb); 1037 1037 } 1038 1038 continue; 1039 1039 } ··· 1056 1056 1057 1057 nskb->dev = ndev; 1058 1058 1059 - if (netif_rx(nskb) == NET_RX_SUCCESS) { 1059 + if (__netif_rx(nskb) == NET_RX_SUCCESS) { 1060 1060 u64_stats_update_begin(&secy_stats->syncp); 1061 1061 secy_stats->stats.InPktsUntagged++; 1062 1062 u64_stats_update_end(&secy_stats->syncp); ··· 1288 1288 1289 1289 macsec_reset_skb(nskb, macsec->secy.netdev); 1290 1290 1291 - ret = netif_rx(nskb); 1291 + ret = __netif_rx(nskb); 1292 1292 if (ret == NET_RX_SUCCESS) { 1293 1293 u64_stats_update_begin(&secy_stats->syncp); 1294 1294 secy_stats->stats.InPktsUnknownSCI++;
+2 -2
drivers/net/macvlan.c
··· 410 410 if (ether_addr_equal_64bits(eth_hdr(skb)->h_dest, dev->dev_addr)) 411 411 nskb->pkt_type = PACKET_HOST; 412 412 413 - ret = netif_rx(nskb); 413 + ret = __netif_rx(nskb); 414 414 macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false); 415 415 } 416 416 ··· 468 468 /* forward to original port. */ 469 469 vlan = src; 470 470 ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?: 471 - netif_rx(skb); 471 + __netif_rx(skb); 472 472 handle_res = RX_HANDLER_CONSUMED; 473 473 goto out; 474 474 }
+1 -1
drivers/net/mhi_net.c
··· 225 225 u64_stats_inc(&mhi_netdev->stats.rx_packets); 226 226 u64_stats_add(&mhi_netdev->stats.rx_bytes, skb->len); 227 227 u64_stats_update_end(&mhi_netdev->stats.rx_syncp); 228 - netif_rx(skb); 228 + __netif_rx(skb); 229 229 } 230 230 231 231 /* Refill if RX buffers queue becomes low */
+1 -1
drivers/net/ntb_netdev.c
··· 119 119 skb->protocol = eth_type_trans(skb, ndev); 120 120 skb->ip_summed = CHECKSUM_NONE; 121 121 122 - if (netif_rx(skb) == NET_RX_DROP) { 122 + if (__netif_rx(skb) == NET_RX_DROP) { 123 123 ndev->stats.rx_errors++; 124 124 ndev->stats.rx_dropped++; 125 125 } else {
+1 -1
drivers/net/rionet.c
··· 109 109 skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE); 110 110 rnet->rx_skb[i]->protocol = 111 111 eth_type_trans(rnet->rx_skb[i], ndev); 112 - error = netif_rx(rnet->rx_skb[i]); 112 + error = __netif_rx(rnet->rx_skb[i]); 113 113 114 114 if (error == NET_RX_DROP) { 115 115 ndev->stats.rx_dropped++;
+1 -1
drivers/net/sb1000.c
··· 872 872 873 873 /* datagram completed: send to upper level */ 874 874 skb_trim(skb, dlen); 875 - netif_rx(skb); 875 + __netif_rx(skb); 876 876 stats->rx_bytes+=dlen; 877 877 stats->rx_packets++; 878 878 lp->rx_skb[ns] = NULL;
+1 -1
drivers/net/veth.c
··· 287 287 { 288 288 return __dev_forward_skb(dev, skb) ?: xdp ? 289 289 veth_xdp_rx(rq, skb) : 290 - netif_rx(skb); 290 + __netif_rx(skb); 291 291 } 292 292 293 293 /* return true if the specified skb has chances of GRO aggregation
+1 -1
drivers/net/vrf.c
··· 418 418 419 419 skb->protocol = eth_type_trans(skb, dev); 420 420 421 - if (likely(netif_rx(skb) == NET_RX_SUCCESS)) 421 + if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) 422 422 vrf_rx_stats(dev, len); 423 423 else 424 424 this_cpu_inc(dev->dstats->rx_drps);
+1 -1
drivers/net/vxlan.c
··· 2541 2541 tx_stats->tx_bytes += len; 2542 2542 u64_stats_update_end(&tx_stats->syncp); 2543 2543 2544 - if (netif_rx(skb) == NET_RX_SUCCESS) { 2544 + if (__netif_rx(skb) == NET_RX_SUCCESS) { 2545 2545 u64_stats_update_begin(&rx_stats->syncp); 2546 2546 rx_stats->rx_packets++; 2547 2547 rx_stats->rx_bytes += len;
+12 -2
include/linux/netdevice.h
··· 3672 3672 void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog); 3673 3673 int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb); 3674 3674 int netif_rx(struct sk_buff *skb); 3675 - int netif_rx_ni(struct sk_buff *skb); 3676 - int netif_rx_any_context(struct sk_buff *skb); 3675 + int __netif_rx(struct sk_buff *skb); 3676 + 3677 + static inline int netif_rx_ni(struct sk_buff *skb) 3678 + { 3679 + return netif_rx(skb); 3680 + } 3681 + 3682 + static inline int netif_rx_any_context(struct sk_buff *skb) 3683 + { 3684 + return netif_rx(skb); 3685 + } 3686 + 3677 3687 int netif_receive_skb(struct sk_buff *skb); 3678 3688 int netif_receive_skb_core(struct sk_buff *skb); 3679 3689 void netif_receive_skb_list_internal(struct list_head *head);
-14
include/trace/events/net.h
··· 260 260 TP_ARGS(skb) 261 261 ); 262 262 263 - DEFINE_EVENT(net_dev_rx_verbose_template, netif_rx_ni_entry, 264 - 265 - TP_PROTO(const struct sk_buff *skb), 266 - 267 - TP_ARGS(skb) 268 - ); 269 - 270 263 DECLARE_EVENT_CLASS(net_dev_rx_exit_template, 271 264 272 265 TP_PROTO(int ret), ··· 299 306 ); 300 307 301 308 DEFINE_EVENT(net_dev_rx_exit_template, netif_rx_exit, 302 - 303 - TP_PROTO(int ret), 304 - 305 - TP_ARGS(ret) 306 - ); 307 - 308 - DEFINE_EVENT(net_dev_rx_exit_template, netif_rx_ni_exit, 309 309 310 310 TP_PROTO(int ret), 311 311
+29 -38
net/core/dev.c
··· 4816 4816 } 4817 4817 4818 4818 /** 4819 + * __netif_rx - Slightly optimized version of netif_rx 4820 + * @skb: buffer to post 4821 + * 4822 + * This behaves as netif_rx except that it does not disable bottom halves. 4823 + * As a result this function may only be invoked from the interrupt context 4824 + * (either hard or soft interrupt). 4825 + */ 4826 + int __netif_rx(struct sk_buff *skb) 4827 + { 4828 + int ret; 4829 + 4830 + lockdep_assert_once(hardirq_count() | softirq_count()); 4831 + 4832 + trace_netif_rx_entry(skb); 4833 + ret = netif_rx_internal(skb); 4834 + trace_netif_rx_exit(ret); 4835 + return ret; 4836 + } 4837 + EXPORT_SYMBOL(__netif_rx); 4838 + 4839 + /** 4819 4840 * netif_rx - post buffer to the network code 4820 4841 * @skb: buffer to post 4821 4842 * 4822 4843 * This function receives a packet from a device driver and queues it for 4823 - * the upper (protocol) levels to process. It always succeeds. The buffer 4824 - * may be dropped during processing for congestion control or by the 4825 - * protocol layers. 4844 + * the upper (protocol) levels to process via the backlog NAPI device. It 4845 + * always succeeds. The buffer may be dropped during processing for 4846 + * congestion control or by the protocol layers. 4847 + * The network buffer is passed via the backlog NAPI device. Modern NIC 4848 + * driver should use NAPI and GRO. 4849 + * This function can used from any context. 4826 4850 * 4827 4851 * return values: 4828 4852 * NET_RX_SUCCESS (no congestion) 4829 4853 * NET_RX_DROP (packet was dropped) 4830 4854 * 4831 4855 */ 4832 - 4833 4856 int netif_rx(struct sk_buff *skb) 4834 4857 { 4835 4858 int ret; 4836 4859 4860 + local_bh_disable(); 4837 4861 trace_netif_rx_entry(skb); 4838 - 4839 4862 ret = netif_rx_internal(skb); 4840 4863 trace_netif_rx_exit(ret); 4841 - 4864 + local_bh_enable(); 4842 4865 return ret; 4843 4866 } 4844 4867 EXPORT_SYMBOL(netif_rx); 4845 - 4846 - int netif_rx_ni(struct sk_buff *skb) 4847 - { 4848 - int err; 4849 - 4850 - trace_netif_rx_ni_entry(skb); 4851 - 4852 - preempt_disable(); 4853 - err = netif_rx_internal(skb); 4854 - if (local_softirq_pending()) 4855 - do_softirq(); 4856 - preempt_enable(); 4857 - trace_netif_rx_ni_exit(err); 4858 - 4859 - return err; 4860 - } 4861 - EXPORT_SYMBOL(netif_rx_ni); 4862 - 4863 - int netif_rx_any_context(struct sk_buff *skb) 4864 - { 4865 - /* 4866 - * If invoked from contexts which do not invoke bottom half 4867 - * processing either at return from interrupt or when softrqs are 4868 - * reenabled, use netif_rx_ni() which invokes bottomhalf processing 4869 - * directly. 4870 - */ 4871 - if (in_interrupt()) 4872 - return netif_rx(skb); 4873 - else 4874 - return netif_rx_ni(skb); 4875 - } 4876 - EXPORT_SYMBOL(netif_rx_any_context); 4877 4868 4878 4869 static __latent_entropy void net_tx_action(struct softirq_action *h) 4879 4870 {