D.3.7.1 Entering and Exiting Dyntick-Idle Mode

Figure: Entering and Exiting Dyntick-Idle Mode
\begin{figure}{ \scriptsize
\begin{verbatim}1 void rcu_enter_nohz(void)
2 {
...
...
23 local_irq_restore(flags);
24 smp_mb();
25 }\end{verbatim}
}\end{figure}

Figure [*] shows the rcu_enter_nohz() and rcu_exit_nohz() functions that allow the scheduler to transition to and from dynticks-idle mode. Therefore, after rcu_enter_nohz() has been call, RCU will ignore it, at least until the next rcu_exit_nohz(), the next interrupt, or the next NMI.

Line 6 of rcu_enter_nohz() executes a memory barrier to ensure that any preceding RCU read-side critical sections are seen to have occurred before the following code that tells RCU to ignore this CPU. Lines 7 and 11 disable and restore interrupts in order to avoid interference with the state change. Line 8 picks up a pointer to the running CPU's rcu_dynticks structure, line 9 increments the ->dynticks field (which now must be even to indicate that this CPU may be ignored), and finally line 10 decrements the ->dynticks_nesting field (which now must be zero to indicate that there is no reason to pay attention to this CPU).

Lines 19 and 23 of rcu_exit_nohz() disable and re-enable interrupts, again to avoid interference. Line 20 obtains a pointer to this CPU's rcu_dynticks structure, line 21 increments the ->dynticks field (which now must be odd in order to indicate that RCU must once again pay attention to this CPU), and line 22 increments the ->dynticks_nesting field (which now must have the value 1 to indicate that there is one reason to pay attention to this CPU).

Paul E. McKenney 2011-12-16