D.3.4.1 rcu_init_percpu_data()

Figure: rcu_init_percpu_data() Code
\begin{figure}{ \scriptsize
\begin{verbatim}1 static void
2 rcu_init_percpu_...
...dp, lastcomp);
42 local_irq_restore(flags);
43 }\end{verbatim}
}\end{figure}

Figure [*] shows the code for rcu_init_percpu_data(), which initializes the specified CPU's rcu_data structure in response to booting up or to that CPU coming online. It also sets up the rcu_node hierarchy so that this CPU will participate in future grace periods.

Line 8 gets a pointer to this CPU's rcu_data structure, based on the specified rcu_state structure, and places this pointer into the local variable rdp. Line 9 gets a pointer to the root rcu_node structure for the specified rcu_state structure, placing it in local variable rnp.

Lines 11-29 initialize the fields of the rcu_data structure under the protection of the root rcu_node structure's lock in order to ensure consistent values. Line 17 is important for tracing, due to the fact that many Linux distributions set NR_CPUS to a very large number, which could result in excessive output when tracing rcu_data structures. The ->beenonline field is used to solve this problem, as it will be set to the value one on any rcu_data structure corresponding to a CPU that has ever been online, and set to zero for all other rcu_data structures. This allows the tracing code to easily ignore irrelevant CPUs.

Lines 30-40 propagate the onlining CPU's bit up the rcu_node hierarchy, proceeding until either the root rcu_node is reached or until the corresponding bit is already set, whichever comes first. This bit-setting is done under the protection of ->onofflock in order to exclude initialization of a new grace period, and, in addition, each rcu_node structure is initialized under the protection of its lock. Line 41 then invokes cpu_quiet() to signal RCU that this CPU has been in an extended quiescent state, and finally, line 42 re-enables irqs.

Quick Quiz D.36: Why call cpu_quiet() on line 41 of Figure [*], given that we are excluding grace periods with various locks, and given that any earlier grace periods would not have been waiting on this previously-offlined CPU? End Quick Quiz

It is important to note that rcu_init_percpu_data() is invoked not only at boot time, but also every time that a given CPU is brought online.

Paul E. McKenney 2011-12-16