E.8.4 Interrupts From Dynticks-Idle Mode

Figure: Interrupts From Dynticks-Idle Mode
\begin{figure}{ \scriptsize
\begin{verbatim}1 void rcu_irq_enter(void)
2 {
...
...cu_bh_data).nxtlist)
25 set_need_resched();
26 }\end{verbatim}
}\end{figure}

Figure [*] shows rcu_irq_enter() and rcu_irq_exit(), which inform RCU of entry to and exit from, respectively, irq context. Line 6 of rcu_irq_enter() increments dynticks_nesting, and if this variable was already non-zero, line 7 silently returns. Otherwise, line 8 increments dynticks, which will then have an odd value, consistent with the fact that this CPU can now execute RCU read-side critical sections. Line 10 therefore executes a memory barrier to ensure that the increment of dynticks is seen before any RCU read-side critical sections that the subsequent irq handler might execute.

Line 18 of rcu_irq_exit decrements dynticks_nesting, and if the result is non-zero, line 19 silently returns. Otherwise, line 20 executes a memory barrier to ensure that the increment of dynticks on line 21 is seen after any RCU read-side critical sections that the prior irq handler might have executed. Line 22 verifies that dynticks is now even, consistent with the fact that no RCU read-side critical sections may appear in dynticks-idle mode. Lines 23-25 check to see if the prior irq handlers enqueued any RCU callbacks, forcing this CPU out of dynticks-idle mode via an reschedule IPI if so.

Paul E. McKenney 2011-12-16