net: dev: Makes sure netif_rx() can be invoked in any context.
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Fri, 11 Feb 2022 23:38:38 +0000 (00:38 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 14 Feb 2022 13:38:35 +0000 (13:38 +0000)
commitbaebdf48c360080710f80699eea3affbb13d6c65
tree1d29aa72815907a13fd9cfc43115a91f249c5d80
parentf234ae2947612825686b25cae3e9579188a6ba95
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>
16 files changed:
drivers/net/amt.c
drivers/net/geneve.c
drivers/net/gtp.c
drivers/net/loopback.c
drivers/net/macsec.c
drivers/net/macvlan.c
drivers/net/mhi_net.c
drivers/net/ntb_netdev.c
drivers/net/rionet.c
drivers/net/sb1000.c
drivers/net/veth.c
drivers/net/vrf.c
drivers/net/vxlan.c
include/linux/netdevice.h
include/trace/events/net.h
net/core/dev.c