[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260119094029.1344361-1-elver@google.com>
Date: Mon, 19 Jan 2026 10:05:50 +0100
From: Marco Elver <elver@...gle.com>
To: elver@...gle.com, Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...nel.org>
Cc: Thomas Gleixner <tglx@...utronix.de>, Will Deacon <will@...nel.org>,
Boqun Feng <boqun.feng@...il.com>, Waiman Long <longman@...hat.com>,
Christoph Hellwig <hch@....de>, Steven Rostedt <rostedt@...dmis.org>, Bart Van Assche <bvanassche@....org>,
kasan-dev@...glegroups.com, llvm@...ts.linux.dev,
linux-crypto@...r.kernel.org, linux-doc@...r.kernel.org,
linux-security-module@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH tip/locking/core 0/6] compiler-context-analysis: Scoped init guards
Current context analysis treats lock_init() as implicitly "holding" the
lock to allow initializing guarded members. This causes false-positive
"double lock" reports if the lock is acquired immediately after
initialization in the same scope; for example:
mutex_init(&d->mtx);
/* ... counter is guarded by mtx ... */
d->counter = 0; /* ok, but mtx is now "held" */
...
mutex_lock(&d->mtx); /* warning: acquiring mutex already held */
This series proposes a solution to this by introducing scoped init
guards which Peter suggested, using the guard(type_init)(&lock) or
scoped_guard(type_init, ..) interface. This explicitly marks init scope
where we can initialize guarded members. With that we can revert the
"implicitly hold" after init annotations, which allows use after
initialization scope as follows:
scoped_guard(mutex_init, &d->mtx) {
d->counter = 0;
}
...
mutex_lock(&d->mtx); /* ok */
Note: Scoped guarded initialization remains optional, and normal
initialization can still be used if no guarded members are being
initialized. Another alternative is to just disable context analysis to
initialize guarded members with `context_unsafe(var = init)` or adding
the `__context_unsafe(init)` function attribute (the latter not being
recommended for non-trivial functions due to lack of any checking):
mutex_init(&d->mtx);
context_unsafe(d->counter = 0); /* ok */
...
mutex_lock(&d->mtx);
This series is an alternative to the approach in [1]:
* Scoped init guards (this series): Sound interface, requires use of
guard(type_init)(&lock) or scoped_guard(type_init, ..) for guarded
member initialization.
* Reentrant init [1]: Less intrusive, type_init() just works, and
also allows guarded member initialization with later lock use in
the same function. But unsound, and e.g. misses double-lock bugs
immediately after init, trading false positives for false negatives.
[1] https://lore.kernel.org/all/20260115005231.1211866-1-elver@google.com/
Marco Elver (6):
cleanup: Make __DEFINE_LOCK_GUARD handle commas in initializers
compiler-context-analysis: Introduce scoped init guards
kcov: Use scoped init guard
crypto: Use scoped init guard
tomoyo: Use scoped init guard
compiler-context-analysis: Remove __assume_ctx_lock from initializers
Documentation/dev-tools/context-analysis.rst | 30 ++++++++++++++++++--
crypto/crypto_engine.c | 2 +-
crypto/drbg.c | 2 +-
include/linux/cleanup.h | 8 +++---
include/linux/compiler-context-analysis.h | 9 ++----
include/linux/local_lock.h | 8 ++++++
include/linux/local_lock_internal.h | 4 +--
include/linux/mutex.h | 4 ++-
include/linux/rwlock.h | 3 +-
include/linux/rwlock_rt.h | 1 -
include/linux/rwsem.h | 6 ++--
include/linux/seqlock.h | 6 +++-
include/linux/spinlock.h | 17 ++++++++---
include/linux/spinlock_rt.h | 1 -
include/linux/ww_mutex.h | 1 -
kernel/kcov.c | 2 +-
lib/test_context-analysis.c | 22 ++++++--------
security/tomoyo/common.c | 2 +-
18 files changed, 80 insertions(+), 48 deletions(-)
--
2.52.0.457.g6b5491de43-goog
Powered by blists - more mailing lists