History

rcu/nocb: Perform deferred wake up before last idle's need_resched() check

Entering RCU idle mode may cause a deferred wake up of an RCU NOCB_GP kthread (rcuog) to be serviced. Usually a local wake up happening while running the idle task is handled in one of the need_resched() checks carefully placed within the idle loop that can break to the scheduler. Unfortunately the call to rcu_idle_enter() is already beyond the last generic need_resched() check and we may halt the CPU with a resched request unhandled, leaving the task hanging. Fix this with splitting the rcuog wakeup handling from rcu_idle_enter() and place it before the last generic need_resched() check in the idle loop. It is then assumed that no call to call_rcu() will be performed after that in the idle loop until the CPU is put in low power mode.

Frederic Weisbecker committed 5 years ago

Commit 43789ef1 parent 54b74294 files · +8 −3Browse files

Showing the changes to kernel (3 of 4 files). Show all

Unified · Split

3 files
  1. kernel/rcu/tree.c +0 −3
  2. kernel/rcu/tree_plugin.h +5 −0
  3. kernel/sched/idle.c +1 −0
kernel/rcu/tree.c+0−3
@@ -671,10 +671,7 @@ static noinstr void rcu_eqs_enter(bool user) · 670 unmodified lines
671671 */
672672 void rcu_idle_enter(void)
673673 {
674− struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
675−
676674 lockdep_assert_irqs_disabled();
677− do_nocb_deferred_wakeup(rdp);
678675 rcu_eqs_enter(false);
679676 }
680677 EXPORT_SYMBOL_GPL(rcu_idle_enter);
kernel/rcu/tree_plugin.h+5−0
@@ -2187,6 +2187,11 @@ static void do_nocb_deferred_wakeup(struct rcu_data *rdp) · 2186 unmodified lines
21872187 do_nocb_deferred_wakeup_common(rdp);
21882188 }
21892189
2190+void rcu_nocb_flush_deferred_wakeup(void)
2191+{
2192+ do_nocb_deferred_wakeup(this_cpu_ptr(&rcu_data));
2193+}
2194+
21902195 void __init rcu_init_nohz(void)
21912196 {
21922197 int cpu;
kernel/sched/idle.c+1−0
@@ -285,6 +285,7 @@ static void do_idle(void) · 284 unmodified lines
285285 }
286286
287287 arch_cpu_idle_enter();
288+ rcu_nocb_flush_deferred_wakeup();
288289
289290 /*
290291 * In poll mode we reenable interrupts and spin. Also if we

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t