* [PATCH] srcutiny: Enable atomic SRCU flavor tracking
@ 2026-09-01 7:48 Kunwu Chan
2026-09-01 17:11 ` Paul E. McKenney
0 siblings, 1 reply; 5+ messages in thread
From: Kunwu Chan @ 2026-09-01 7:48 UTC (permalink / raw)
To: jiangshanlai, paulmck, josh, rostedt, mathieu.desnoyers
Cc: rcu, linux-kernel, Kunwu Chan
From: Kunwu Chan <kunwu.chan@gmail.com>
Set srcu_reader_flavor to SRCU_READ_FLAVOR_ATOMIC in the Tiny SRCU
atomic initialization paths, so that the entry-point checks added by
the previous commit can identify atomic SRCU domains.
For static initialization, add a flavor parameter to
__SRCU_STRUCT_INIT() and pass SRCU_READ_FLAVOR_ATOMIC through
DEFINE_SRCU_ATOMIC() and DEFINE_STATIC_SRCU_ATOMIC().
For dynamic initialization, initialize srcu_reader_flavor to zero in
init_srcu_struct_fields() for the generic initialization path, and
set it to SRCU_READ_FLAVOR_ATOMIC in init_srcu_struct_atomic().
Handle both CONFIG_DEBUG_LOCK_ALLOC and non-debug initialization paths.
Enable srcu_check_read_flavor() for Tiny SRCU, matching the Tree SRCU
behavior, so that readers can verify that the requested flavor matches
the SRCU domain.
Signed-off-by: Kunwu Chan <kunwu.chan@gmail.com>
---
include/linux/srcutiny.h | 39 +++++++++++++++++++++++++++++----------
kernel/rcu/srcutiny.c | 1 +
2 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
index 2b293336525a..9dce4b5aa084 100644
--- a/include/linux/srcutiny.h
+++ b/include/linux/srcutiny.h
@@ -40,7 +40,7 @@ void srcu_drive_gp(struct work_struct *wp);
void srcu_tiny_irq_work(struct irq_work *irq_work);
void srcu_defer_drain(struct irq_work *irq_work);
-#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \
+#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, flavor) \
{ \
.srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
.srcu_cb_tail = &name.srcu_cb_head, \
@@ -49,6 +49,7 @@ void srcu_defer_drain(struct irq_work *irq_work);
.defer_cbs = LLIST_HEAD_INIT(name.defer_cbs), \
.defer_iw = { .node = { .u_flags = IRQ_WORK_HARD_IRQ }, \
.func = srcu_defer_drain }, \
+ .srcu_reader_flavor = flavor, \
__SRCU_DEP_MAP_INIT(name) \
}
@@ -57,29 +58,43 @@ void srcu_defer_drain(struct irq_work *irq_work);
* Tree SRCU, which needs some per-CPU data.
*/
#define DEFINE_SRCU(name) \
- struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
+ struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
#define DEFINE_STATIC_SRCU(name) \
- static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
+ static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
#define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name)
#define DEFINE_STATIC_SRCU_FAST(name) \
- static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
+ static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
#define DEFINE_SRCU_FAST_UPDOWN(name) DEFINE_SRCU(name)
#define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
- static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
-#define DEFINE_SRCU_ATOMIC(name) DEFINE_SRCU(name)
+ static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
+#define DEFINE_SRCU_ATOMIC(name) \
+ struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
#define DEFINE_STATIC_SRCU_ATOMIC(name) \
- static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
+ static struct srcu_struct name = \
+ __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
// Dummy structure for srcu_notifier_head.
struct srcu_usage { };
#define __SRCU_USAGE_INIT(name) { }
#define __init_srcu_struct_fast __init_srcu_struct
#define __init_srcu_struct_fast_updown __init_srcu_struct
-#define __init_srcu_struct_atomic __init_srcu_struct
+#define __init_srcu_struct_atomic(ssp, name, key) \
+({ \
+ int __ret = __init_srcu_struct(ssp, name, key); \
+ if (!__ret) \
+ (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC; \
+ __ret; \
+})
#ifndef CONFIG_DEBUG_LOCK_ALLOC
#define init_srcu_struct_fast init_srcu_struct
#define init_srcu_struct_fast_updown init_srcu_struct
-#define init_srcu_struct_atomic init_srcu_struct
+#define init_srcu_struct_atomic(ssp) \
+ ({ \
+ int __ret = init_srcu_struct(ssp); \
+ if (!__ret) \
+ (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC;\
+ __ret; \
+ })
#endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC
void synchronize_srcu(struct srcu_struct *ssp);
@@ -148,7 +163,11 @@ static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)
void srcu_barrier(struct srcu_struct *ssp);
static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
-#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
+#define srcu_check_read_flavor(ssp, read_flavor) \
+ ({ \
+ u8 __f = (ssp)->srcu_reader_flavor; \
+ WARN_ON_ONCE(__f && !(__f & (read_flavor))); \
+ })
/* Defined here to avoid size increase for non-torture kernels. */
static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
index 22f7716cbb0e..873b30ccf563 100644
--- a/kernel/rcu/srcutiny.c
+++ b/kernel/rcu/srcutiny.c
@@ -42,6 +42,7 @@ static int init_srcu_struct_fields(struct srcu_struct *ssp)
ssp->srcu_gp_running = false;
ssp->srcu_gp_waiting = false;
ssp->srcu_atomic_gp_flag = 0;
+ ssp->srcu_reader_flavor = 0;
ssp->srcu_idx = 0;
ssp->srcu_idx_max = 0;
INIT_WORK(&ssp->srcu_work, srcu_drive_gp);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] srcutiny: Enable atomic SRCU flavor tracking
2026-09-01 7:48 [PATCH] srcutiny: Enable atomic SRCU flavor tracking Kunwu Chan
@ 2026-09-01 17:11 ` Paul E. McKenney
2026-09-02 9:18 ` KunWu Chan
0 siblings, 1 reply; 5+ messages in thread
From: Paul E. McKenney @ 2026-09-01 17:11 UTC (permalink / raw)
To: Kunwu Chan
Cc: jiangshanlai, josh, rostedt, mathieu.desnoyers, rcu, linux-kernel
On Tue, Sep 01, 2026 at 03:48:15PM +0800, Kunwu Chan wrote:
> From: Kunwu Chan <kunwu.chan@gmail.com>
>
> Set srcu_reader_flavor to SRCU_READ_FLAVOR_ATOMIC in the Tiny SRCU
> atomic initialization paths, so that the entry-point checks added by
> the previous commit can identify atomic SRCU domains.
>
> For static initialization, add a flavor parameter to
> __SRCU_STRUCT_INIT() and pass SRCU_READ_FLAVOR_ATOMIC through
> DEFINE_SRCU_ATOMIC() and DEFINE_STATIC_SRCU_ATOMIC().
>
> For dynamic initialization, initialize srcu_reader_flavor to zero in
> init_srcu_struct_fields() for the generic initialization path, and
> set it to SRCU_READ_FLAVOR_ATOMIC in init_srcu_struct_atomic().
> Handle both CONFIG_DEBUG_LOCK_ALLOC and non-debug initialization paths.
>
> Enable srcu_check_read_flavor() for Tiny SRCU, matching the Tree SRCU
> behavior, so that readers can verify that the requested flavor matches
> the SRCU domain.
>
> Signed-off-by: Kunwu Chan <kunwu.chan@gmail.com>
Much better! Please see below for additional questions and comments.
> ---
> include/linux/srcutiny.h | 39 +++++++++++++++++++++++++++++----------
> kernel/rcu/srcutiny.c | 1 +
> 2 files changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
> index 2b293336525a..9dce4b5aa084 100644
> --- a/include/linux/srcutiny.h
> +++ b/include/linux/srcutiny.h
> @@ -40,7 +40,7 @@ void srcu_drive_gp(struct work_struct *wp);
> void srcu_tiny_irq_work(struct irq_work *irq_work);
> void srcu_defer_drain(struct irq_work *irq_work);
>
> -#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \
> +#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, flavor) \
> { \
> .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
> .srcu_cb_tail = &name.srcu_cb_head, \
> @@ -49,6 +49,7 @@ void srcu_defer_drain(struct irq_work *irq_work);
> .defer_cbs = LLIST_HEAD_INIT(name.defer_cbs), \
> .defer_iw = { .node = { .u_flags = IRQ_WORK_HARD_IRQ }, \
> .func = srcu_defer_drain }, \
> + .srcu_reader_flavor = flavor, \
Don't we also need to define srcu_reader_flavor? Or is this patch
supposed to be applied on top of your previous one?
> __SRCU_DEP_MAP_INIT(name) \
> }
>
> @@ -57,29 +58,43 @@ void srcu_defer_drain(struct irq_work *irq_work);
> * Tree SRCU, which needs some per-CPU data.
> */
> #define DEFINE_SRCU(name) \
> - struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> #define DEFINE_STATIC_SRCU(name) \
> - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> #define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name)
> #define DEFINE_STATIC_SRCU_FAST(name) \
> - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> #define DEFINE_SRCU_FAST_UPDOWN(name) DEFINE_SRCU(name)
> #define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
> - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> -#define DEFINE_SRCU_ATOMIC(name) DEFINE_SRCU(name)
> + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> +#define DEFINE_SRCU_ATOMIC(name) \
> + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> #define DEFINE_STATIC_SRCU_ATOMIC(name) \
> - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> + static struct srcu_struct name = \
> + __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
>
> // Dummy structure for srcu_notifier_head.
> struct srcu_usage { };
> #define __SRCU_USAGE_INIT(name) { }
> #define __init_srcu_struct_fast __init_srcu_struct
> #define __init_srcu_struct_fast_updown __init_srcu_struct
> -#define __init_srcu_struct_atomic __init_srcu_struct
> +#define __init_srcu_struct_atomic(ssp, name, key) \
> +({ \
> + int __ret = __init_srcu_struct(ssp, name, key); \
> + if (!__ret) \
> + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC; \
> + __ret; \
> +})
> #ifndef CONFIG_DEBUG_LOCK_ALLOC
> #define init_srcu_struct_fast init_srcu_struct
> #define init_srcu_struct_fast_updown init_srcu_struct
> -#define init_srcu_struct_atomic init_srcu_struct
> +#define init_srcu_struct_atomic(ssp) \
> + ({ \
> + int __ret = init_srcu_struct(ssp); \
> + if (!__ret) \
> + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC;\
> + __ret; \
> + })
> #endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC
>
> void synchronize_srcu(struct srcu_struct *ssp);
> @@ -148,7 +163,11 @@ static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)
> void srcu_barrier(struct srcu_struct *ssp);
>
> static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
> -#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
> +#define srcu_check_read_flavor(ssp, read_flavor) \
> + ({ \
> + u8 __f = (ssp)->srcu_reader_flavor; \
> + WARN_ON_ONCE(__f && !(__f & (read_flavor))); \
> + })
Why not make this a static inline function, along with
__init_srcu_struct_atomic() and init_srcu_struct_atomic() above?
That should simplify the code.
> /* Defined here to avoid size increase for non-torture kernels. */
> static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
> diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
> index 22f7716cbb0e..873b30ccf563 100644
> --- a/kernel/rcu/srcutiny.c
> +++ b/kernel/rcu/srcutiny.c
> @@ -42,6 +42,7 @@ static int init_srcu_struct_fields(struct srcu_struct *ssp)
> ssp->srcu_gp_running = false;
> ssp->srcu_gp_waiting = false;
> ssp->srcu_atomic_gp_flag = 0;
> + ssp->srcu_reader_flavor = 0;
> ssp->srcu_idx = 0;
> ssp->srcu_idx_max = 0;
> INIT_WORK(&ssp->srcu_work, srcu_drive_gp);
> --
> 2.43.0
One of the purposes of Tiny SRCU is to be tiny, and one could argue
that Tiny SRCU already has too much diagnostic code. Should we include
these patches at all? If we should, shouldn't they be under something
like CONFIG_PROVE_RCU? Should some of the existing Tiny SRCU debugging
code also be under something like CONFIG_PROVE_RCU?
Thoughts?
Thanx, Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] srcutiny: Enable atomic SRCU flavor tracking
2026-09-01 17:11 ` Paul E. McKenney
@ 2026-09-02 9:18 ` KunWu Chan
2026-09-02 15:43 ` Paul E. McKenney
0 siblings, 1 reply; 5+ messages in thread
From: KunWu Chan @ 2026-09-02 9:18 UTC (permalink / raw)
To: paulmck; +Cc: jiangshanlai, josh, rostedt, mathieu.desnoyers, rcu, linux-kernel
On Wed, Sep 2, 2026 at 1:11 AM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> On Tue, Sep 01, 2026 at 03:48:15PM +0800, Kunwu Chan wrote:
> > From: Kunwu Chan <kunwu.chan@gmail.com>
> >
> > Set srcu_reader_flavor to SRCU_READ_FLAVOR_ATOMIC in the Tiny SRCU
> > atomic initialization paths, so that the entry-point checks added by
> > the previous commit can identify atomic SRCU domains.
> >
> > For static initialization, add a flavor parameter to
> > __SRCU_STRUCT_INIT() and pass SRCU_READ_FLAVOR_ATOMIC through
> > DEFINE_SRCU_ATOMIC() and DEFINE_STATIC_SRCU_ATOMIC().
> >
> > For dynamic initialization, initialize srcu_reader_flavor to zero in
> > init_srcu_struct_fields() for the generic initialization path, and
> > set it to SRCU_READ_FLAVOR_ATOMIC in init_srcu_struct_atomic().
> > Handle both CONFIG_DEBUG_LOCK_ALLOC and non-debug initialization paths.
> >
> > Enable srcu_check_read_flavor() for Tiny SRCU, matching the Tree SRCU
> > behavior, so that readers can verify that the requested flavor matches
> > the SRCU domain.
> >
> > Signed-off-by: Kunwu Chan <kunwu.chan@gmail.com>
>
> Much better! Please see below for additional questions and comments.
Thanks Paul for the detailed reply.
>
> > ---
> > include/linux/srcutiny.h | 39 +++++++++++++++++++++++++++++----------
> > kernel/rcu/srcutiny.c | 1 +
> > 2 files changed, 30 insertions(+), 10 deletions(-)
> >
> > diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
> > index 2b293336525a..9dce4b5aa084 100644
> > --- a/include/linux/srcutiny.h
> > +++ b/include/linux/srcutiny.h
> > @@ -40,7 +40,7 @@ void srcu_drive_gp(struct work_struct *wp);
> > void srcu_tiny_irq_work(struct irq_work *irq_work);
> > void srcu_defer_drain(struct irq_work *irq_work);
> >
> > -#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \
> > +#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, flavor) \
> > { \
> > .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
> > .srcu_cb_tail = &name.srcu_cb_head, \
> > @@ -49,6 +49,7 @@ void srcu_defer_drain(struct irq_work *irq_work);
> > .defer_cbs = LLIST_HEAD_INIT(name.defer_cbs), \
> > .defer_iw = { .node = { .u_flags = IRQ_WORK_HARD_IRQ }, \
> > .func = srcu_defer_drain }, \
> > + .srcu_reader_flavor = flavor, \
>
> Don't we also need to define srcu_reader_flavor? Or is this patch
> supposed to be applied on top of your previous one?
Yes, this is intended to be applied on top of the previous one [1].
[1] https://lore.kernel.org/rcu/20260831074937.2380914-1-kunwu.chan@linux.dev/
>
> > __SRCU_DEP_MAP_INIT(name) \
> > }
> >
> > @@ -57,29 +58,43 @@ void srcu_defer_drain(struct irq_work *irq_work);
> > * Tree SRCU, which needs some per-CPU data.
> > */
> > #define DEFINE_SRCU(name) \
> > - struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > #define DEFINE_STATIC_SRCU(name) \
> > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > #define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name)
> > #define DEFINE_STATIC_SRCU_FAST(name) \
> > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > #define DEFINE_SRCU_FAST_UPDOWN(name) DEFINE_SRCU(name)
> > #define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
> > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > -#define DEFINE_SRCU_ATOMIC(name) DEFINE_SRCU(name)
> > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > +#define DEFINE_SRCU_ATOMIC(name) \
> > + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> > #define DEFINE_STATIC_SRCU_ATOMIC(name) \
> > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > + static struct srcu_struct name = \
> > + __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> >
> > // Dummy structure for srcu_notifier_head.
> > struct srcu_usage { };
> > #define __SRCU_USAGE_INIT(name) { }
> > #define __init_srcu_struct_fast __init_srcu_struct
> > #define __init_srcu_struct_fast_updown __init_srcu_struct
> > -#define __init_srcu_struct_atomic __init_srcu_struct
> > +#define __init_srcu_struct_atomic(ssp, name, key) \
> > +({ \
> > + int __ret = __init_srcu_struct(ssp, name, key); \
> > + if (!__ret) \
> > + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC; \
> > + __ret; \
> > +})
> > #ifndef CONFIG_DEBUG_LOCK_ALLOC
> > #define init_srcu_struct_fast init_srcu_struct
> > #define init_srcu_struct_fast_updown init_srcu_struct
> > -#define init_srcu_struct_atomic init_srcu_struct
> > +#define init_srcu_struct_atomic(ssp) \
> > + ({ \
> > + int __ret = init_srcu_struct(ssp); \
> > + if (!__ret) \
> > + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC;\
> > + __ret; \
> > + })
> > #endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC
> >
> > void synchronize_srcu(struct srcu_struct *ssp);
> > @@ -148,7 +163,11 @@ static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)
> > void srcu_barrier(struct srcu_struct *ssp);
> >
> > static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
> > -#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
> > +#define srcu_check_read_flavor(ssp, read_flavor) \
> > + ({ \
> > + u8 __f = (ssp)->srcu_reader_flavor; \
> > + WARN_ON_ONCE(__f && !(__f & (read_flavor))); \
> > + })
>
> Why not make this a static inline function, along with
> __init_srcu_struct_atomic() and init_srcu_struct_atomic() above?
> That should simplify the code.
Thanks. I’ll rework the initialization helpers as static inline
functions as suggested.
>
> > /* Defined here to avoid size increase for non-torture kernels. */
> > static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
> > diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
> > index 22f7716cbb0e..873b30ccf563 100644
> > --- a/kernel/rcu/srcutiny.c
> > +++ b/kernel/rcu/srcutiny.c
> > @@ -42,6 +42,7 @@ static int init_srcu_struct_fields(struct srcu_struct *ssp)
> > ssp->srcu_gp_running = false;
> > ssp->srcu_gp_waiting = false;
> > ssp->srcu_atomic_gp_flag = 0;
> > + ssp->srcu_reader_flavor = 0;
> > ssp->srcu_idx = 0;
> > ssp->srcu_idx_max = 0;
> > INIT_WORK(&ssp->srcu_work, srcu_drive_gp);
> > --
> > 2.43.0
>
> One of the purposes of Tiny SRCU is to be tiny, and one could argue
> that Tiny SRCU already has too much diagnostic code. Should we include
> these patches at all? If we should, shouldn't they be under something
> like CONFIG_PROVE_RCU? Should some of the existing Tiny SRCU debugging
> code also be under something like CONFIG_PROVE_RCU?
>
> Thoughts?
I agree that Tiny SRCU should keep its core as small as possible, so I think
it is worth reconsidering how much diagnostic machinery we want to add here.
For srcu_reader_flavor, I did have some hesitation when adding it.
Tiny SRCU did not previously have the concept of a reader flavor; I
mainly added it
to distinguish Tiny Atomic SRCU, following the approach used by Tree
SRCU. If we still
need state for this purpose, perhaps a one-bit flag would be sufficient.
One question is whether the flavor checking really needs to be part of
srcutiny.c.
I think there are two somewhat different cases:
1: checking for invalid API usage, where the purpose is to detect or
stop misuse;
2: defensive handling of an invalid call, where we redirect to a safe
implementation,
like in synchronize_srcu.
The first case seems more like diagnostic functionality and could
potentially be handled
in the common SRCU API layer under CONFIG_PROVE_RCU. The second case affects
runtime behavior and should remain independent of CONFIG_PROVE_RCU.
This makes me wonder whether the common flavor validation could live in srcu.h,
as part of the common SRCU interface, rather than adding more checking
logic to srcutiny.c.
That could centralize the validation and keep the Tiny SRCU
implementation easier to follow,
although it would add another wrapper layer, such as a macro or static inline.
Thanks,
Kunwu
>
> Thanx, Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] srcutiny: Enable atomic SRCU flavor tracking
2026-09-02 9:18 ` KunWu Chan
@ 2026-09-02 15:43 ` Paul E. McKenney
2026-09-02 16:29 ` KunWu Chan
0 siblings, 1 reply; 5+ messages in thread
From: Paul E. McKenney @ 2026-09-02 15:43 UTC (permalink / raw)
To: KunWu Chan
Cc: jiangshanlai, josh, rostedt, mathieu.desnoyers, rcu, linux-kernel
On Wed, Sep 02, 2026 at 05:18:50PM +0800, KunWu Chan wrote:
> On Wed, Sep 2, 2026 at 1:11 AM Paul E. McKenney <paulmck@kernel.org> wrote:
> >
> > On Tue, Sep 01, 2026 at 03:48:15PM +0800, Kunwu Chan wrote:
> > > From: Kunwu Chan <kunwu.chan@gmail.com>
> > >
> > > Set srcu_reader_flavor to SRCU_READ_FLAVOR_ATOMIC in the Tiny SRCU
> > > atomic initialization paths, so that the entry-point checks added by
> > > the previous commit can identify atomic SRCU domains.
> > >
> > > For static initialization, add a flavor parameter to
> > > __SRCU_STRUCT_INIT() and pass SRCU_READ_FLAVOR_ATOMIC through
> > > DEFINE_SRCU_ATOMIC() and DEFINE_STATIC_SRCU_ATOMIC().
> > >
> > > For dynamic initialization, initialize srcu_reader_flavor to zero in
> > > init_srcu_struct_fields() for the generic initialization path, and
> > > set it to SRCU_READ_FLAVOR_ATOMIC in init_srcu_struct_atomic().
> > > Handle both CONFIG_DEBUG_LOCK_ALLOC and non-debug initialization paths.
> > >
> > > Enable srcu_check_read_flavor() for Tiny SRCU, matching the Tree SRCU
> > > behavior, so that readers can verify that the requested flavor matches
> > > the SRCU domain.
> > >
> > > Signed-off-by: Kunwu Chan <kunwu.chan@gmail.com>
> >
> > Much better! Please see below for additional questions and comments.
>
> Thanks Paul for the detailed reply.
>
> >
> > > ---
> > > include/linux/srcutiny.h | 39 +++++++++++++++++++++++++++++----------
> > > kernel/rcu/srcutiny.c | 1 +
> > > 2 files changed, 30 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
> > > index 2b293336525a..9dce4b5aa084 100644
> > > --- a/include/linux/srcutiny.h
> > > +++ b/include/linux/srcutiny.h
> > > @@ -40,7 +40,7 @@ void srcu_drive_gp(struct work_struct *wp);
> > > void srcu_tiny_irq_work(struct irq_work *irq_work);
> > > void srcu_defer_drain(struct irq_work *irq_work);
> > >
> > > -#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \
> > > +#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, flavor) \
> > > { \
> > > .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
> > > .srcu_cb_tail = &name.srcu_cb_head, \
> > > @@ -49,6 +49,7 @@ void srcu_defer_drain(struct irq_work *irq_work);
> > > .defer_cbs = LLIST_HEAD_INIT(name.defer_cbs), \
> > > .defer_iw = { .node = { .u_flags = IRQ_WORK_HARD_IRQ }, \
> > > .func = srcu_defer_drain }, \
> > > + .srcu_reader_flavor = flavor, \
> >
> > Don't we also need to define srcu_reader_flavor? Or is this patch
> > supposed to be applied on top of your previous one?
>
> Yes, this is intended to be applied on top of the previous one [1].
> [1] https://lore.kernel.org/rcu/20260831074937.2380914-1-kunwu.chan@linux.dev/
>
> > > __SRCU_DEP_MAP_INIT(name) \
> > > }
> > >
> > > @@ -57,29 +58,43 @@ void srcu_defer_drain(struct irq_work *irq_work);
> > > * Tree SRCU, which needs some per-CPU data.
> > > */
> > > #define DEFINE_SRCU(name) \
> > > - struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > #define DEFINE_STATIC_SRCU(name) \
> > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > #define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name)
> > > #define DEFINE_STATIC_SRCU_FAST(name) \
> > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > #define DEFINE_SRCU_FAST_UPDOWN(name) DEFINE_SRCU(name)
> > > #define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
> > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > -#define DEFINE_SRCU_ATOMIC(name) DEFINE_SRCU(name)
> > > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > +#define DEFINE_SRCU_ATOMIC(name) \
> > > + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> > > #define DEFINE_STATIC_SRCU_ATOMIC(name) \
> > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > + static struct srcu_struct name = \
> > > + __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> > >
> > > // Dummy structure for srcu_notifier_head.
> > > struct srcu_usage { };
> > > #define __SRCU_USAGE_INIT(name) { }
> > > #define __init_srcu_struct_fast __init_srcu_struct
> > > #define __init_srcu_struct_fast_updown __init_srcu_struct
> > > -#define __init_srcu_struct_atomic __init_srcu_struct
> > > +#define __init_srcu_struct_atomic(ssp, name, key) \
> > > +({ \
> > > + int __ret = __init_srcu_struct(ssp, name, key); \
> > > + if (!__ret) \
> > > + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC; \
> > > + __ret; \
> > > +})
> > > #ifndef CONFIG_DEBUG_LOCK_ALLOC
> > > #define init_srcu_struct_fast init_srcu_struct
> > > #define init_srcu_struct_fast_updown init_srcu_struct
> > > -#define init_srcu_struct_atomic init_srcu_struct
> > > +#define init_srcu_struct_atomic(ssp) \
> > > + ({ \
> > > + int __ret = init_srcu_struct(ssp); \
> > > + if (!__ret) \
> > > + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC;\
> > > + __ret; \
> > > + })
> > > #endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC
> > >
> > > void synchronize_srcu(struct srcu_struct *ssp);
> > > @@ -148,7 +163,11 @@ static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)
> > > void srcu_barrier(struct srcu_struct *ssp);
> > >
> > > static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
> > > -#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
> > > +#define srcu_check_read_flavor(ssp, read_flavor) \
> > > + ({ \
> > > + u8 __f = (ssp)->srcu_reader_flavor; \
> > > + WARN_ON_ONCE(__f && !(__f & (read_flavor))); \
> > > + })
> >
> > Why not make this a static inline function, along with
> > __init_srcu_struct_atomic() and init_srcu_struct_atomic() above?
> > That should simplify the code.
>
> Thanks. I’ll rework the initialization helpers as static inline
> functions as suggested.
>
> > > /* Defined here to avoid size increase for non-torture kernels. */
> > > static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
> > > diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
> > > index 22f7716cbb0e..873b30ccf563 100644
> > > --- a/kernel/rcu/srcutiny.c
> > > +++ b/kernel/rcu/srcutiny.c
> > > @@ -42,6 +42,7 @@ static int init_srcu_struct_fields(struct srcu_struct *ssp)
> > > ssp->srcu_gp_running = false;
> > > ssp->srcu_gp_waiting = false;
> > > ssp->srcu_atomic_gp_flag = 0;
> > > + ssp->srcu_reader_flavor = 0;
> > > ssp->srcu_idx = 0;
> > > ssp->srcu_idx_max = 0;
> > > INIT_WORK(&ssp->srcu_work, srcu_drive_gp);
> > > --
> > > 2.43.0
> >
> > One of the purposes of Tiny SRCU is to be tiny, and one could argue
> > that Tiny SRCU already has too much diagnostic code. Should we include
> > these patches at all? If we should, shouldn't they be under something
> > like CONFIG_PROVE_RCU? Should some of the existing Tiny SRCU debugging
> > code also be under something like CONFIG_PROVE_RCU?
> >
> > Thoughts?
>
> I agree that Tiny SRCU should keep its core as small as possible, so I think
> it is worth reconsidering how much diagnostic machinery we want to add here.
>
> For srcu_reader_flavor, I did have some hesitation when adding it.
> Tiny SRCU did not previously have the concept of a reader flavor; I
> mainly added it
> to distinguish Tiny Atomic SRCU, following the approach used by Tree
> SRCU. If we still
> need state for this purpose, perhaps a one-bit flag would be sufficient.
>
> One question is whether the flavor checking really needs to be part of
> srcutiny.c.
> I think there are two somewhat different cases:
> 1: checking for invalid API usage, where the purpose is to detect or
> stop misuse;
> 2: defensive handling of an invalid call, where we redirect to a safe
> implementation,
> like in synchronize_srcu.
>
> The first case seems more like diagnostic functionality and could
> potentially be handled
> in the common SRCU API layer under CONFIG_PROVE_RCU. The second case affects
> runtime behavior and should remain independent of CONFIG_PROVE_RCU.
>
> This makes me wonder whether the common flavor validation could live in srcu.h,
> as part of the common SRCU interface, rather than adding more checking
> logic to srcutiny.c.
> That could centralize the validation and keep the Tiny SRCU
> implementation easier to follow,
> although it would add another wrapper layer, such as a macro or static inline.
Another approach is to let the checking in Tree SRCU cover this.
That way, the only misuses of the atomic SRCU API that are missed are
those that appear only in CONFIG_SMP=n code. And right now, there isn't
any such uses. There might be in the future, but perhaps this is quite
unlikely.
Thanx, Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] srcutiny: Enable atomic SRCU flavor tracking
2026-09-02 15:43 ` Paul E. McKenney
@ 2026-09-02 16:29 ` KunWu Chan
0 siblings, 0 replies; 5+ messages in thread
From: KunWu Chan @ 2026-09-02 16:29 UTC (permalink / raw)
To: paulmck; +Cc: jiangshanlai, josh, rostedt, mathieu.desnoyers, rcu, linux-kernel
On Wed, Sep 2, 2026 at 11:43 PM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> On Wed, Sep 02, 2026 at 05:18:50PM +0800, KunWu Chan wrote:
> > On Wed, Sep 2, 2026 at 1:11 AM Paul E. McKenney <paulmck@kernel.org> wrote:
> > >
> > > On Tue, Sep 01, 2026 at 03:48:15PM +0800, Kunwu Chan wrote:
> > > > From: Kunwu Chan <kunwu.chan@gmail.com>
> > > >
> > > > Set srcu_reader_flavor to SRCU_READ_FLAVOR_ATOMIC in the Tiny SRCU
> > > > atomic initialization paths, so that the entry-point checks added by
> > > > the previous commit can identify atomic SRCU domains.
> > > >
> > > > For static initialization, add a flavor parameter to
> > > > __SRCU_STRUCT_INIT() and pass SRCU_READ_FLAVOR_ATOMIC through
> > > > DEFINE_SRCU_ATOMIC() and DEFINE_STATIC_SRCU_ATOMIC().
> > > >
> > > > For dynamic initialization, initialize srcu_reader_flavor to zero in
> > > > init_srcu_struct_fields() for the generic initialization path, and
> > > > set it to SRCU_READ_FLAVOR_ATOMIC in init_srcu_struct_atomic().
> > > > Handle both CONFIG_DEBUG_LOCK_ALLOC and non-debug initialization paths.
> > > >
> > > > Enable srcu_check_read_flavor() for Tiny SRCU, matching the Tree SRCU
> > > > behavior, so that readers can verify that the requested flavor matches
> > > > the SRCU domain.
> > > >
> > > > Signed-off-by: Kunwu Chan <kunwu.chan@gmail.com>
> > >
> > > Much better! Please see below for additional questions and comments.
> >
> > Thanks Paul for the detailed reply.
> >
> > >
> > > > ---
> > > > include/linux/srcutiny.h | 39 +++++++++++++++++++++++++++++----------
> > > > kernel/rcu/srcutiny.c | 1 +
> > > > 2 files changed, 30 insertions(+), 10 deletions(-)
> > > >
> > > > diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
> > > > index 2b293336525a..9dce4b5aa084 100644
> > > > --- a/include/linux/srcutiny.h
> > > > +++ b/include/linux/srcutiny.h
> > > > @@ -40,7 +40,7 @@ void srcu_drive_gp(struct work_struct *wp);
> > > > void srcu_tiny_irq_work(struct irq_work *irq_work);
> > > > void srcu_defer_drain(struct irq_work *irq_work);
> > > >
> > > > -#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \
> > > > +#define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, flavor) \
> > > > { \
> > > > .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \
> > > > .srcu_cb_tail = &name.srcu_cb_head, \
> > > > @@ -49,6 +49,7 @@ void srcu_defer_drain(struct irq_work *irq_work);
> > > > .defer_cbs = LLIST_HEAD_INIT(name.defer_cbs), \
> > > > .defer_iw = { .node = { .u_flags = IRQ_WORK_HARD_IRQ }, \
> > > > .func = srcu_defer_drain }, \
> > > > + .srcu_reader_flavor = flavor, \
> > >
> > > Don't we also need to define srcu_reader_flavor? Or is this patch
> > > supposed to be applied on top of your previous one?
> >
> > Yes, this is intended to be applied on top of the previous one [1].
> > [1] https://lore.kernel.org/rcu/20260831074937.2380914-1-kunwu.chan@linux.dev/
> >
> > > > __SRCU_DEP_MAP_INIT(name) \
> > > > }
> > > >
> > > > @@ -57,29 +58,43 @@ void srcu_defer_drain(struct irq_work *irq_work);
> > > > * Tree SRCU, which needs some per-CPU data.
> > > > */
> > > > #define DEFINE_SRCU(name) \
> > > > - struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > > + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > > #define DEFINE_STATIC_SRCU(name) \
> > > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > > #define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name)
> > > > #define DEFINE_STATIC_SRCU_FAST(name) \
> > > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > > #define DEFINE_SRCU_FAST_UPDOWN(name) DEFINE_SRCU(name)
> > > > #define DEFINE_STATIC_SRCU_FAST_UPDOWN(name) \
> > > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > > -#define DEFINE_SRCU_ATOMIC(name) DEFINE_SRCU(name)
> > > > + static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, 0)
> > > > +#define DEFINE_SRCU_ATOMIC(name) \
> > > > + struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> > > > #define DEFINE_STATIC_SRCU_ATOMIC(name) \
> > > > - static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
> > > > + static struct srcu_struct name = \
> > > > + __SRCU_STRUCT_INIT(name, name, name, SRCU_READ_FLAVOR_ATOMIC)
> > > >
> > > > // Dummy structure for srcu_notifier_head.
> > > > struct srcu_usage { };
> > > > #define __SRCU_USAGE_INIT(name) { }
> > > > #define __init_srcu_struct_fast __init_srcu_struct
> > > > #define __init_srcu_struct_fast_updown __init_srcu_struct
> > > > -#define __init_srcu_struct_atomic __init_srcu_struct
> > > > +#define __init_srcu_struct_atomic(ssp, name, key) \
> > > > +({ \
> > > > + int __ret = __init_srcu_struct(ssp, name, key); \
> > > > + if (!__ret) \
> > > > + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC; \
> > > > + __ret; \
> > > > +})
> > > > #ifndef CONFIG_DEBUG_LOCK_ALLOC
> > > > #define init_srcu_struct_fast init_srcu_struct
> > > > #define init_srcu_struct_fast_updown init_srcu_struct
> > > > -#define init_srcu_struct_atomic init_srcu_struct
> > > > +#define init_srcu_struct_atomic(ssp) \
> > > > + ({ \
> > > > + int __ret = init_srcu_struct(ssp); \
> > > > + if (!__ret) \
> > > > + (ssp)->srcu_reader_flavor = SRCU_READ_FLAVOR_ATOMIC;\
> > > > + __ret; \
> > > > + })
> > > > #endif // #ifndef CONFIG_DEBUG_LOCK_ALLOC
> > > >
> > > > void synchronize_srcu(struct srcu_struct *ssp);
> > > > @@ -148,7 +163,11 @@ static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)
> > > > void srcu_barrier(struct srcu_struct *ssp);
> > > >
> > > > static inline void srcu_expedite_current(struct srcu_struct *ssp) { }
> > > > -#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)
> > > > +#define srcu_check_read_flavor(ssp, read_flavor) \
> > > > + ({ \
> > > > + u8 __f = (ssp)->srcu_reader_flavor; \
> > > > + WARN_ON_ONCE(__f && !(__f & (read_flavor))); \
> > > > + })
> > >
> > > Why not make this a static inline function, along with
> > > __init_srcu_struct_atomic() and init_srcu_struct_atomic() above?
> > > That should simplify the code.
> >
> > Thanks. I’ll rework the initialization helpers as static inline
> > functions as suggested.
> >
> > > > /* Defined here to avoid size increase for non-torture kernels. */
> > > > static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
> > > > diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
> > > > index 22f7716cbb0e..873b30ccf563 100644
> > > > --- a/kernel/rcu/srcutiny.c
> > > > +++ b/kernel/rcu/srcutiny.c
> > > > @@ -42,6 +42,7 @@ static int init_srcu_struct_fields(struct srcu_struct *ssp)
> > > > ssp->srcu_gp_running = false;
> > > > ssp->srcu_gp_waiting = false;
> > > > ssp->srcu_atomic_gp_flag = 0;
> > > > + ssp->srcu_reader_flavor = 0;
> > > > ssp->srcu_idx = 0;
> > > > ssp->srcu_idx_max = 0;
> > > > INIT_WORK(&ssp->srcu_work, srcu_drive_gp);
> > > > --
> > > > 2.43.0
> > >
> > > One of the purposes of Tiny SRCU is to be tiny, and one could argue
> > > that Tiny SRCU already has too much diagnostic code. Should we include
> > > these patches at all? If we should, shouldn't they be under something
> > > like CONFIG_PROVE_RCU? Should some of the existing Tiny SRCU debugging
> > > code also be under something like CONFIG_PROVE_RCU?
> > >
> > > Thoughts?
> >
> > I agree that Tiny SRCU should keep its core as small as possible, so I think
> > it is worth reconsidering how much diagnostic machinery we want to add here.
> >
> > For srcu_reader_flavor, I did have some hesitation when adding it.
> > Tiny SRCU did not previously have the concept of a reader flavor; I
> > mainly added it
> > to distinguish Tiny Atomic SRCU, following the approach used by Tree
> > SRCU. If we still
> > need state for this purpose, perhaps a one-bit flag would be sufficient.
> >
> > One question is whether the flavor checking really needs to be part of
> > srcutiny.c.
> > I think there are two somewhat different cases:
> > 1: checking for invalid API usage, where the purpose is to detect or
> > stop misuse;
> > 2: defensive handling of an invalid call, where we redirect to a safe
> > implementation,
> > like in synchronize_srcu.
> >
> > The first case seems more like diagnostic functionality and could
> > potentially be handled
> > in the common SRCU API layer under CONFIG_PROVE_RCU. The second case affects
> > runtime behavior and should remain independent of CONFIG_PROVE_RCU.
> >
> > This makes me wonder whether the common flavor validation could live in srcu.h,
> > as part of the common SRCU interface, rather than adding more checking
> > logic to srcutiny.c.
> > That could centralize the validation and keep the Tiny SRCU
> > implementation easier to follow,
> > although it would add another wrapper layer, such as a macro or static inline.
>
> Another approach is to let the checking in Tree SRCU cover this.
> That way, the only misuses of the atomic SRCU API that are missed are
> those that appear only in CONFIG_SMP=n code. And right now, there isn't
> any such uses. There might be in the future, but perhaps this is quite
> unlikely.
Thanks Paul. That makes sense to me.
If Tree SRCU already catches the relevant flavor misuse for CONFIG_SMP=y,
and there are currently no such uses that are specific to CONFIG_SMP=n, then
I agree that adding flavor tracking/checking to Tiny SRCU just for that
coverage would not be worthwhile. :)
I originally added the Tiny SRCU flavor tracking mainly for defensive handling
and to keep the behavior consistent with Tree SRCU. But given the Tiny SRCU
size goal, I agree that this additional diagnostic coverage is not worth
the extra complexity. :-)
I'll drop the Tiny SRCU flavor-tracking part.
Thanks,
KunWu
>
> Thanx, Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-02 16:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-01 7:48 [PATCH] srcutiny: Enable atomic SRCU flavor tracking Kunwu Chan
2026-09-01 17:11 ` Paul E. McKenney
2026-09-02 9:18 ` KunWu Chan
2026-09-02 15:43 ` Paul E. McKenney
2026-09-02 16:29 ` KunWu Chan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®