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