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>
pull/1354/merge
Valentin Schneider 2025-10-10 17:38:13 +02:00 committed by Frederic Weisbecker
parent 3a86608788
commit d1e6d27738
2 changed files with 52 additions and 7 deletions

View File

@ -18,12 +18,6 @@ enum ctx_state {
CT_STATE_MAX = 4,
};
/* Odd value for watching, else even. */
#define CT_RCU_WATCHING CT_STATE_MAX
#define CT_STATE_MASK (CT_STATE_MAX - 1)
#define CT_RCU_WATCHING_MASK (~CT_STATE_MASK)
struct context_tracking {
#ifdef CONFIG_CONTEXT_TRACKING_USER
/*
@ -44,9 +38,45 @@ struct context_tracking {
#endif
};
/*
* We cram two different things within the same atomic variable:
*
* CT_RCU_WATCHING_START CT_STATE_START
* | |
* v v
* MSB [ RCU watching counter ][ context_state ] LSB
* ^ ^
* | |
* CT_RCU_WATCHING_END CT_STATE_END
*
* Bits are used from the LSB upwards, so unused bits (if any) will always be in
* upper bits of the variable.
*/
#ifdef CONFIG_CONTEXT_TRACKING
#define CT_SIZE (sizeof(((struct context_tracking *)0)->state) * BITS_PER_BYTE)
#define CT_STATE_WIDTH bits_per(CT_STATE_MAX - 1)
#define CT_STATE_START 0
#define CT_STATE_END (CT_STATE_START + CT_STATE_WIDTH - 1)
#define CT_RCU_WATCHING_MAX_WIDTH (CT_SIZE - CT_STATE_WIDTH)
#define CT_RCU_WATCHING_WIDTH (IS_ENABLED(CONFIG_RCU_DYNTICKS_TORTURE) ? 2 : CT_RCU_WATCHING_MAX_WIDTH)
#define CT_RCU_WATCHING_START (CT_STATE_END + 1)
#define CT_RCU_WATCHING_END (CT_RCU_WATCHING_START + CT_RCU_WATCHING_WIDTH - 1)
#define CT_RCU_WATCHING BIT(CT_RCU_WATCHING_START)
#define CT_STATE_MASK GENMASK(CT_STATE_END, CT_STATE_START)
#define CT_RCU_WATCHING_MASK GENMASK(CT_RCU_WATCHING_END, CT_RCU_WATCHING_START)
#define CT_UNUSED_WIDTH (CT_RCU_WATCHING_MAX_WIDTH - CT_RCU_WATCHING_WIDTH)
static_assert(CT_STATE_WIDTH +
CT_RCU_WATCHING_WIDTH +
CT_UNUSED_WIDTH ==
CT_SIZE);
DECLARE_PER_CPU(struct context_tracking, context_tracking);
#endif
#endif /* CONFIG_CONTEXT_TRACKING */
#ifdef CONFIG_CONTEXT_TRACKING_USER
static __always_inline int __ct_state(void)

View File

@ -213,4 +213,19 @@ config RCU_STRICT_GRACE_PERIOD
when looking for certain types of RCU usage bugs, for example,
too-short RCU read-side critical sections.
config RCU_DYNTICKS_TORTURE
bool "Minimize RCU dynticks counter size"
depends on RCU_EXPERT && !COMPILE_TEST
default n
help
This option sets the width of the dynticks counter to its
minimum usable value. This minimum width greatly increases
the probability of flushing out bugs involving counter wrap,
but it also increases the probability of extending grace period
durations. This Kconfig option should therefore be avoided in
production due to the consequent increased probability of OOMs.
This has no value for production and is only for testing.
endmenu # "RCU Debugging"