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>
Showing
- drivers/net/amt.c 2 additions, 2 deletionsdrivers/net/amt.c
- drivers/net/geneve.c 2 additions, 2 deletionsdrivers/net/geneve.c
- drivers/net/gtp.c 1 addition, 1 deletiondrivers/net/gtp.c
- drivers/net/loopback.c 2 additions, 2 deletionsdrivers/net/loopback.c
- drivers/net/macsec.c 3 additions, 3 deletionsdrivers/net/macsec.c
- drivers/net/macvlan.c 2 additions, 2 deletionsdrivers/net/macvlan.c
- drivers/net/mhi_net.c 1 addition, 1 deletiondrivers/net/mhi_net.c
- drivers/net/ntb_netdev.c 1 addition, 1 deletiondrivers/net/ntb_netdev.c
- drivers/net/rionet.c 1 addition, 1 deletiondrivers/net/rionet.c
- drivers/net/sb1000.c 1 addition, 1 deletiondrivers/net/sb1000.c
- drivers/net/veth.c 1 addition, 1 deletiondrivers/net/veth.c
- drivers/net/vrf.c 1 addition, 1 deletiondrivers/net/vrf.c
- drivers/net/vxlan.c 1 addition, 1 deletiondrivers/net/vxlan.c
- include/linux/netdevice.h 12 additions, 2 deletionsinclude/linux/netdevice.h
- include/trace/events/net.h 0 additions, 14 deletionsinclude/trace/events/net.h
- net/core/dev.c 29 additions, 38 deletionsnet/core/dev.c
Please register or sign in to comment