E.8.5 Checking For Dynticks Quiescent States

Figure: Saving Dyntick Progress Counters
\begin{figure}{ \scriptsize
\begin{verbatim}1 static int
2 dyntick_save_prog...
...et)
15 rdp->dynticks_fqs++;
16 return ret;
17 }\end{verbatim}
}\end{figure}

Figure [*] shows dyntick_save_progress_counter(), which takes a snapshot of the specified CPU's dynticks and dynticks_nmi counters. Lines 8 and 9 snapshot these two variables to locals, line 10 executes a memory barrier to pair with the memory barriers in the functions in Figures [*], [*], and [*]. Lines 11 and 12 record the snapshots for later calls to rcu_implicit_dynticks_qs, and 13 checks to see if the CPU is in dynticks-idle mode with neither irqs nor NMIs in progress (in other words, both snapshots have even values), hence in an extended quiescent state. If so, lines 14 and 15 count this event, and line 16 returns true if the CPU was in a quiescent state.

Figure: Checking Dyntick Progress Counters
\begin{figure}{ \scriptsize
\begin{verbatim}1 static int
2 rcu_implicit_dynt...
...8 }
19 return rcu_implicit_offline_qs(rdp);
20 }\end{verbatim}
}\end{figure}

Figure [*] shows dyntick_save_progress_counter, which is called to check whether a CPU has entered dyntick-idle mode subsequent to a call to dynticks_save_progress_counter(). Lines 9 and 11 take new snapshots of the corresponding CPU's dynticks and dynticks_nmi variables, while lines 10 and 12 retrieve the snapshots saved earlier by dynticks_save_progress_counter(). Line 13 then executes a memory barrier to pair with the memory barriers in the functions in Figures [*], [*], and [*]. Lines 14 and 15 then check to see if the CPU is either currently in a quiescent state (curr and curr_nmi having even values) or has passed through a quiescent state since the last call to dynticks_save_progress_counter() (the values of dynticks and dynticks_nmi having changed). If these checks confirm that the CPU has passed through a dyntick-idle quiescent state, then line 16 counts that fact and line 16 returns an indication of this fact. Either way, line 19 checks for race conditions that can result in RCU waiting for a CPU that is offline.

Quick Quiz E.20: This is still pretty complicated. Why not just have a cpumask_t that has a bit set for each CPU that is in dyntick-idle mode, clearing the bit when entering an irq or NMI handler, and setting it upon exit? End Quick Quiz

Paul E. McKenney 2011-12-16