* [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
@ 2026-09-15 3:03 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 8:23 ` Peter Zijlstra
2026-09-15 3:03 ` [PATCH 02/17] locking/rtmutex: assert static storage for DEFINE_RT_MUTEX() Yury Norov
` (16 subsequent siblings)
17 siblings, 2 replies; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:03 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_MUTEX() uses a static lock initializer whose lockdep class key
requires a persistent object address. Reject automatic local declarations
with ASSERT_STATIC_STORAGE(), in both the regular and PREEMPT_RT variants.
Align the VMA and memblock tools stubs with the kernel declaration.
The two automatic mutexes in the WireGuard allowedips selftests already
call mutex_init(). Replace their redundant static initializers with plain
struct mutex declarations.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
drivers/net/wireguard/selftest/allowedips.c | 4 ++--
include/linux/mutex.h | 7 +++++--
tools/testing/memblock/linux/mutex.h | 8 ++++++--
tools/testing/vma/include/dup.h | 5 ++++-
4 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c
index 3e857e6fb627..ecb2908228e7 100644
--- a/drivers/net/wireguard/selftest/allowedips.c
+++ b/drivers/net/wireguard/selftest/allowedips.c
@@ -257,7 +257,7 @@ static __init bool randomized_test(void)
u8 ip[16], mutate_mask[16], mutated[16];
struct wg_peer **peers, *peer;
struct horrible_allowedips h;
- DEFINE_MUTEX(mutex);
+ struct mutex mutex;
struct allowedips t;
bool ret = false;
@@ -499,7 +499,7 @@ bool __init wg_allowedips_selftest(void)
struct allowedips_node *iter_node;
bool success = false;
struct allowedips t;
- DEFINE_MUTEX(mutex);
+ struct mutex mutex;
struct in6_addr ip;
size_t i = 0, count = 0;
__be64 part;
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 734048c02f4f..2f2d95f3097c 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -11,6 +11,7 @@
#ifndef __LINUX_MUTEX_H
#define __LINUX_MUTEX_H
+#include <linux/compiler.h>
#include <asm/current.h>
#include <linux/list.h>
#include <linux/spinlock_types.h>
@@ -84,7 +85,8 @@ do { \
__DEP_MAP_MUTEX_INITIALIZER(lockname) }
#define DEFINE_MUTEX(mutexname) \
- struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+ struct mutex mutexname = __MUTEX_INITIALIZER(mutexname); \
+ ASSERT_STATIC_STORAGE(mutexname)
#ifdef CONFIG_DEBUG_LOCK_ALLOC
void mutex_init_lockdep(struct mutex *lock, const char *name, struct lock_class_key *key);
@@ -124,7 +126,8 @@ extern bool mutex_is_locked(struct mutex *lock);
}
#define DEFINE_MUTEX(mutexname) \
- struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+ struct mutex mutexname = __MUTEX_INITIALIZER(mutexname); \
+ ASSERT_STATIC_STORAGE(mutexname)
#define mutex_is_locked(l) rt_mutex_base_is_locked(&(l)->rtmutex)
diff --git a/tools/testing/memblock/linux/mutex.h b/tools/testing/memblock/linux/mutex.h
index ae3f497165d6..d1a52d6dae80 100644
--- a/tools/testing/memblock/linux/mutex.h
+++ b/tools/testing/memblock/linux/mutex.h
@@ -2,7 +2,11 @@
#ifndef _MUTEX_H
#define _MUTEX_H
-#define DEFINE_MUTEX(name) int name
+#include <linux/compiler.h>
+
+#define DEFINE_MUTEX(name) \
+ int name; \
+ ASSERT_STATIC_STORAGE(name)
static inline void dummy_mutex_guard(int *name)
{
@@ -11,4 +15,4 @@ static inline void dummy_mutex_guard(int *name)
#define guard(mutex) \
dummy_##mutex##_guard
-#endif /* _MUTEX_H */
\ No newline at end of file
+#endif /* _MUTEX_H */
diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h
index 4c58487b764e..f2cdb9185ef9 100644
--- a/tools/testing/vma/include/dup.h
+++ b/tools/testing/vma/include/dup.h
@@ -2,6 +2,8 @@
#pragma once
+#include <linux/compiler.h>
+
/* Forward declarations to avoid header cycle. */
struct vm_area_struct;
static inline void vma_start_write(struct vm_area_struct *vma);
@@ -435,7 +437,8 @@ struct vma_iterator {
}
#define DEFINE_MUTEX(mutexname) \
- struct mutex mutexname = {}
+ struct mutex mutexname = {}; \
+ ASSERT_STATIC_STORAGE(mutexname)
#define DECLARE_BITMAP(name, bits) \
unsigned long name[BITS_TO_LONGS(bits)]
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX()
2026-09-15 3:03 ` [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX() Yury Norov
@ 2026-09-15 3:25 ` sashiko-bot
2026-09-15 8:23 ` Peter Zijlstra
1 sibling, 0 replies; 40+ messages in thread
From: sashiko-bot @ 2026-09-15 3:25 UTC (permalink / raw)
To: Yury Norov
Cc: linux-rt-devel, Eugenio Perez, virtualization, linux-kernel,
Michael S. Tsirkin
> DEFINE_MUTEX() uses a static lock initializer whose lockdep class key
> requires a persistent object address. Reject automatic local declarations
> with ASSERT_STATIC_STORAGE(), in both the regular and PREEMPT_RT variants.
> Align the VMA and memblock tools stubs with the kernel declaration.
>
> The two automatic mutexes in the WireGuard allowedips selftests already
> call mutex_init(). Replace their redundant static initializers with plain
> struct mutex declarations.
>
> Assisted-by: OpenAI Codex
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260915030336.1192299-1-ynorov@nvidia.com?part=1
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX()
2026-09-15 3:03 ` [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX() Yury Norov
2026-09-15 3:25 ` sashiko-bot
@ 2026-09-15 8:23 ` Peter Zijlstra
2026-09-15 15:54 ` Yury Norov
1 sibling, 1 reply; 40+ messages in thread
From: Peter Zijlstra @ 2026-09-15 8:23 UTC (permalink / raw)
To: Yury Norov
Cc: Andrew Morton, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, Dennis Zhou,
Tejun Heo, Christoph Lameter, Paul E. McKenney,
Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
On Mon, Sep 14, 2026 at 11:03:19PM -0400, Yury Norov wrote:
> DEFINE_MUTEX() uses a static lock initializer whose lockdep class key
> requires a persistent object address. Reject automatic local declarations
> with ASSERT_STATIC_STORAGE(), in both the regular and PREEMPT_RT variants.
> Align the VMA and memblock tools stubs with the kernel declaration.
>
> The two automatic mutexes in the WireGuard allowedips selftests already
> call mutex_init(). Replace their redundant static initializers with plain
> struct mutex declarations.
>
> Assisted-by: OpenAI Codex
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
> ---
> drivers/net/wireguard/selftest/allowedips.c | 4 ++--
> include/linux/mutex.h | 7 +++++--
> tools/testing/memblock/linux/mutex.h | 8 ++++++--
> tools/testing/vma/include/dup.h | 5 ++++-
> 4 files changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c
> index 3e857e6fb627..ecb2908228e7 100644
> --- a/drivers/net/wireguard/selftest/allowedips.c
> +++ b/drivers/net/wireguard/selftest/allowedips.c
> @@ -257,7 +257,7 @@ static __init bool randomized_test(void)
> u8 ip[16], mutate_mask[16], mutated[16];
> struct wg_peer **peers, *peer;
> struct horrible_allowedips h;
> - DEFINE_MUTEX(mutex);
> + struct mutex mutex;
> struct allowedips t;
> bool ret = false;
>
> @@ -499,7 +499,7 @@ bool __init wg_allowedips_selftest(void)
> struct allowedips_node *iter_node;
> bool success = false;
> struct allowedips t;
> - DEFINE_MUTEX(mutex);
> + struct mutex mutex;
> struct in6_addr ip;
> size_t i = 0, count = 0;
> __be64 part;
This should probably be a separate patch.
> diff --git a/include/linux/mutex.h b/include/linux/mutex.h
> index 734048c02f4f..2f2d95f3097c 100644
> --- a/include/linux/mutex.h
> +++ b/include/linux/mutex.h
> @@ -11,6 +11,7 @@
> #ifndef __LINUX_MUTEX_H
> #define __LINUX_MUTEX_H
>
> +#include <linux/compiler.h>
> #include <asm/current.h>
> #include <linux/list.h>
> #include <linux/spinlock_types.h>
> @@ -84,7 +85,8 @@ do { \
> __DEP_MAP_MUTEX_INITIALIZER(lockname) }
>
> #define DEFINE_MUTEX(mutexname) \
> - struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
> + struct mutex mutexname = __MUTEX_INITIALIZER(mutexname); \
> + ASSERT_STATIC_STORAGE(mutexname)
My tree no has ASSERT_STATIC_STORAGE. Please repost when that lands?
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX()
2026-09-15 8:23 ` Peter Zijlstra
@ 2026-09-15 15:54 ` Yury Norov
0 siblings, 0 replies; 40+ messages in thread
From: Yury Norov @ 2026-09-15 15:54 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Andrew Morton, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, Dennis Zhou,
Tejun Heo, Christoph Lameter, Paul E. McKenney,
Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
On Tue, Sep 15, 2026 at 10:23:00AM +0200, Peter Zijlstra wrote:
> On Mon, Sep 14, 2026 at 11:03:19PM -0400, Yury Norov wrote:
> > DEFINE_MUTEX() uses a static lock initializer whose lockdep class key
> > requires a persistent object address. Reject automatic local declarations
> > with ASSERT_STATIC_STORAGE(), in both the regular and PREEMPT_RT variants.
> > Align the VMA and memblock tools stubs with the kernel declaration.
> >
> > The two automatic mutexes in the WireGuard allowedips selftests already
> > call mutex_init(). Replace their redundant static initializers with plain
> > struct mutex declarations.
> >
> > Assisted-by: OpenAI Codex
> > Signed-off-by: Yury Norov <ynorov@nvidia.com>
> > ---
> > drivers/net/wireguard/selftest/allowedips.c | 4 ++--
> > include/linux/mutex.h | 7 +++++--
> > tools/testing/memblock/linux/mutex.h | 8 ++++++--
> > tools/testing/vma/include/dup.h | 5 ++++-
> > 4 files changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c
> > index 3e857e6fb627..ecb2908228e7 100644
> > --- a/drivers/net/wireguard/selftest/allowedips.c
> > +++ b/drivers/net/wireguard/selftest/allowedips.c
> > @@ -257,7 +257,7 @@ static __init bool randomized_test(void)
> > u8 ip[16], mutate_mask[16], mutated[16];
> > struct wg_peer **peers, *peer;
> > struct horrible_allowedips h;
> > - DEFINE_MUTEX(mutex);
> > + struct mutex mutex;
> > struct allowedips t;
> > bool ret = false;
> >
> > @@ -499,7 +499,7 @@ bool __init wg_allowedips_selftest(void)
> > struct allowedips_node *iter_node;
> > bool success = false;
> > struct allowedips t;
> > - DEFINE_MUTEX(mutex);
> > + struct mutex mutex;
> > struct in6_addr ip;
> > size_t i = 0, count = 0;
> > __be64 part;
>
> This should probably be a separate patch.
>
> > diff --git a/include/linux/mutex.h b/include/linux/mutex.h
> > index 734048c02f4f..2f2d95f3097c 100644
> > --- a/include/linux/mutex.h
> > +++ b/include/linux/mutex.h
> > @@ -11,6 +11,7 @@
> > #ifndef __LINUX_MUTEX_H
> > #define __LINUX_MUTEX_H
> >
> > +#include <linux/compiler.h>
> > #include <asm/current.h>
> > #include <linux/list.h>
> > #include <linux/spinlock_types.h>
> > @@ -84,7 +85,8 @@ do { \
> > __DEP_MAP_MUTEX_INITIALIZER(lockname) }
> >
> > #define DEFINE_MUTEX(mutexname) \
> > - struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
> > + struct mutex mutexname = __MUTEX_INITIALIZER(mutexname); \
> > + ASSERT_STATIC_STORAGE(mutexname)
>
> My tree no has ASSERT_STATIC_STORAGE. Please repost when that lands?
It's on top of:
https://lore.kernel.org/all/20260911221444.1523311-1-ynorov@nvidia.com/
Check the cover letter for more details.
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 02/17] locking/rtmutex: assert static storage for DEFINE_RT_MUTEX()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
2026-09-15 3:03 ` [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX() Yury Norov
@ 2026-09-15 3:03 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:03 ` [PATCH 03/17] locking/rwsem: assert static storage for semaphore definitions Yury Norov
` (15 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:03 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_RT_MUTEX() statically initializes both the mutex lockdep map and
its internal wait lock. An automatic local object cannot supply the
persistent class key expected by this initialization.
Add ASSERT_STATIC_STORAGE() to reject automatic declarations. Such mutexes
must use rt_mutex_init(); file-scope and static local definitions remain
valid. Leave __RT_MUTEX_INITIALIZER() available for embedded objects.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/rtmutex.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h
index 9e1f012f89db..495509d82c88 100644
--- a/include/linux/rtmutex.h
+++ b/include/linux/rtmutex.h
@@ -105,7 +105,8 @@ do { \
}
#define DEFINE_RT_MUTEX(mutexname) \
- struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname)
+ struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname); \
+ ASSERT_STATIC_STORAGE(mutexname)
extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 03/17] locking/rwsem: assert static storage for semaphore definitions
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
2026-09-15 3:03 ` [PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX() Yury Norov
2026-09-15 3:03 ` [PATCH 02/17] locking/rtmutex: assert static storage for DEFINE_RT_MUTEX() Yury Norov
@ 2026-09-15 3:03 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:03 ` [PATCH 04/17] locking/semaphore: assert static storage for DEFINE_SEMAPHORE() Yury Norov
` (14 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:03 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
The static rwsem initializers rely on persistent lockdep class keys,
both for their own maps and for embedded locks or wait queues.
Enforce static storage in DECLARE_RWSEM(), including PREEMPT_RT, and in
__DEFINE_PERCPU_RWSEM(), covering both public per-CPU rwsem declarations.
Automatic objects must use init_rwsem() or percpu_init_rwsem().
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/percpu-rwsem.h | 4 +++-
include/linux/rwsem.h | 7 +++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
index 39d5bf8e6562..680c3efc14c8 100644
--- a/include/linux/percpu-rwsem.h
+++ b/include/linux/percpu-rwsem.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_PERCPU_RWSEM_H
#define _LINUX_PERCPU_RWSEM_H
+#include <linux/compiler.h>
#include <linux/atomic.h>
#include <linux/percpu.h>
#include <linux/rcuwait.h>
@@ -36,7 +37,8 @@ is_static struct percpu_rw_semaphore name = { \
.waiters = __WAIT_QUEUE_HEAD_INITIALIZER(name.waiters), \
.block = ATOMIC_INIT(0), \
__PERCPU_RWSEM_DEP_MAP_INIT(name) \
-}
+}; \
+ ASSERT_STATIC_STORAGE(name)
#define DEFINE_PERCPU_RWSEM(name) \
__DEFINE_PERCPU_RWSEM(name, /* not static */)
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
index 6a1a7bae5f81..faf52c0c8dd3 100644
--- a/include/linux/rwsem.h
+++ b/include/linux/rwsem.h
@@ -8,6 +8,7 @@
#ifndef _LINUX_RWSEM_H
#define _LINUX_RWSEM_H
+#include <linux/compiler.h>
#include <linux/linkage.h>
#include <linux/types.h>
@@ -111,7 +112,8 @@ static inline void rwsem_assert_held_write_nolockdep(const struct rw_semaphore *
__RWSEM_DEP_MAP_INIT(name) }
#define DECLARE_RWSEM(name) \
- struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name); \
+ ASSERT_STATIC_STORAGE(name)
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
struct lock_class_key *key);
@@ -164,7 +166,8 @@ context_lock_struct(rw_semaphore) {
}
#define DECLARE_RWSEM(lockname) \
- struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname)
+ struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname); \
+ ASSERT_STATIC_STORAGE(lockname)
extern void __init_rwsem(struct rw_semaphore *rwsem, const char *name,
struct lock_class_key *key);
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 04/17] locking/semaphore: assert static storage for DEFINE_SEMAPHORE()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (2 preceding siblings ...)
2026-09-15 3:03 ` [PATCH 03/17] locking/rwsem: assert static storage for semaphore definitions Yury Norov
@ 2026-09-15 3:03 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:03 ` [PATCH 05/17] locking/seqlock: assert static storage for DEFINE_SEQLOCK() Yury Norov
` (13 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:03 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_SEMAPHORE() statically initializes its embedded raw spinlock.
Using it for an automatic local semaphore leaves lockdep without a
persistent class key.
Reject this use with ASSERT_STATIC_STORAGE(). Automatic semaphores must
use sema_init(), which supplies a static class key. Preserve the underlying
initializer used by sema_init() and by embedded objects.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/semaphore.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h
index a4c8651ef021..c0657a6aeb12 100644
--- a/include/linux/semaphore.h
+++ b/include/linux/semaphore.h
@@ -8,6 +8,7 @@
#ifndef __LINUX_SEMAPHORE_H
#define __LINUX_SEMAPHORE_H
+#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/spinlock.h>
@@ -44,7 +45,8 @@ struct semaphore {
* context.
*/
#define DEFINE_SEMAPHORE(_name, _n) \
- struct semaphore _name = __SEMAPHORE_INITIALIZER(_name, _n)
+ struct semaphore _name = __SEMAPHORE_INITIALIZER(_name, _n); \
+ ASSERT_STATIC_STORAGE(_name)
static inline void sema_init(struct semaphore *sem, int val)
{
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 05/17] locking/seqlock: assert static storage for DEFINE_SEQLOCK()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (3 preceding siblings ...)
2026-09-15 3:03 ` [PATCH 04/17] locking/semaphore: assert static storage for DEFINE_SEMAPHORE() Yury Norov
@ 2026-09-15 3:03 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 06/17] sched: assert static storage for wait queue and completion declarations Yury Norov
` (12 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:03 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_SEQLOCK() statically initializes its sequence counter and spinlock.
Their lockdep maps require persistent class keys, which an automatic
local object cannot provide through this initializer.
Add ASSERT_STATIC_STORAGE() to the declaration macro. Automatic seqlocks
must use seqlock_init(); the underlying initializer remains available for
embedded objects.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/seqlock.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index f865491c4f2c..2aa793a45213 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -824,7 +824,8 @@ static __always_inline void write_seqcount_latch_end(seqcount_latch_t *s)
* @sl: Name of the seqlock_t instance
*/
#define DEFINE_SEQLOCK(sl) \
- seqlock_t sl = __SEQLOCK_UNLOCKED(sl)
+ seqlock_t sl = __SEQLOCK_UNLOCKED(sl); \
+ ASSERT_STATIC_STORAGE(sl)
/**
* read_seqbegin() - start a seqlock_t read side critical section
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 06/17] sched: assert static storage for wait queue and completion declarations
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (4 preceding siblings ...)
2026-09-15 3:03 ` [PATCH 05/17] locking/seqlock: assert static storage for DEFINE_SEQLOCK() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 07/17] xarray: assert static storage for DEFINE_XARRAY_FLAGS() Yury Norov
` (11 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
The ordinary wait queue and completion declarations statically initialize
their embedded locks. Automatic objects need runtime initialization so
lockdep receives persistent class keys.
Add ASSERT_STATIC_STORAGE() to DECLARE_WAIT_QUEUE_HEAD(),
DECLARE_SWAIT_QUEUE_HEAD() and DECLARE_COMPLETION(). Keep the _ONSTACK
variants usable without CONFIG_LOCKDEP by expanding to the underlying
initializer instead of an asserted declaration.
Convert the two automatic completions in the AMS PMU driver to
DECLARE_COMPLETION_ONSTACK().
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
drivers/macintosh/ams/ams-pmu.c | 4 ++--
include/linux/completion.h | 10 +++++++---
include/linux/swait.h | 6 ++++--
include/linux/wait.h | 7 +++++--
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/macintosh/ams/ams-pmu.c b/drivers/macintosh/ams/ams-pmu.c
index 1c3ce39e9a59..046a7d5dc5b2 100644
--- a/drivers/macintosh/ams/ams-pmu.c
+++ b/drivers/macintosh/ams/ams-pmu.c
@@ -48,7 +48,7 @@ static void ams_pmu_req_complete(struct adb_request *req)
static void ams_pmu_set_register(u8 reg, u8 value)
{
static struct adb_request req;
- DECLARE_COMPLETION(req_complete);
+ DECLARE_COMPLETION_ONSTACK(req_complete);
req.arg = &req_complete;
if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value))
@@ -61,7 +61,7 @@ static void ams_pmu_set_register(u8 reg, u8 value)
static u8 ams_pmu_get_register(u8 reg)
{
static struct adb_request req;
- DECLARE_COMPLETION(req_complete);
+ DECLARE_COMPLETION_ONSTACK(req_complete);
req.arg = &req_complete;
if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg))
diff --git a/include/linux/completion.h b/include/linux/completion.h
index fb2915676574..b514b5555722 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -9,6 +9,7 @@
* See kernel/sched/completion.c for details.
*/
+#include <linux/compiler.h>
#include <linux/swait.h>
/*
@@ -50,7 +51,8 @@ static inline void complete_release(struct completion *x) {}
* variables.
*/
#define DECLARE_COMPLETION(work) \
- struct completion work = COMPLETION_INITIALIZER(work)
+ struct completion work = COMPLETION_INITIALIZER(work); \
+ ASSERT_STATIC_STORAGE(work)
/*
* Lockdep needs to run a non-constant initializer for on-stack
@@ -70,8 +72,10 @@ static inline void complete_release(struct completion *x) {}
# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \
struct completion work = COMPLETION_INITIALIZER_ONSTACK_MAP(work, map)
#else
-# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
-# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) DECLARE_COMPLETION(work)
+# define DECLARE_COMPLETION_ONSTACK(work) \
+ struct completion work = COMPLETION_INITIALIZER(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \
+ DECLARE_COMPLETION_ONSTACK(work)
#endif
/**
diff --git a/include/linux/swait.h b/include/linux/swait.h
index d324419482a0..caa3028d1dd0 100644
--- a/include/linux/swait.h
+++ b/include/linux/swait.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_SWAIT_H
#define _LINUX_SWAIT_H
+#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
@@ -64,7 +65,8 @@ struct swait_queue {
}
#define DECLARE_SWAIT_QUEUE_HEAD(name) \
- struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name)
+ struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name); \
+ ASSERT_STATIC_STORAGE(name)
extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name,
struct lock_class_key *key);
@@ -82,7 +84,7 @@ extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name
struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INIT_ONSTACK(name)
#else
# define DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(name) \
- DECLARE_SWAIT_QUEUE_HEAD(name)
+ struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name)
#endif
/**
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 7e215330199c..5c7d49187396 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -4,6 +4,7 @@
/*
* Linux wait queue related types and methods
*/
+#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
@@ -57,7 +58,8 @@ struct task_struct;
.head = LIST_HEAD_INIT(name.head) }
#define DECLARE_WAIT_QUEUE_HEAD(name) \
- struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
+ struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name); \
+ ASSERT_STATIC_STORAGE(name)
extern void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *name, struct lock_class_key *);
@@ -74,7 +76,8 @@ extern void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *n
# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \
struct wait_queue_head name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name)
#else
-# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name)
+# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \
+ struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
#endif
static inline void init_waitqueue_entry(struct wait_queue_entry *wq_entry, struct task_struct *p)
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 07/17] xarray: assert static storage for DEFINE_XARRAY_FLAGS()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (5 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 06/17] sched: assert static storage for wait queue and completion declarations Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 08/17] idr: enforce the static-storage contract of DEFINE_IDR() Yury Norov
` (10 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_XARRAY_FLAGS() statically initializes xa_lock. For an automatic
local XArray, lockdep cannot use the lock address as a persistent class
key and disables itself when the lock is acquired.
Add ASSERT_STATIC_STORAGE() to the common declaration macro, covering
DEFINE_XARRAY(), DEFINE_XARRAY_ALLOC() and DEFINE_XARRAY_ALLOC1() as well.
Convert the automatic XArray in the userspace iteration test to xa_init().
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/xarray.h | 3 ++-
tools/testing/radix-tree/iteration_check_2.c | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index be850174e802..9b9a5eea006d 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -321,7 +321,8 @@ struct xarray {
* initialisation at compiletime instead of runtime.
*/
#define DEFINE_XARRAY_FLAGS(name, flags) \
- struct xarray name = XARRAY_INIT(name, flags)
+ struct xarray name = XARRAY_INIT(name, flags); \
+ ASSERT_STATIC_STORAGE(name)
/**
* DEFINE_XARRAY() - Define an XArray.
diff --git a/tools/testing/radix-tree/iteration_check_2.c b/tools/testing/radix-tree/iteration_check_2.c
index aac5c50a3674..f798603a6f28 100644
--- a/tools/testing/radix-tree/iteration_check_2.c
+++ b/tools/testing/radix-tree/iteration_check_2.c
@@ -54,9 +54,11 @@ static void *throbber(void *arg)
void iteration_test2(unsigned test_duration)
{
pthread_t threads[2];
- DEFINE_XARRAY(array);
+ struct xarray array;
int i;
+ xa_init(&array);
+
printv(1, "Running iteration test 2 for %d seconds\n", test_duration);
test_complete = false;
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 08/17] idr: enforce the static-storage contract of DEFINE_IDR()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (6 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 07/17] xarray: assert static storage for DEFINE_XARRAY_FLAGS() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 09/17] radix-tree: require static storage for RADIX_TREE() Yury Norov
` (9 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_IDR() is documented as defining a statically allocated IDR. Enforce
that contract with ASSERT_STATIC_STORAGE(), matching DEFINE_IDA().
Normal IDR operations use external synchronization and do not acquire the
embedded XArray lock. This change enforces the declaration API contract;
it does not fix a lockdep failure in ordinary IDR operations.
Convert the seven automatic IDRs in the userspace tests to plain
declarations and runtime initialization. Two already use idr_init_base().
Keep direct IDR_INIT() and IDR_INIT_BASE() initializers unchanged.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/idr.h | 4 +++-
tools/testing/radix-tree/idr-test.c | 29 ++++++++++++++++++++---------
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/include/linux/idr.h b/include/linux/idr.h
index e2a4b6298511..d0393b7fe985 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -55,7 +55,9 @@ struct idr {
* An IDR defined using this macro is ready for use with no additional
* initialisation required. It contains no IDs.
*/
-#define DEFINE_IDR(name) struct idr name = IDR_INIT(name)
+#define DEFINE_IDR(name) \
+ struct idr name = IDR_INIT(name); \
+ ASSERT_STATIC_STORAGE(name)
/**
* idr_get_cursor - Return the current position of the cyclic allocator
diff --git a/tools/testing/radix-tree/idr-test.c b/tools/testing/radix-tree/idr-test.c
index 6fcba5b5870b..4668c6a4f6ea 100644
--- a/tools/testing/radix-tree/idr-test.c
+++ b/tools/testing/radix-tree/idr-test.c
@@ -33,7 +33,9 @@ void item_idr_remove(struct idr *idr, int id)
void idr_alloc_test(void)
{
unsigned long i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
assert(idr_alloc_cyclic(&idr, DUMMY_PTR, 0, 0x4000, GFP_KERNEL) == 0);
assert(idr_alloc_cyclic(&idr, DUMMY_PTR, 0x3ffd, 0x4000, GFP_KERNEL) == 0x3ffd);
@@ -79,7 +81,9 @@ void idr_alloc2_test(void)
void idr_replace_test(void)
{
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
idr_alloc(&idr, (void *)-1, 10, 11, GFP_KERNEL);
idr_replace(&idr, &idr, 10);
@@ -96,7 +100,9 @@ void idr_replace_test(void)
void idr_null_test(void)
{
int i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
assert(idr_is_empty(&idr));
@@ -150,7 +156,9 @@ void idr_null_test(void)
void idr_nowait_test(void)
{
unsigned int i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
idr_preload(GFP_KERNEL);
@@ -169,11 +177,11 @@ void idr_get_next_test(int base)
{
unsigned long i;
int nextid;
- DEFINE_IDR(idr);
- idr_init_base(&idr, base);
-
+ struct idr idr;
int indices[] = {4, 7, 9, 15, 65, 128, 1000, 99999, 0};
+ idr_init_base(&idr, base);
+
for(i = 0; indices[i]; i++) {
struct item *item = item_create(indices[i], 0);
assert(idr_alloc(&idr, item, indices[i], indices[i+1],
@@ -229,7 +237,8 @@ void idr_u32_test1(struct idr *idr, u32 handle)
void idr_u32_test(int base)
{
- DEFINE_IDR(idr);
+ struct idr idr;
+
idr_init_base(&idr, base);
idr_u32_test1(&idr, 10);
idr_u32_test1(&idr, 0x7fffffff);
@@ -360,7 +369,9 @@ void idr_find_test(void)
void idr_checks(void)
{
unsigned long i;
- DEFINE_IDR(idr);
+ struct idr idr;
+
+ idr_init(&idr);
for (i = 0; i < 10000; i++) {
struct item *item = item_create(i, 0);
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH 08/17] idr: enforce the static-storage contract of DEFINE_IDR()
2026-09-15 3:13 ` [PATCH 08/17] idr: enforce the static-storage contract of DEFINE_IDR() Yury Norov
@ 2026-09-15 3:25 ` sashiko-bot
0 siblings, 0 replies; 40+ messages in thread
From: sashiko-bot @ 2026-09-15 3:25 UTC (permalink / raw)
To: Yury Norov
Cc: virtualization, linux-rt-devel, linux-kernel, Michael S. Tsirkin,
Eugenio Perez
> DEFINE_IDR() is documented as defining a statically allocated IDR. Enforce
> that contract with ASSERT_STATIC_STORAGE(), matching DEFINE_IDA().
>
> Normal IDR operations use external synchronization and do not acquire the
> embedded XArray lock. This change enforces the declaration API contract;
> it does not fix a lockdep failure in ordinary IDR operations.
>
> Convert the seven automatic IDRs in the userspace tests to plain
> declarations and runtime initialization. Two already use idr_init_base().
> Keep direct IDR_INIT() and IDR_INIT_BASE() initializers unchanged.
>
> Assisted-by: OpenAI Codex
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260915030336.1192299-1-ynorov@nvidia.com?part=8
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 09/17] radix-tree: require static storage for RADIX_TREE()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (7 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 08/17] idr: enforce the static-storage contract of DEFINE_IDR() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 10/17] klist: assert static storage for DEFINE_KLIST() Yury Norov
` (8 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
RADIX_TREE() uses the static XArray initializer. Enforce static storage
for this declaration wrapper, consistently with DEFINE_XARRAY_FLAGS()
and DEFINE_IDR(). Leave RADIX_TREE_INIT() unchanged for embedded objects.
Normal radix-tree operations use external synchronization rather than the
embedded XArray lock, so this is declaration-contract enforcement rather
than a fix for a lockdep failure in normal radix-tree operations.
Convert the thirteen automatic roots in the userspace tests and benchmark
to plain declarations followed by INIT_RADIX_TREE(), preserving their
allocation flags.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/radix-tree.h | 4 +++-
tools/testing/radix-tree/benchmark.c | 4 +++-
tools/testing/radix-tree/main.c | 16 +++++++++++----
tools/testing/radix-tree/regression3.c | 4 +++-
tools/testing/radix-tree/tag_check.c | 28 +++++++++++++++++++-------
5 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 057edc4cbb6e..dc3795f4cb1f 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -8,6 +8,7 @@
#ifndef _LINUX_RADIX_TREE_H
#define _LINUX_RADIX_TREE_H
+#include <linux/compiler.h>
#include <linux/bitops.h>
#include <linux/gfp_types.h>
#include <linux/list.h>
@@ -79,7 +80,8 @@ static inline bool radix_tree_is_internal_node(void *ptr)
#define RADIX_TREE_INIT(name, mask) XARRAY_INIT(name, mask)
#define RADIX_TREE(name, mask) \
- struct radix_tree_root name = RADIX_TREE_INIT(name, mask)
+ struct radix_tree_root name = RADIX_TREE_INIT(name, mask); \
+ ASSERT_STATIC_STORAGE(name)
#define INIT_RADIX_TREE(root, mask) xa_init_flags(root, mask)
diff --git a/tools/testing/radix-tree/benchmark.c b/tools/testing/radix-tree/benchmark.c
index 523c79f22ed3..57ab92e6cd77 100644
--- a/tools/testing/radix-tree/benchmark.c
+++ b/tools/testing/radix-tree/benchmark.c
@@ -114,9 +114,11 @@ static void benchmark_delete(struct radix_tree_root *root,
static void benchmark_size(unsigned long size, unsigned long step)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
long long normal, tagged;
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
+
benchmark_insert(&tree, size, step);
benchmark_tagging(&tree, size, step);
diff --git a/tools/testing/radix-tree/main.c b/tools/testing/radix-tree/main.c
index f2cbc8e5b97c..6f0f8eaa044d 100644
--- a/tools/testing/radix-tree/main.c
+++ b/tools/testing/radix-tree/main.c
@@ -15,7 +15,9 @@
void __gang_check(unsigned long middle, long down, long up, int chunk, int hop)
{
long idx;
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
middle = 1 << 30;
@@ -78,7 +80,9 @@ void big_gang_check(bool long_run)
void add_and_check(void)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
item_insert(&tree, 44);
item_check_present(&tree, 44);
@@ -89,7 +93,9 @@ void add_and_check(void)
void dynamic_height_check(void)
{
int i;
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
tree_verify_min_height(&tree, 0);
item_insert(&tree, 42);
@@ -155,11 +161,13 @@ void check_copied_tags(struct radix_tree_root *tree, unsigned long start, unsign
void copy_tag_check(void)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
unsigned long idx[ITEMS];
unsigned long start, end, count = 0, tagged, cur, tmp;
int i;
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
+
// printf("generating radix tree indices...\n");
start = rand();
end = rand();
diff --git a/tools/testing/radix-tree/regression3.c b/tools/testing/radix-tree/regression3.c
index 9f9a3b280f56..dc235bff0063 100644
--- a/tools/testing/radix-tree/regression3.c
+++ b/tools/testing/radix-tree/regression3.c
@@ -28,13 +28,15 @@
void regression3_test(void)
{
- RADIX_TREE(root, GFP_KERNEL);
+ struct radix_tree_root root;
void *ptr0 = (void *)4ul;
void *ptr = (void *)8ul;
struct radix_tree_iter iter;
void **slot;
bool first;
+ INIT_RADIX_TREE(&root, GFP_KERNEL);
+
printv(1, "running regression test 3 (should take milliseconds)\n");
radix_tree_insert(&root, 0, ptr0);
diff --git a/tools/testing/radix-tree/tag_check.c b/tools/testing/radix-tree/tag_check.c
index f898957b1a19..51c0f0d6152c 100644
--- a/tools/testing/radix-tree/tag_check.c
+++ b/tools/testing/radix-tree/tag_check.c
@@ -42,7 +42,9 @@ __simple_checks(struct radix_tree_root *tree, unsigned long index, int tag)
void simple_checks(void)
{
unsigned long index;
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
for (index = 0; index < 10000; index++) {
__simple_checks(&tree, index, 0);
@@ -61,7 +63,9 @@ void simple_checks(void)
*/
static void extend_checks(void)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
item_insert(&tree, 43);
assert(item_tag_get(&tree, 43, 0) == 0);
@@ -90,7 +94,9 @@ static void contract_checks(void)
{
struct item *item;
int tmp;
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
tmp = 1<<RADIX_TREE_MAP_SHIFT;
item_insert(&tree, tmp);
@@ -271,9 +277,11 @@ static void do_thrash(struct radix_tree_root *tree, char *thrash_state, int tag)
static void thrash_tags(void)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
char *thrash_state;
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
+
thrash_state = malloc(THRASH_SIZE);
memset(thrash_state, 0, THRASH_SIZE);
@@ -286,7 +294,9 @@ static void thrash_tags(void)
static void leak_check(void)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
item_insert(&tree, 1000000);
item_delete(&tree, 1000000);
@@ -295,7 +305,9 @@ static void leak_check(void)
static void __leak_check(void)
{
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
+
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
printv(2, "%d: nr_allocated=%d\n", __LINE__, nr_allocated);
item_insert(&tree, 1000000);
@@ -309,10 +321,12 @@ static void __leak_check(void)
static void single_check(void)
{
struct item *items[BATCH];
- RADIX_TREE(tree, GFP_KERNEL);
+ struct radix_tree_root tree;
int ret;
unsigned long first = 0;
+ INIT_RADIX_TREE(&tree, GFP_KERNEL);
+
item_insert(&tree, 0);
item_tag_set(&tree, 0, 0);
ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0);
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH 09/17] radix-tree: require static storage for RADIX_TREE()
2026-09-15 3:13 ` [PATCH 09/17] radix-tree: require static storage for RADIX_TREE() Yury Norov
@ 2026-09-15 3:25 ` sashiko-bot
0 siblings, 0 replies; 40+ messages in thread
From: sashiko-bot @ 2026-09-15 3:25 UTC (permalink / raw)
To: Yury Norov
Cc: Michael S. Tsirkin, linux-kernel, Eugenio Perez, virtualization,
linux-rt-devel
> RADIX_TREE() uses the static XArray initializer. Enforce static storage
> for this declaration wrapper, consistently with DEFINE_XARRAY_FLAGS()
> and DEFINE_IDR(). Leave RADIX_TREE_INIT() unchanged for embedded objects.
>
> Normal radix-tree operations use external synchronization rather than the
> embedded XArray lock, so this is declaration-contract enforcement rather
> than a fix for a lockdep failure in normal radix-tree operations.
>
> Convert the thirteen automatic roots in the userspace tests and benchmark
> to plain declarations followed by INIT_RADIX_TREE(), preserving their
> allocation flags.
>
> Assisted-by: OpenAI Codex
> Signed-off-by: Yury Norov <ynorov@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260915030336.1192299-1-ynorov@nvidia.com?part=9
^ permalink raw reply [flat|nested] 40+ messages in thread
* [PATCH 10/17] klist: assert static storage for DEFINE_KLIST()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (8 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 09/17] radix-tree: require static storage for RADIX_TREE() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 11/17] workqueue: assert static storage for work declarations Yury Norov
` (7 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_KLIST() statically initializes k_lock, relying on the object
address as a persistent lockdep class key. An automatic local klist must
instead use klist_init().
Add ASSERT_STATIC_STORAGE() to enforce this requirement at compile time.
Keep KLIST_INIT() available for embedded objects.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/klist.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/klist.h b/include/linux/klist.h
index b0f238f20dbb..5848363242b6 100644
--- a/include/linux/klist.h
+++ b/include/linux/klist.h
@@ -10,6 +10,7 @@
#ifndef _LINUX_KLIST_H
#define _LINUX_KLIST_H
+#include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <linux/list.h>
@@ -29,7 +30,8 @@ struct klist {
.put = _put, }
#define DEFINE_KLIST(_name, _get, _put) \
- struct klist _name = KLIST_INIT(_name, _get, _put)
+ struct klist _name = KLIST_INIT(_name, _get, _put); \
+ ASSERT_STATIC_STORAGE(_name)
extern void klist_init(struct klist *k, void (*get)(struct klist_node *),
void (*put)(struct klist_node *));
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 11/17] workqueue: assert static storage for work declarations
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (9 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 10/17] klist: assert static storage for DEFINE_KLIST() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 12/17] timers: assert static storage for DEFINE_TIMER() Yury Norov
` (6 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
Static work initializers use the work address as a lockdep class key and
mark the work item static for debugobjects. Automatic objects require
on-stack initialization instead.
Apply ASSERT_STATIC_STORAGE() to DECLARE_WORK(), DECLARE_DELAYED_WORK()
and DECLARE_DEFERRABLE_WORK(). Automatic objects must use the matching
INIT_*_ONSTACK() API and destroy the on-stack debugobjects before leaving
scope. Keep the underlying initializers available for embedded objects.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/workqueue.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index c8a36423cb34..433c9801d9c5 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -6,6 +6,7 @@
#ifndef _LINUX_WORKQUEUE_H
#define _LINUX_WORKQUEUE_H
+#include <linux/compiler.h>
#include <linux/alloc_tag.h>
#include <linux/timer.h>
#include <linux/linkage.h>
@@ -250,13 +251,16 @@ struct execute_work {
}
#define DECLARE_WORK(n, f) \
- struct work_struct n = __WORK_INITIALIZER(n, f)
+ struct work_struct n = __WORK_INITIALIZER(n, f); \
+ ASSERT_STATIC_STORAGE(n)
#define DECLARE_DELAYED_WORK(n, f) \
- struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, 0)
+ struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, 0); \
+ ASSERT_STATIC_STORAGE(n)
#define DECLARE_DEFERRABLE_WORK(n, f) \
- struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, TIMER_DEFERRABLE)
+ struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, TIMER_DEFERRABLE); \
+ ASSERT_STATIC_STORAGE(n)
#ifdef CONFIG_DEBUG_OBJECTS_WORK
extern void __init_work(struct work_struct *work, int onstack);
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 12/17] timers: assert static storage for DEFINE_TIMER()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (10 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 11/17] workqueue: assert static storage for work declarations Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 13/17] kthread: assert static storage for delayed work declarations Yury Norov
` (5 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_TIMER() marks a timer as statically initialized for debugobjects.
An automatic local timer instead needs timer_setup_on_stack() and the
corresponding on-stack destruction before leaving scope.
Add ASSERT_STATIC_STORAGE() to catch automatic declarations at compile
time. The timer lockdep key is already static; this check enforces the
debugobjects storage contract. Leave __TIMER_INITIALIZER() unchanged.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/timer.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 62e1cea71125..420509329883 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_TIMER_H
#define _LINUX_TIMER_H
+#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/ktime.h>
#include <linux/stddef.h>
@@ -62,7 +63,8 @@
#define DEFINE_TIMER(_name, _function) \
struct timer_list _name = \
- __TIMER_INITIALIZER(_function, 0)
+ __TIMER_INITIALIZER(_function, 0); \
+ ASSERT_STATIC_STORAGE(_name)
/*
* LOCKDEP and DEBUG timer interfaces.
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 13/17] kthread: assert static storage for delayed work declarations
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (11 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 12/17] timers: assert static storage for DEFINE_TIMER() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:25 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 14/17] ratelimit: assert static storage for DEFINE_RATELIMIT_STATE() Yury Norov
` (4 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_KTHREAD_DELAYED_WORK() embeds a statically initialized timer.
Using the declaration for an automatic object violates the timer's
debugobjects storage contract.
Add ASSERT_STATIC_STORAGE() to reject such declarations. Plain
DEFINE_KTHREAD_WORK() has no embedded timer or static lockdep map and
remains usable for automatic objects with an appropriately bounded
lifetime.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/kthread.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index a01a474719a7..faa9dfb2f6cf 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_KTHREAD_H
#define _LINUX_KTHREAD_H
/* Simple interface for creating and stopping kernel threads without mess. */
+#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/sched.h>
@@ -179,7 +180,8 @@ struct kthread_delayed_work {
#define DEFINE_KTHREAD_DELAYED_WORK(dwork, fn) \
struct kthread_delayed_work dwork = \
- KTHREAD_DELAYED_WORK_INIT(dwork, fn)
+ KTHREAD_DELAYED_WORK_INIT(dwork, fn); \
+ ASSERT_STATIC_STORAGE(dwork)
extern void __kthread_init_worker(struct kthread_worker *worker,
const char *name, struct lock_class_key *key);
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 14/17] ratelimit: assert static storage for DEFINE_RATELIMIT_STATE()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (12 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 13/17] kthread: assert static storage for delayed work declarations Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 15/17] notifier: assert static storage for locking notifier heads Yury Norov
` (3 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_RATELIMIT_STATE() uses a static raw spinlock initializer, which
requires a persistent object address for lockdep. Automatic objects must
use ratelimit_state_init().
Add ASSERT_STATIC_STORAGE() to the declaration and align the virtio tools
stub. The virtio tools use a private compiler.h, so provide the same
assertion helper and its unused attribute there as well.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/ratelimit_types.h | 4 +++-
tools/virtio/linux/compiler.h | 9 +++++++++
tools/virtio/linux/ratelimit.h | 6 +++++-
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/include/linux/ratelimit_types.h b/include/linux/ratelimit_types.h
index b19c4354540a..977fdfff5926 100644
--- a/include/linux/ratelimit_types.h
+++ b/include/linux/ratelimit_types.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_RATELIMIT_TYPES_H
#define _LINUX_RATELIMIT_TYPES_H
+#include <linux/compiler.h>
#include <linux/bits.h>
#include <linux/param.h>
#include <linux/spinlock_types_raw.h>
@@ -40,7 +41,8 @@ struct ratelimit_state {
#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \
\
struct ratelimit_state name = \
- RATELIMIT_STATE_INIT(name, interval_init, burst_init) \
+ RATELIMIT_STATE_INIT(name, interval_init, burst_init); \
+ ASSERT_STATIC_STORAGE(name)
extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
#define __ratelimit(state) ___ratelimit(state, __func__)
diff --git a/tools/virtio/linux/compiler.h b/tools/virtio/linux/compiler.h
index 0f25db473f55..3c1eca4a4380 100644
--- a/tools/virtio/linux/compiler.h
+++ b/tools/virtio/linux/compiler.h
@@ -15,6 +15,15 @@
#define __aligned(x) __attribute((__aligned__(x)))
+#ifndef __always_unused
+#define __always_unused __attribute__((__unused__))
+#endif
+
+/* Enforce static storage duration. */
+#define ASSERT_STATIC_STORAGE(name) \
+ static typeof(name) * const __always_unused \
+ name##_storage_check = &(name)
+
/**
* data_race - mark an expression as containing intentional data races
*
diff --git a/tools/virtio/linux/ratelimit.h b/tools/virtio/linux/ratelimit.h
index dcce1725f90d..c15c82a5ca21 100644
--- a/tools/virtio/linux/ratelimit.h
+++ b/tools/virtio/linux/ratelimit.h
@@ -1,4 +1,8 @@
-#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) int name = 0
+#include <linux/compiler.h>
+
+#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \
+ int name = 0; \
+ ASSERT_STATIC_STORAGE(name)
#define __ratelimit(x) (*(x))
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 15/17] notifier: assert static storage for locking notifier heads
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (13 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 14/17] ratelimit: assert static storage for DEFINE_RATELIMIT_STATE() Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 16/17] rcu: assert static storage for RCU sync and SRCU definitions Yury Norov
` (2 subsequent siblings)
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
Atomic, blocking and SRCU notifier head declarations statically initialize
locks or SRCU state that require persistent lockdep class keys.
Apply ASSERT_STATIC_STORAGE() to ATOMIC_NOTIFIER_HEAD(),
BLOCKING_NOTIFIER_HEAD() and the common _SRCU_NOTIFIER_HEAD() wrapper,
including both Tree SRCU and Tiny SRCU variants. Leave RAW_NOTIFIER_HEAD()
unchanged because it has no such initialization requirement.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/notifier.h | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 01b6c9d9956f..4f6330360df2 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -10,6 +10,7 @@
#ifndef _LINUX_NOTIFIER_H
#define _LINUX_NOTIFIER_H
+#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
@@ -114,10 +115,12 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
#define ATOMIC_NOTIFIER_HEAD(name) \
struct atomic_notifier_head name = \
- ATOMIC_NOTIFIER_INIT(name)
+ ATOMIC_NOTIFIER_INIT(name); \
+ ASSERT_STATIC_STORAGE(name)
#define BLOCKING_NOTIFIER_HEAD(name) \
struct blocking_notifier_head name = \
- BLOCKING_NOTIFIER_INIT(name)
+ BLOCKING_NOTIFIER_INIT(name); \
+ ASSERT_STATIC_STORAGE(name)
#define RAW_NOTIFIER_HEAD(name) \
struct raw_notifier_head name = \
RAW_NOTIFIER_INIT(name)
@@ -126,12 +129,14 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh);
#define _SRCU_NOTIFIER_HEAD(name, mod) \
static DEFINE_PER_CPU(struct srcu_data, name##_head_srcu_data); \
mod struct srcu_notifier_head name = \
- SRCU_NOTIFIER_INIT(name, name##_head_srcu_data)
+ SRCU_NOTIFIER_INIT(name, name##_head_srcu_data); \
+ ASSERT_STATIC_STORAGE(name)
#else
#define _SRCU_NOTIFIER_HEAD(name, mod) \
mod struct srcu_notifier_head name = \
- SRCU_NOTIFIER_INIT(name, name)
+ SRCU_NOTIFIER_INIT(name, name); \
+ ASSERT_STATIC_STORAGE(name)
#endif
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 16/17] rcu: assert static storage for RCU sync and SRCU definitions
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (14 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 15/17] notifier: assert static storage for locking notifier heads Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 3:13 ` [PATCH 17/17] sysctl: assert static storage for DEFINE_CTL_TABLE_POLL() Yury Norov
2026-09-15 6:14 ` [PATCH 00/17] Treewide: enforce static storage for object initializers Andrew Morton
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_RCU_SYNC() contains a statically initialized wait queue. SRCU
static definitions similarly rely on persistent lockdep keys and, in
Tiny SRCU, a statically initialized work item.
Add ASSERT_STATIC_STORAGE() to DEFINE_RCU_SYNC(), both Tree SRCU
__DEFINE_SRCU() variants and Tiny SRCU's common DEFINE_SRCU() declaration.
This covers the non-static FAST and FAST_UPDOWN wrappers too. Tiny SRCU's
explicitly static declarations already enforce the required duration.
The existing per-CPU restrictions on Tree SRCU declarations still apply.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/rcu_sync.h | 4 +++-
include/linux/srcutiny.h | 4 +++-
include/linux/srcutree.h | 7 +++++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/linux/rcu_sync.h b/include/linux/rcu_sync.h
index 3860dbb9107a..c10b6d30561a 100644
--- a/include/linux/rcu_sync.h
+++ b/include/linux/rcu_sync.h
@@ -10,6 +10,7 @@
#ifndef _LINUX_RCU_SYNC_H_
#define _LINUX_RCU_SYNC_H_
+#include <linux/compiler.h>
#include <linux/wait.h>
#include <linux/rcupdate.h>
@@ -48,6 +49,7 @@ extern void rcu_sync_dtor(struct rcu_sync *);
}
#define DEFINE_RCU_SYNC(name) \
- struct rcu_sync name = __RCU_SYNC_INITIALIZER(name)
+ struct rcu_sync name = __RCU_SYNC_INITIALIZER(name); \
+ ASSERT_STATIC_STORAGE(name)
#endif /* _LINUX_RCU_SYNC_H_ */
diff --git a/include/linux/srcutiny.h b/include/linux/srcutiny.h
index fbcf13bc12d1..40b592b4e2d8 100644
--- a/include/linux/srcutiny.h
+++ b/include/linux/srcutiny.h
@@ -11,6 +11,7 @@
#ifndef _LINUX_SRCU_TINY_H
#define _LINUX_SRCU_TINY_H
+#include <linux/compiler.h>
#include <linux/irq_work_types.h>
#include <linux/swait.h>
@@ -48,7 +49,8 @@ void srcu_tiny_irq_work(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, name); \
+ ASSERT_STATIC_STORAGE(name)
#define DEFINE_STATIC_SRCU(name) \
static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name, name, name)
#define DEFINE_SRCU_FAST(name) DEFINE_SRCU(name)
diff --git a/include/linux/srcutree.h b/include/linux/srcutree.h
index 75e54e4f963f..8bea8044230a 100644
--- a/include/linux/srcutree.h
+++ b/include/linux/srcutree.h
@@ -11,6 +11,7 @@
#ifndef _LINUX_SRCU_TREE_H
#define _LINUX_SRCU_TREE_H
+#include <linux/compiler.h>
#include <linux/rcu_node_tree.h>
#include <linux/completion.h>
@@ -217,13 +218,15 @@ struct srcu_struct {
fast); \
extern struct srcu_struct * const __srcu_struct_##name; \
struct srcu_struct * const __srcu_struct_##name \
- __section("___srcu_struct_ptrs") = &name
+ __section("___srcu_struct_ptrs") = &name; \
+ ASSERT_STATIC_STORAGE(name)
#else
# define __DEFINE_SRCU(name, fast, is_static) \
static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data); \
static struct srcu_usage name##_srcu_usage = __SRCU_USAGE_INIT(name##_srcu_usage); \
is_static struct srcu_struct name = \
- __SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data, fast)
+ __SRCU_STRUCT_INIT(name, name##_srcu_usage, name##_srcu_data, fast); \
+ ASSERT_STATIC_STORAGE(name)
#endif
#define DEFINE_SRCU(name) __DEFINE_SRCU(name, 0, /* not static */)
#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, 0, static)
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* [PATCH 17/17] sysctl: assert static storage for DEFINE_CTL_TABLE_POLL()
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (15 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 16/17] rcu: assert static storage for RCU sync and SRCU definitions Yury Norov
@ 2026-09-15 3:13 ` Yury Norov
2026-09-15 3:26 ` sashiko-bot
2026-09-15 6:14 ` [PATCH 00/17] Treewide: enforce static storage for object initializers Andrew Morton
17 siblings, 1 reply; 40+ messages in thread
From: Yury Norov @ 2026-09-15 3:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
DEFINE_CTL_TABLE_POLL() statically initializes an embedded wait queue.
An automatic local poll object cannot provide the persistent lockdep
class key expected by its wait queue lock.
Add ASSERT_STATIC_STORAGE() to reject automatic declarations while
preserving file-scope and static local definitions. Leave the underlying
initializer available for embedded objects.
Assisted-by: OpenAI Codex
Signed-off-by: Yury Norov <ynorov@nvidia.com>
---
include/linux/sysctl.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e5d7226ab6f5..be79359346af 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -22,6 +22,7 @@
#ifndef _LINUX_SYSCTL_H
#define _LINUX_SYSCTL_H
+#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/wait.h>
@@ -216,7 +217,8 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
.wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait) }
#define DEFINE_CTL_TABLE_POLL(name) \
- struct ctl_table_poll name = __CTL_TABLE_POLL_INITIALIZER(name)
+ struct ctl_table_poll name = __CTL_TABLE_POLL_INITIALIZER(name); \
+ ASSERT_STATIC_STORAGE(name)
/* A sysctl table is an array of struct ctl_table: */
struct ctl_table {
--
2.53.0
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH 00/17] Treewide: enforce static storage for object initializers
2026-09-15 3:03 [PATCH 00/17] Treewide: enforce static storage for object initializers Yury Norov
` (16 preceding siblings ...)
2026-09-15 3:13 ` [PATCH 17/17] sysctl: assert static storage for DEFINE_CTL_TABLE_POLL() Yury Norov
@ 2026-09-15 6:14 ` Andrew Morton
2026-09-15 9:24 ` David Laight
17 siblings, 1 reply; 40+ messages in thread
From: Andrew Morton @ 2026-09-15 6:14 UTC (permalink / raw)
To: Yury Norov
Cc: Jason A. Donenfeld, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Matthew Wilcox, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long, Dennis Zhou,
Tejun Heo, Christoph Lameter, Paul E. McKenney,
Frederic Weisbecker, Neeraj Upadhyay, Joel Fernandes,
Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
On Mon, 14 Sep 2026 23:03:18 -0400 Yury Norov <ynorov@nvidia.com> wrote:
> Declaration macros that statically initialize embedded locks require static
> storage when lockdep is enabled. Automatic objects must use runtime
> initialization so lockdep receives a persistent class key.
>
> For automatic local objects, lockdep cannot use the lock address as a persistent
> class key and reports "INFO: trying to register non-static key" before disabling
> itself.
So why haven't we been buried in reports about this warning coming out?
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH 00/17] Treewide: enforce static storage for object initializers
2026-09-15 6:14 ` [PATCH 00/17] Treewide: enforce static storage for object initializers Andrew Morton
@ 2026-09-15 9:24 ` David Laight
2026-09-15 15:53 ` Yury Norov
0 siblings, 1 reply; 40+ messages in thread
From: David Laight @ 2026-09-15 9:24 UTC (permalink / raw)
To: Andrew Morton
Cc: Yury Norov, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
On Mon, 14 Sep 2026 23:14:18 -0700
Andrew Morton <akpm@linux-foundation.org> wrote:
> On Mon, 14 Sep 2026 23:03:18 -0400 Yury Norov <ynorov@nvidia.com> wrote:
>
> > Declaration macros that statically initialize embedded locks require static
> > storage when lockdep is enabled. Automatic objects must use runtime
> > initialization so lockdep receives a persistent class key.
> >
> > For automatic local objects, lockdep cannot use the lock address as a persistent
> > class key and reports "INFO: trying to register non-static key" before disabling
> > itself.
>
> So why haven't we been buried in reports about this warning coming out?
>
Are there any code changes outside of testing?
David
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH 00/17] Treewide: enforce static storage for object initializers
2026-09-15 9:24 ` David Laight
@ 2026-09-15 15:53 ` Yury Norov
0 siblings, 0 replies; 40+ messages in thread
From: Yury Norov @ 2026-09-15 15:53 UTC (permalink / raw)
To: David Laight
Cc: Andrew Morton, Jason A. Donenfeld, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Matthew Wilcox,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng,
Waiman Long, Dennis Zhou, Tejun Heo, Christoph Lameter,
Paul E. McKenney, Frederic Weisbecker, Neeraj Upadhyay,
Joel Fernandes, Josh Triplett, Uladzislau Rezki, Steven Rostedt,
Mathieu Desnoyers, Lai Jiangshan, Zqiang, Onur Özkan,
Kees Cook, Joel Granados, Anna-Maria Behnsen, Thomas Gleixner,
Juri Lelli, Vincent Guittot, Dietmar Eggemann, Ben Segall,
Mel Gorman, Valentin Schneider, K Prateek Nayak, Mike Rapoport,
Liam R. Howlett, Lorenzo Stoakes, Vlastimil Babka, Jann Horn,
Pedro Falcato, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Sebastian Andrzej Siewior, Clark Williams,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linuxppc-dev, linux-kernel, wireguard, netdev, linux-fsdevel,
linux-mm, rcu, virtualization, linux-rt-devel, llvm, Yury Norov
On Tue, Sep 15, 2026 at 10:24:01AM +0100, David Laight wrote:
> On Mon, 14 Sep 2026 23:14:18 -0700
> Andrew Morton <akpm@linux-foundation.org> wrote:
>
> > On Mon, 14 Sep 2026 23:03:18 -0400 Yury Norov <ynorov@nvidia.com> wrote:
> >
> > > Declaration macros that statically initialize embedded locks require static
> > > storage when lockdep is enabled. Automatic objects must use runtime
> > > initialization so lockdep receives a persistent class key.
> > >
> > > For automatic local objects, lockdep cannot use the lock address as a persistent
> > > class key and reports "INFO: trying to register non-static key" before disabling
> > > itself.
> >
> > So why haven't we been buried in reports about this warning coming out?
I have no answer. Maybe because lockdep isn't enabled by major distros...
The original report came from i386 randconfig. It looks like a combination
of some luck and a new code, probably attracting more robots attention.
> Are there any code changes outside of testing?
ams_pmu_set/get_register in patch #6 for example.
^ permalink raw reply [flat|nested] 40+ messages in thread