[PATCH 01/17] locking/mutex: assert static storage for DEFINE_MUTEX()

From: Yury Norov

Date: Mon Sep 14 2026 - 23:06:40 EST


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@xxxxxxxxxx>
---
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