From: Sebastian Andrzej Siewior Date: Wed, 16 Feb 2022 17:50:46 +0000 (+0100) Subject: net: Correct wrong BH disable in hard-interrupt. X-Git-Tag: v5.18-rc1~136^2~266 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=167053f8dd0ed60287858448696b4784d7e1d899;p=tomoyo%2Ftomoyo-test1.git net: Correct wrong BH disable in hard-interrupt. I missed the obvious case where netif_ix() is invoked from hard-IRQ context. Disabling bottom halves is only needed in process context. This ensures that the code remains on the current CPU and that the soft-interrupts are processed at local_bh_enable() time. In hard- and soft-interrupt context this is already the case and the soft-interrupts will be processed once the context is left (at irq-exit time). Disable bottom halves if neither hard-interrupts nor soft-interrupts are disabled. Update the kernel-doc, mention that interrupts must be enabled if invoked from process context. Fixes: baebdf48c3600 ("net: dev: Makes sure netif_rx() can be invoked in any context.") Reported-by: Marek Szyprowski Signed-off-by: Sebastian Andrzej Siewior Tested-by: Marek Szyprowski Tested-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/Yg05duINKBqvnxUc@linutronix.de Signed-off-by: Jakub Kicinski --- diff --git a/net/core/dev.c b/net/core/dev.c index a1190291c48e..2d6771075720 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4860,7 +4860,9 @@ EXPORT_SYMBOL(__netif_rx); * congestion control or by the protocol layers. * The network buffer is passed via the backlog NAPI device. Modern NIC * driver should use NAPI and GRO. - * This function can used from any context. + * This function can used from interrupt and from process context. The + * caller from process context must not disable interrupts before invoking + * this function. * * return values: * NET_RX_SUCCESS (no congestion) @@ -4869,13 +4871,16 @@ EXPORT_SYMBOL(__netif_rx); */ int netif_rx(struct sk_buff *skb) { + bool need_bh_off = !(hardirq_count() | softirq_count()); int ret; - local_bh_disable(); + if (need_bh_off) + local_bh_disable(); trace_netif_rx_entry(skb); ret = netif_rx_internal(skb); trace_netif_rx_exit(ret); - local_bh_enable(); + if (need_bh_off) + local_bh_enable(); return ret; } EXPORT_SYMBOL(netif_rx);