D.3.3.1 rcu_init_levelspread()

Figure: rcu_init_levelspread() Code
\begin{figure}{ \scriptsize
\begin{verbatim}1  ...

Figure [*] shows the code for the rcu_init_levelspread() function, which controls the fanout, or the number of children per parent, in the rcu_node hierarchy. There are two versions of this function, one shown on lines 2-9 that enforces the exact fanout (specified by CONFIG_RCU_FANOUT), and the other on lines 11-25 that determines the number of child nodes based indirectly on the specified fanout, but then balances the tree. The CONFIG_RCU_FANOUT_EXACT kernel parameter selects which version to use for a given kernel build.

The exact-fanout version simply assigns all of the elements of the specified rcu_state structure's ->levelspread array to the CONFIG_RCU_FANOUT kernel parameter, as shown by the loop on lines 7 and 8.

The hierarchy-balancing version on lines 11-24 uses a pair of local variables ccur and cprv which track the number of rcu_node structures on the current and previous levels, respectively. This function works from the leaf level up the hierarchy, so cprv is initialized by line 18 to NR_CPUS, which corresponds to the number of rcu_data structures that feed into the leaf level. Lines 19-23 iterate from the leaf to the root. Within this loop, line 20 picking up the number of rcu_node structures for the current level into ccur. Line 21 then rounds up the ratio of the number of nodes on the previous (lower) level (be they rcu_node or rcu_data) to the number of rcu_node structures on the current level, placing the result in the specified rcu_state structure's ->levelspread array. Line 22 then sets up for the next pass through the loop.

After a call to either function, the ->levelspread array contains the number of children for each level of the rcu_node hierarchy.

Paul E. McKenney 2011-12-16