1*f2425b4eSPaul E. McKenney /* 2*f2425b4eSPaul E. McKenney * RCU node combining tree definitions. These are used to compute 3*f2425b4eSPaul E. McKenney * global attributes while avoiding common-case global contention. A key 4*f2425b4eSPaul E. McKenney * property that these computations rely on is a tournament-style approach 5*f2425b4eSPaul E. McKenney * where only one of the tasks contending a lower level in the tree need 6*f2425b4eSPaul E. McKenney * advance to the next higher level. If properly configured, this allows 7*f2425b4eSPaul E. McKenney * unlimited scalability while maintaining a constant level of contention 8*f2425b4eSPaul E. McKenney * on the root node. 9*f2425b4eSPaul E. McKenney * 10*f2425b4eSPaul E. McKenney * This program is free software; you can redistribute it and/or modify 11*f2425b4eSPaul E. McKenney * it under the terms of the GNU General Public License as published by 12*f2425b4eSPaul E. McKenney * the Free Software Foundation; either version 2 of the License, or 13*f2425b4eSPaul E. McKenney * (at your option) any later version. 14*f2425b4eSPaul E. McKenney * 15*f2425b4eSPaul E. McKenney * This program is distributed in the hope that it will be useful, 16*f2425b4eSPaul E. McKenney * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*f2425b4eSPaul E. McKenney * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*f2425b4eSPaul E. McKenney * GNU General Public License for more details. 19*f2425b4eSPaul E. McKenney * 20*f2425b4eSPaul E. McKenney * You should have received a copy of the GNU General Public License 21*f2425b4eSPaul E. McKenney * along with this program; if not, you can access it online at 22*f2425b4eSPaul E. McKenney * http://www.gnu.org/licenses/gpl-2.0.html. 23*f2425b4eSPaul E. McKenney * 24*f2425b4eSPaul E. McKenney * Copyright IBM Corporation, 2017 25*f2425b4eSPaul E. McKenney * 26*f2425b4eSPaul E. McKenney * Author: Paul E. McKenney <[email protected]> 27*f2425b4eSPaul E. McKenney */ 28*f2425b4eSPaul E. McKenney 29*f2425b4eSPaul E. McKenney #ifndef __LINUX_RCU_NODE_TREE_H 30*f2425b4eSPaul E. McKenney #define __LINUX_RCU_NODE_TREE_H 31*f2425b4eSPaul E. McKenney 32*f2425b4eSPaul E. McKenney /* 33*f2425b4eSPaul E. McKenney * Define shape of hierarchy based on NR_CPUS, CONFIG_RCU_FANOUT, and 34*f2425b4eSPaul E. McKenney * CONFIG_RCU_FANOUT_LEAF. 35*f2425b4eSPaul E. McKenney * In theory, it should be possible to add more levels straightforwardly. 36*f2425b4eSPaul E. McKenney * In practice, this did work well going from three levels to four. 37*f2425b4eSPaul E. McKenney * Of course, your mileage may vary. 38*f2425b4eSPaul E. McKenney */ 39*f2425b4eSPaul E. McKenney 40*f2425b4eSPaul E. McKenney #ifdef CONFIG_RCU_FANOUT 41*f2425b4eSPaul E. McKenney #define RCU_FANOUT CONFIG_RCU_FANOUT 42*f2425b4eSPaul E. McKenney #else /* #ifdef CONFIG_RCU_FANOUT */ 43*f2425b4eSPaul E. McKenney # ifdef CONFIG_64BIT 44*f2425b4eSPaul E. McKenney # define RCU_FANOUT 64 45*f2425b4eSPaul E. McKenney # else 46*f2425b4eSPaul E. McKenney # define RCU_FANOUT 32 47*f2425b4eSPaul E. McKenney # endif 48*f2425b4eSPaul E. McKenney #endif /* #else #ifdef CONFIG_RCU_FANOUT */ 49*f2425b4eSPaul E. McKenney 50*f2425b4eSPaul E. McKenney #ifdef CONFIG_RCU_FANOUT_LEAF 51*f2425b4eSPaul E. McKenney #define RCU_FANOUT_LEAF CONFIG_RCU_FANOUT_LEAF 52*f2425b4eSPaul E. McKenney #else /* #ifdef CONFIG_RCU_FANOUT_LEAF */ 53*f2425b4eSPaul E. McKenney #define RCU_FANOUT_LEAF 16 54*f2425b4eSPaul E. McKenney #endif /* #else #ifdef CONFIG_RCU_FANOUT_LEAF */ 55*f2425b4eSPaul E. McKenney 56*f2425b4eSPaul E. McKenney #define RCU_FANOUT_1 (RCU_FANOUT_LEAF) 57*f2425b4eSPaul E. McKenney #define RCU_FANOUT_2 (RCU_FANOUT_1 * RCU_FANOUT) 58*f2425b4eSPaul E. McKenney #define RCU_FANOUT_3 (RCU_FANOUT_2 * RCU_FANOUT) 59*f2425b4eSPaul E. McKenney #define RCU_FANOUT_4 (RCU_FANOUT_3 * RCU_FANOUT) 60*f2425b4eSPaul E. McKenney 61*f2425b4eSPaul E. McKenney #if NR_CPUS <= RCU_FANOUT_1 62*f2425b4eSPaul E. McKenney # define RCU_NUM_LVLS 1 63*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_0 1 64*f2425b4eSPaul E. McKenney # define NUM_RCU_NODES NUM_RCU_LVL_0 65*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_INIT { NUM_RCU_LVL_0 } 66*f2425b4eSPaul E. McKenney # define RCU_NODE_NAME_INIT { "rcu_node_0" } 67*f2425b4eSPaul E. McKenney # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0" } 68*f2425b4eSPaul E. McKenney #elif NR_CPUS <= RCU_FANOUT_2 69*f2425b4eSPaul E. McKenney # define RCU_NUM_LVLS 2 70*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_0 1 71*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) 72*f2425b4eSPaul E. McKenney # define NUM_RCU_NODES (NUM_RCU_LVL_0 + NUM_RCU_LVL_1) 73*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_INIT { NUM_RCU_LVL_0, NUM_RCU_LVL_1 } 74*f2425b4eSPaul E. McKenney # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1" } 75*f2425b4eSPaul E. McKenney # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1" } 76*f2425b4eSPaul E. McKenney #elif NR_CPUS <= RCU_FANOUT_3 77*f2425b4eSPaul E. McKenney # define RCU_NUM_LVLS 3 78*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_0 1 79*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) 80*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) 81*f2425b4eSPaul E. McKenney # define NUM_RCU_NODES (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2) 82*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_INIT { NUM_RCU_LVL_0, NUM_RCU_LVL_1, NUM_RCU_LVL_2 } 83*f2425b4eSPaul E. McKenney # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2" } 84*f2425b4eSPaul E. McKenney # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2" } 85*f2425b4eSPaul E. McKenney #elif NR_CPUS <= RCU_FANOUT_4 86*f2425b4eSPaul E. McKenney # define RCU_NUM_LVLS 4 87*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_0 1 88*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) 89*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) 90*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_3 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) 91*f2425b4eSPaul E. McKenney # define NUM_RCU_NODES (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3) 92*f2425b4eSPaul E. McKenney # define NUM_RCU_LVL_INIT { NUM_RCU_LVL_0, NUM_RCU_LVL_1, NUM_RCU_LVL_2, NUM_RCU_LVL_3 } 93*f2425b4eSPaul E. McKenney # define RCU_NODE_NAME_INIT { "rcu_node_0", "rcu_node_1", "rcu_node_2", "rcu_node_3" } 94*f2425b4eSPaul E. McKenney # define RCU_FQS_NAME_INIT { "rcu_node_fqs_0", "rcu_node_fqs_1", "rcu_node_fqs_2", "rcu_node_fqs_3" } 95*f2425b4eSPaul E. McKenney #else 96*f2425b4eSPaul E. McKenney # error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" 97*f2425b4eSPaul E. McKenney #endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */ 98*f2425b4eSPaul E. McKenney 99*f2425b4eSPaul E. McKenney extern int rcu_num_lvls; 100*f2425b4eSPaul E. McKenney extern int rcu_num_nodes; 101*f2425b4eSPaul E. McKenney 102*f2425b4eSPaul E. McKenney #endif /* __LINUX_RCU_NODE_TREE_H */ 103