• Paul E. McKenney's avatar
    rcu: Fix CONFIG_RCU_FANOUT_EXACT for odd fanout/leaf values · 04f34650
    Paul E. McKenney authored
    Each element of the rcu_state structure's ->levelspread[] array
    is intended to contain the per-level fanout, where the zero-th
    element corresponds to the root of the rcu_node tree, and the last
    element corresponds to the leaves.  In the CONFIG_RCU_FANOUT_EXACT
    case, this means that the last element should be filled in
    from CONFIG_RCU_FANOUT_LEAF (or from the rcu_fanout_leaf boot
    parameter, if provided) and that the remaining elements should
    be filled in from CONFIG_RCU_FANOUT.  Unfortunately, the current
    code in rcu_init_levelspread() takes the opposite approach, placing
    CONFIG_RCU_FANOUT_LEAF in the zero-th element and CONFIG_RCU_FANOUT in
    the remaining elements.
    
    For typical power-of-two values, this generates odd but functional
    rcu_node trees.  However, other values, for example CONFIG_RCU_FANOUT=3
    and CONFIG_RCU_FANOUT_LEAF=2, generate trees that can leave some CPUs
    out of the grace-period computation, resulting in too-short grace periods
    and therefore a broken RCU implementation.
    
    This commit therefore fixes rcu_init_levelspread() to set the last
    ->levelspread[] array element from CONFIG_RCU_FANOUT_LEAF and the
    remaining elements from CONFIG_RCU_FANOUT, thus generating the
    intended rcu_node trees.
    Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
    04f34650
tree.c 108 KB