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