linux/include/linux/rcu_node_tree.h

/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * RCU node combining tree definitions.  These are used to compute
 * global attributes while avoiding common-case global contention.  A key
 * property that these computations rely on is a tournament-style approach
 * where only one of the tasks contending a lower level in the tree need
 * advance to the next higher level.  If properly configured, this allows
 * unlimited scalability while maintaining a constant level of contention
 * on the root node.
 *
 * This seemingly RCU-private file must be available to SRCU users
 * because the size of the TREE SRCU srcu_struct structure depends
 * on these definitions.
 *
 * Copyright IBM Corporation, 2017
 *
 * Author: Paul E. McKenney <[email protected]>
 */

#ifndef __LINUX_RCU_NODE_TREE_H
#define __LINUX_RCU_NODE_TREE_H

#include <linux/math.h>

/*
 * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and
 * CONFIG_RCU_FANOUT_LEAF.
 * In theory, it should be possible to add more levels straightforwardly.
 * In practice, this did work well going from three levels to four.
 * Of course, your mileage may vary.
 */

#ifdef CONFIG_RCU_FANOUT
#define RCU_FANOUT
#else /* #ifdef CONFIG_RCU_FANOUT */
# ifdef CONFIG_64BIT
#define RCU_FANOUT
# else
#define RCU_FANOUT
# endif
#endif /* #else #ifdef CONFIG_RCU_FANOUT */

#ifdef CONFIG_RCU_FANOUT_LEAF
#define RCU_FANOUT_LEAF
#else /* #ifdef CONFIG_RCU_FANOUT_LEAF */
#define RCU_FANOUT_LEAF
#endif /* #else #ifdef CONFIG_RCU_FANOUT_LEAF */

#define RCU_FANOUT_1
#define RCU_FANOUT_2
#define RCU_FANOUT_3
#define RCU_FANOUT_4

#if NR_CPUS <= RCU_FANOUT_1
#define RCU_NUM_LVLS
#define NUM_RCU_LVL_0
#define NUM_RCU_NODES
#define NUM_RCU_LVL_INIT
#define RCU_NODE_NAME_INIT
#define RCU_FQS_NAME_INIT
#elif NR_CPUS <= RCU_FANOUT_2
#define RCU_NUM_LVLS
#define NUM_RCU_LVL_0
#define NUM_RCU_LVL_1
#define NUM_RCU_NODES
#define NUM_RCU_LVL_INIT
#define RCU_NODE_NAME_INIT
#define RCU_FQS_NAME_INIT
#elif NR_CPUS <= RCU_FANOUT_3
#define RCU_NUM_LVLS
#define NUM_RCU_LVL_0
#define NUM_RCU_LVL_1
#define NUM_RCU_LVL_2
#define NUM_RCU_NODES
#define NUM_RCU_LVL_INIT
#define RCU_NODE_NAME_INIT
#define RCU_FQS_NAME_INIT
#elif NR_CPUS <= RCU_FANOUT_4
#define RCU_NUM_LVLS
#define NUM_RCU_LVL_0
#define NUM_RCU_LVL_1
#define NUM_RCU_LVL_2
#define NUM_RCU_LVL_3
#define NUM_RCU_NODES
#define NUM_RCU_LVL_INIT
#define RCU_NODE_NAME_INIT
#define RCU_FQS_NAME_INIT
#else
# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
#endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */

#endif /* __LINUX_RCU_NODE_TREE_H */