Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rcu: Add a small-width RCU watching counter debug option

A later commit will reduce the size of the RCU watching counter to free up
some bits for another purpose. Paul suggested adding a config option to
test the extreme case where the counter is reduced to its minimum usable
width for rcutorture to poke at, so do that.

Make it only configurable under RCU_EXPERT. While at it, add a comment to
explain the layout of context_tracking->state.

Link: http://lore.kernel.org/r/4c2cb573-168f-4806-b1d9-164e8276e66a@paulmck-laptop
Suggested-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Valentin Schneider <vschneid@redhat.com>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>

authored by

Valentin Schneider and committed by
Frederic Weisbecker
d1e6d277 3a866087

+52 -7
+37 -7
include/linux/context_tracking_state.h
··· 18 18 CT_STATE_MAX = 4, 19 19 }; 20 20 21 - /* Odd value for watching, else even. */ 22 - #define CT_RCU_WATCHING CT_STATE_MAX 23 - 24 - #define CT_STATE_MASK (CT_STATE_MAX - 1) 25 - #define CT_RCU_WATCHING_MASK (~CT_STATE_MASK) 26 - 27 21 struct context_tracking { 28 22 #ifdef CONFIG_CONTEXT_TRACKING_USER 29 23 /* ··· 38 44 #endif 39 45 }; 40 46 47 + /* 48 + * We cram two different things within the same atomic variable: 49 + * 50 + * CT_RCU_WATCHING_START CT_STATE_START 51 + * | | 52 + * v v 53 + * MSB [ RCU watching counter ][ context_state ] LSB 54 + * ^ ^ 55 + * | | 56 + * CT_RCU_WATCHING_END CT_STATE_END 57 + * 58 + * Bits are used from the LSB upwards, so unused bits (if any) will always be in 59 + * upper bits of the variable. 60 + */ 41 61 #ifdef CONFIG_CONTEXT_TRACKING 62 + #define CT_SIZE (sizeof(((struct context_tracking *)0)->state) * BITS_PER_BYTE) 63 + 64 + #define CT_STATE_WIDTH bits_per(CT_STATE_MAX - 1) 65 + #define CT_STATE_START 0 66 + #define CT_STATE_END (CT_STATE_START + CT_STATE_WIDTH - 1) 67 + 68 + #define CT_RCU_WATCHING_MAX_WIDTH (CT_SIZE - CT_STATE_WIDTH) 69 + #define CT_RCU_WATCHING_WIDTH (IS_ENABLED(CONFIG_RCU_DYNTICKS_TORTURE) ? 2 : CT_RCU_WATCHING_MAX_WIDTH) 70 + #define CT_RCU_WATCHING_START (CT_STATE_END + 1) 71 + #define CT_RCU_WATCHING_END (CT_RCU_WATCHING_START + CT_RCU_WATCHING_WIDTH - 1) 72 + #define CT_RCU_WATCHING BIT(CT_RCU_WATCHING_START) 73 + 74 + #define CT_STATE_MASK GENMASK(CT_STATE_END, CT_STATE_START) 75 + #define CT_RCU_WATCHING_MASK GENMASK(CT_RCU_WATCHING_END, CT_RCU_WATCHING_START) 76 + 77 + #define CT_UNUSED_WIDTH (CT_RCU_WATCHING_MAX_WIDTH - CT_RCU_WATCHING_WIDTH) 78 + 79 + static_assert(CT_STATE_WIDTH + 80 + CT_RCU_WATCHING_WIDTH + 81 + CT_UNUSED_WIDTH == 82 + CT_SIZE); 83 + 42 84 DECLARE_PER_CPU(struct context_tracking, context_tracking); 43 - #endif 85 + #endif /* CONFIG_CONTEXT_TRACKING */ 44 86 45 87 #ifdef CONFIG_CONTEXT_TRACKING_USER 46 88 static __always_inline int __ct_state(void)
+15
kernel/rcu/Kconfig.debug
··· 213 213 when looking for certain types of RCU usage bugs, for example, 214 214 too-short RCU read-side critical sections. 215 215 216 + 217 + config RCU_DYNTICKS_TORTURE 218 + bool "Minimize RCU dynticks counter size" 219 + depends on RCU_EXPERT && !COMPILE_TEST 220 + default n 221 + help 222 + This option sets the width of the dynticks counter to its 223 + minimum usable value. This minimum width greatly increases 224 + the probability of flushing out bugs involving counter wrap, 225 + but it also increases the probability of extending grace period 226 + durations. This Kconfig option should therefore be avoided in 227 + production due to the consequent increased probability of OOMs. 228 + 229 + This has no value for production and is only for testing. 230 + 216 231 endmenu # "RCU Debugging"