|
@@ -31,46 +31,51 @@
|
|
|
/*
|
|
|
* Define shape of hierarchy based on NR_CPUS and CONFIG_RCU_FANOUT.
|
|
|
* In theory, it should be possible to add more levels straightforwardly.
|
|
|
- * In practice, this has not been tested, so there is probably some
|
|
|
- * bug somewhere.
|
|
|
+ * In practice, this did work well going from three levels to four.
|
|
|
+ * Of course, your mileage may vary.
|
|
|
*/
|
|
|
#define MAX_RCU_LVLS 4
|
|
|
-#define RCU_FANOUT (CONFIG_RCU_FANOUT)
|
|
|
-#define RCU_FANOUT_SQ (RCU_FANOUT * RCU_FANOUT)
|
|
|
-#define RCU_FANOUT_CUBE (RCU_FANOUT_SQ * RCU_FANOUT)
|
|
|
-#define RCU_FANOUT_FOURTH (RCU_FANOUT_CUBE * RCU_FANOUT)
|
|
|
-
|
|
|
-#if NR_CPUS <= RCU_FANOUT
|
|
|
+#if CONFIG_RCU_FANOUT > 16
|
|
|
+#define RCU_FANOUT_LEAF 16
|
|
|
+#else /* #if CONFIG_RCU_FANOUT > 16 */
|
|
|
+#define RCU_FANOUT_LEAF (CONFIG_RCU_FANOUT)
|
|
|
+#endif /* #else #if CONFIG_RCU_FANOUT > 16 */
|
|
|
+#define RCU_FANOUT_1 (RCU_FANOUT_LEAF)
|
|
|
+#define RCU_FANOUT_2 (RCU_FANOUT_1 * CONFIG_RCU_FANOUT)
|
|
|
+#define RCU_FANOUT_3 (RCU_FANOUT_2 * CONFIG_RCU_FANOUT)
|
|
|
+#define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT)
|
|
|
+
|
|
|
+#if NR_CPUS <= RCU_FANOUT_1
|
|
|
# define NUM_RCU_LVLS 1
|
|
|
# define NUM_RCU_LVL_0 1
|
|
|
# define NUM_RCU_LVL_1 (NR_CPUS)
|
|
|
# define NUM_RCU_LVL_2 0
|
|
|
# define NUM_RCU_LVL_3 0
|
|
|
# define NUM_RCU_LVL_4 0
|
|
|
-#elif NR_CPUS <= RCU_FANOUT_SQ
|
|
|
+#elif NR_CPUS <= RCU_FANOUT_2
|
|
|
# define NUM_RCU_LVLS 2
|
|
|
# define NUM_RCU_LVL_0 1
|
|
|
-# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
|
|
|
+# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
|
|
|
# define NUM_RCU_LVL_2 (NR_CPUS)
|
|
|
# define NUM_RCU_LVL_3 0
|
|
|
# define NUM_RCU_LVL_4 0
|
|
|
-#elif NR_CPUS <= RCU_FANOUT_CUBE
|
|
|
+#elif NR_CPUS <= RCU_FANOUT_3
|
|
|
# define NUM_RCU_LVLS 3
|
|
|
# define NUM_RCU_LVL_0 1
|
|
|
-# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
|
|
|
-# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
|
|
|
-# define NUM_RCU_LVL_3 NR_CPUS
|
|
|
+# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2)
|
|
|
+# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
|
|
|
+# define NUM_RCU_LVL_3 (NR_CPUS)
|
|
|
# define NUM_RCU_LVL_4 0
|
|
|
-#elif NR_CPUS <= RCU_FANOUT_FOURTH
|
|
|
+#elif NR_CPUS <= RCU_FANOUT_4
|
|
|
# define NUM_RCU_LVLS 4
|
|
|
# define NUM_RCU_LVL_0 1
|
|
|
-# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_CUBE)
|
|
|
-# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
|
|
|
-# define NUM_RCU_LVL_3 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
|
|
|
-# define NUM_RCU_LVL_4 NR_CPUS
|
|
|
+# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3)
|
|
|
+# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2)
|
|
|
+# define NUM_RCU_LVL_3 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1)
|
|
|
+# define NUM_RCU_LVL_4 (NR_CPUS)
|
|
|
#else
|
|
|
# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
|
|
|
-#endif /* #if (NR_CPUS) <= RCU_FANOUT */
|
|
|
+#endif /* #if (NR_CPUS) <= RCU_FANOUT_1 */
|
|
|
|
|
|
#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4)
|
|
|
#define NUM_RCU_NODES (RCU_SUM - NR_CPUS)
|