From: Sebastian Andrzej Siewior Date: Fri, 16 Feb 2018 11:45:13 +0100 Subject: [PATCH] RCU: skip the "schedule() in RCU section" warning on UP, too Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.16/older/patches-4.16.7-rt1.tar.xz In "RCU: we need to skip that warning but only on sleeping locks" we skipped a warning on SMP systems in case we schedule out in a RCU section while attempt to obtain a sleeping lock. This is also required on UP systems. In order to do so, I introduce a tiny version of migrate_disable() + _enable() which only update the counters which we then can check against on RT && !SMP. Cc: stable-rt@vger.kernel.org Reported-by: Grygorii Strashko Tested-by: Grygorii Strashko Signed-off-by: Sebastian Andrzej Siewior --- include/linux/preempt.h | 9 +++++++++ include/linux/sched.h | 6 ++++++ kernel/rcu/tree_plugin.h | 2 +- kernel/sched/core.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -211,6 +211,15 @@ extern void migrate_enable(void); int __migrate_disabled(struct task_struct *p); +#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) + +extern void migrate_disable(void); +extern void migrate_enable(void); +static inline int __migrate_disabled(struct task_struct *p) +{ + return 0; +} + #else #define migrate_disable() barrier() #define migrate_enable() barrier() --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -604,6 +604,12 @@ struct task_struct { # ifdef CONFIG_SCHED_DEBUG int migrate_disable_atomic; # endif + +#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) + int migrate_disable; +# ifdef CONFIG_SCHED_DEBUG + int migrate_disable_atomic; +# endif #endif #ifdef CONFIG_PREEMPT_RCU --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -328,7 +328,7 @@ static void rcu_preempt_note_context_swi int mg_counter = 0; lockdep_assert_irqs_disabled(); -#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) +#if defined(CONFIG_PREEMPT_RT_BASE) mg_counter = t->migrate_disable; #endif WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0 && !mg_counter); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7278,4 +7278,49 @@ void migrate_enable(void) preempt_enable(); } EXPORT_SYMBOL(migrate_enable); + +#elif !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT_BASE) +void migrate_disable(void) +{ + struct task_struct *p = current; + + if (in_atomic() || irqs_disabled()) { +#ifdef CONFIG_SCHED_DEBUG + p->migrate_disable_atomic++; +#endif + return; + } +#ifdef CONFIG_SCHED_DEBUG + if (unlikely(p->migrate_disable_atomic)) { + tracing_off(); + WARN_ON_ONCE(1); + } +#endif + + p->migrate_disable++; +} +EXPORT_SYMBOL(migrate_disable); + +void migrate_enable(void) +{ + struct task_struct *p = current; + + if (in_atomic() || irqs_disabled()) { +#ifdef CONFIG_SCHED_DEBUG + p->migrate_disable_atomic--; +#endif + return; + } + +#ifdef CONFIG_SCHED_DEBUG + if (unlikely(p->migrate_disable_atomic)) { + tracing_off(); + WARN_ON_ONCE(1); + } +#endif + + WARN_ON_ONCE(p->migrate_disable <= 0); + p->migrate_disable--; +} +EXPORT_SYMBOL(migrate_enable); #endif