Figure
shows the code for rcu_init_one(), which does boot-time initialization
for the specified
rcu_state structure.
Recall from
Section
that the ->levelcnt[] array in the rcu_state structure
is compile-time initialized to the number of nodes at each level of
the hierarchy starting from the root,
with an additional element in the array initialized
to the maximum possible number of CPUs, NR_CPUS.
In addition, the first element of the ->level[] array is compile-time
initialized to reference to the root rcu_node structure, which is
in turn
the first element of the ->node[] array in the rcu_state structure.
This array is further laid out in breadth-first order.
Keeping all of this in mind, the loop at lines 8-10 initializes the rest
of the ->level[] array to reference the first rcu_node structure
of each level of the rcu_node hierarchy.
Line 11 then invokes rcu_init_levelspread(), which fills in the
->levelspread[] array, as was described in
Section .
The auxiliary arrays are then fully initialized, and thus ready for
the loop from lines 15-35, each pass through which initializes
one level of the rcu_node hierarchy, starting from the leaves.
Line 13 computes the number of CPUs per rcu_node structure for the current level of the hierarchy, and line 14 obtains a pointer to the first rcu_node structure on the current level of the hierarchy, in preparation for the loop from lines 15-34, each pass through which initializes one rcu_node structure.
Lines 16-18 initialize the rcu_node structure's spinlock and its CPU masks. The qsmaskinit field will have bits set as CPUs come online later in boot, and the qsmask field will have bits set when the first grace period starts. Line 19 sets the ->grplo field to the number of the this rcu_node structure's first CPU and line 20 sets the ->grphi to the number of this rcu_node structure's last CPU. If the last rcu_node structure on a given level of the hierarchy is only partially full, lines 21 and 22 set its ->grphi field to the number of the last possible CPU in the system.
Lines 24-26 initialize the ->grpnum, ->grpmask, and ->parent fields for the root rcu_node structure, which has no parent, hence the zeroes and NULL. Lines 28-31 initialize these same fields for the rest of the rcu_node structures in the hierarchy. Line 28 computes the ->grpnum field as the index of this rcu_node structure within the set having the same parent, and line 29 sets the corresponding bit in the ->grpmask field. Finally, lines 30-31 places a pointer to the parent node into the ->parent field. These three fields will used to propagate quiescent states up the hierarchy.
Finally, line 33 records the hierarchy level in ->level, which is used for tracing when traversing the full hierarchy.
Paul E. McKenney 2011-12-16