diff options
Diffstat (limited to 'debian/patches-rt/0204-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch')
-rw-r--r-- | debian/patches-rt/0204-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/debian/patches-rt/0204-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch b/debian/patches-rt/0204-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch new file mode 100644 index 000000000..5a4aed73f --- /dev/null +++ b/debian/patches-rt/0204-net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch @@ -0,0 +1,77 @@ +From 2faaff72af2ce49a00236dbfe09246e3099229ec Mon Sep 17 00:00:00 2001 +From: Steven Rostedt <rostedt@goodmis.org> +Date: Tue, 6 Dec 2016 17:50:30 -0500 +Subject: [PATCH 204/347] net: Have __napi_schedule_irqoff() disable interrupts + on RT +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz + +A customer hit a crash where the napi sd->poll_list became corrupted. +The customer had the bnx2x driver, which does a +__napi_schedule_irqoff() in its interrupt handler. Unfortunately, when +running with CONFIG_PREEMPT_RT_FULL, this interrupt handler is run as a +thread and is preemptable. The call to ____napi_schedule() must be done +with interrupts disabled to protect the per cpu softnet_data's +"poll_list, which is protected by disabling interrupts (disabling +preemption is enough when all interrupts are threaded and +local_bh_disable() can't preempt)." + +As bnx2x isn't the only driver that does this, the safest thing to do +is to make __napi_schedule_irqoff() call __napi_schedule() instead when +CONFIG_PREEMPT_RT_FULL is enabled, which will call local_irq_save() +before calling ____napi_schedule(). + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Steven Rostedt (Red Hat) <rostedt@goodmis.org> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/netdevice.h | 12 ++++++++++++ + net/core/dev.c | 2 ++ + 2 files changed, 14 insertions(+) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index dfec34087039..c4713217b20e 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -423,7 +423,19 @@ typedef enum rx_handler_result rx_handler_result_t; + typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb); + + void __napi_schedule(struct napi_struct *n); ++ ++/* ++ * When PREEMPT_RT_FULL is defined, all device interrupt handlers ++ * run as threads, and they can also be preempted (without PREEMPT_RT ++ * interrupt threads can not be preempted). Which means that calling ++ * __napi_schedule_irqoff() from an interrupt handler can be preempted ++ * and can corrupt the napi->poll_list. ++ */ ++#ifdef CONFIG_PREEMPT_RT_FULL ++#define __napi_schedule_irqoff(n) __napi_schedule(n) ++#else + void __napi_schedule_irqoff(struct napi_struct *n); ++#endif + + static inline bool napi_disable_pending(struct napi_struct *n) + { +diff --git a/net/core/dev.c b/net/core/dev.c +index 7c59fa4d3ecf..e65dc7a7cc13 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -5953,6 +5953,7 @@ bool napi_schedule_prep(struct napi_struct *n) + } + EXPORT_SYMBOL(napi_schedule_prep); + ++#ifndef CONFIG_PREEMPT_RT_FULL + /** + * __napi_schedule_irqoff - schedule for receive + * @n: entry to schedule +@@ -5971,6 +5972,7 @@ void __napi_schedule_irqoff(struct napi_struct *n) + __napi_schedule(n); + } + EXPORT_SYMBOL(__napi_schedule_irqoff); ++#endif + + bool napi_complete_done(struct napi_struct *n, int work_done) + { +-- +2.36.1 + |