Skip to content

Commit d1e6d27

Browse files
valschneiderFrederic Weisbecker
authored andcommitted
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>
1 parent 3a86608 commit d1e6d27

2 files changed

Lines changed: 52 additions & 7 deletions

File tree

include/linux/context_tracking_state.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ enum ctx_state {
1818
CT_STATE_MAX = 4,
1919
};
2020

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-
2721
struct context_tracking {
2822
#ifdef CONFIG_CONTEXT_TRACKING_USER
2923
/*
@@ -44,9 +38,45 @@ struct context_tracking {
4438
#endif
4539
};
4640

41+
/*
42+
* We cram two different things within the same atomic variable:
43+
*
44+
* CT_RCU_WATCHING_START CT_STATE_START
45+
* | |
46+
* v v
47+
* MSB [ RCU watching counter ][ context_state ] LSB
48+
* ^ ^
49+
* | |
50+
* CT_RCU_WATCHING_END CT_STATE_END
51+
*
52+
* Bits are used from the LSB upwards, so unused bits (if any) will always be in
53+
* upper bits of the variable.
54+
*/
4755
#ifdef CONFIG_CONTEXT_TRACKING
56+
#define CT_SIZE (sizeof(((struct context_tracking *)0)->state) * BITS_PER_BYTE)
57+
58+
#define CT_STATE_WIDTH bits_per(CT_STATE_MAX - 1)
59+
#define CT_STATE_START 0
60+
#define CT_STATE_END (CT_STATE_START + CT_STATE_WIDTH - 1)
61+
62+
#define CT_RCU_WATCHING_MAX_WIDTH (CT_SIZE - CT_STATE_WIDTH)
63+
#define CT_RCU_WATCHING_WIDTH (IS_ENABLED(CONFIG_RCU_DYNTICKS_TORTURE) ? 2 : CT_RCU_WATCHING_MAX_WIDTH)
64+
#define CT_RCU_WATCHING_START (CT_STATE_END + 1)
65+
#define CT_RCU_WATCHING_END (CT_RCU_WATCHING_START + CT_RCU_WATCHING_WIDTH - 1)
66+
#define CT_RCU_WATCHING BIT(CT_RCU_WATCHING_START)
67+
68+
#define CT_STATE_MASK GENMASK(CT_STATE_END, CT_STATE_START)
69+
#define CT_RCU_WATCHING_MASK GENMASK(CT_RCU_WATCHING_END, CT_RCU_WATCHING_START)
70+
71+
#define CT_UNUSED_WIDTH (CT_RCU_WATCHING_MAX_WIDTH - CT_RCU_WATCHING_WIDTH)
72+
73+
static_assert(CT_STATE_WIDTH +
74+
CT_RCU_WATCHING_WIDTH +
75+
CT_UNUSED_WIDTH ==
76+
CT_SIZE);
77+
4878
DECLARE_PER_CPU(struct context_tracking, context_tracking);
49-
#endif
79+
#endif /* CONFIG_CONTEXT_TRACKING */
5080

5181
#ifdef CONFIG_CONTEXT_TRACKING_USER
5282
static __always_inline int __ct_state(void)

kernel/rcu/Kconfig.debug

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,19 @@ config RCU_STRICT_GRACE_PERIOD
213213
when looking for certain types of RCU usage bugs, for example,
214214
too-short RCU read-side critical sections.
215215

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+
216231
endmenu # "RCU Debugging"

0 commit comments

Comments
 (0)