Hi Ingo & Peter,
Please pull the lockdep changes for v6.17 into tip. One thing to notice
is that I would like to add Breno Leitao's workaround in
lockdep_unregister_key(), since the alternative requires hazptr and I'm
not near to get it done. I added comments explaining this and left a
TODO there, and I will replace it once the shazptr patch is in a good
shape. Peter, if you have any concern about it, either we can drop the
patch #9 or I can create another tag. Thanks!
The following changes since commit 7ff495e26a39f3e7a3d4058df59b5b6d6f943cab:
local_lock: Move this_cpu_ptr() notation from internal to main header (2025-06-30 17:45:35 +0200)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/boqun/linux.git tags/lockdep-for-tip.2025.07.16
for you to fetch changes up to 7a3cedafccf8e7d038ad4cfec5b38052647ceac5:
lockdep: Speed up lockdep_unregister_key() with expedited RCU synchronization (2025-07-14 21:57:29 -0700)
----------------------------------------------------------------
Locking changes for v6.17:
- General
- Mark devm_mutex_init() as __must_check
- Add #[must_use] to Lock::try_lock()
- Remove OWNER_SPINNABLE in rwsem
- Remove redundant #ifdefs in mutex
- Lockdep
- Avoid returning struct in lock_stats()
- Change `static const` into enum for LOCKF_*_IRQ_*
- Temporarily use synchronize_rcu_expedited() in
lockdep_unregister_key() to speed things up.
----------------------------------------------------------------
Regards,
Boqun
Arnd Bergmann (2):
locking/lockdep: Avoid struct return in lock_stats()
locking/lockdep: Change 'static const' variables to enum values
Breno Leitao (1):
lockdep: Speed up lockdep_unregister_key() with expedited RCU synchronization
Jason Devers (1):
rust: sync: Add #[must_use] to Lock::try_lock()
Jinliang Zheng (1):
locking/rwsem: Use OWNER_NONSPINNABLE directly instead of OWNER_SPINNABLE
Ran Xiaokai (1):
locking/mutex: Remove redundant #ifdefs
Thomas Weißschuh (3):
spi: spi-nxp-fspi: Check return value of devm_mutex_init()
leds: lp8860: Check return value of devm_mutex_init()
locking/mutex: Mark devm_mutex_init() as __must_check
drivers/leds/leds-lp8860.c | 4 +++-
drivers/spi/spi-nxp-fspi.c | 4 +++-
include/linux/lockdep_types.h | 2 +-
include/linux/mutex.h | 11 +++++++----
kernel/locking/lockdep.c | 39 +++++++++++++++++++++-----------------
kernel/locking/lockdep_internals.h | 18 ++++++++++--------
kernel/locking/lockdep_proc.c | 2 +-
kernel/locking/mutex.c | 4 ----
kernel/locking/rwsem.c | 4 +---
rust/kernel/sync/lock.rs | 2 ++
10 files changed, 50 insertions(+), 40 deletions(-)
--
2.39.5 (Apple Git-154)
From: Thomas Weißschuh <linux@weissschuh.net>
devm_mutex_init() can fail. With CONFIG_DEBUG_MUTEXES=y the mutex will
be marked as unusable and trigger errors on usage.
Add the missed check.
Fixes: 48900813abd2 ("spi: spi-nxp-fspi: remove the goto in probe")
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250617-must_check-devm_mutex_init-v7-1-d9e449f4d224@weissschuh.net
---
drivers/spi/spi-nxp-fspi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
@@ -1273,7 +1273,9 @@ static int nxp_fspi_probe(struct platform_device *pdev)if(ret)returndev_err_probe(dev,ret,"Failed to request irq\n");-devm_mutex_init(dev,&f->lock);+ret=devm_mutex_init(dev,&f->lock);+if(ret)+returndev_err_probe(dev,ret,"Failed to initialize lock\n");ctlr->bus_num=-1;ctlr->num_chipselect=NXP_FSPI_MAX_CHIPSELECT;
From: Thomas Weißschuh <linux@weissschuh.net>
devm_mutex_init() can fail. With CONFIG_DEBUG_MUTEXES=y the mutex will be
marked as unusable and trigger errors on usage.
Add the missed check.
Fixes: 87a59548af95 ("leds: lp8860: Use new mutex guards to cleanup function exits")
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Andrew Davis <redacted>
Acked-by: Lee Jones <lee@kernel.org>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250617-must_check-devm_mutex_init-v7-2-d9e449f4d224@weissschuh.net
---
drivers/leds/leds-lp8860.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
From: Thomas Weißschuh <linux@weissschuh.net>
devm_mutex_init() can fail. With CONFIG_DEBUG_MUTEXES=y the mutex will be
marked as unusable and trigger errors on usage.
Enforce all callers check the return value through the compiler.
As devm_mutex_init() itself is a macro, it can not be annotated
directly. Annotate __devm_mutex_init() instead.
Unfortunately __must_check/warn_unused_result don't propagate through
statement expression. So move the statement expression into the argument
list of the call to __devm_mutex_init() through a helper macro.
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Bartosz Golaszewski <redacted>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250617-must_check-devm_mutex_init-v7-3-d9e449f4d224@weissschuh.net
---
include/linux/mutex.h | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
From: Jason Devers <redacted>
The `Lock::try_lock()` function returns an `Option<Guard<...>>`, but it
currently does not issue a warning if the return value is unused.
To avoid potential bugs, the `#[must_use]` annotation is added to ensure
proper usage.
Note that `T` is `#[must_use]` but `Option<T>` is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Link: https://github.com/Rust-for-Linux/linux/issues/1133
Signed-off-by: Jason Devers <redacted>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20241212154753.139563-1-dev.json2@gmail.com
---
rust/kernel/sync/lock.rs | 2 ++
1 file changed, 2 insertions(+)
@@ -175,6 +175,8 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock.////// Returns a guard that can be used to access the data protected by the lock if successful.+// `Option<T>` is not `#[must_use]` even if `T` is, thus the attribute is needed here.+#[must_use = "if unused, the lock will be immediately unlocked"]pubfntry_lock(&self)->Option<Guard<'_,T,B>>{// SAFETY: The constructor of the type calls `init`, so the existence of the object proves// that `init` was called.
From: Arnd Bergmann <arnd@arndb.de>
Returning a large structure from the lock_stats() function causes clang
to have multiple copies of it on the stack and copy between them, which
can end up exceeding the frame size warning limit:
kernel/locking/lockdep.c:300:25: error: stack frame size (1464) exceeds limit (1280) in 'lock_stats' [-Werror,-Wframe-larger-than]
300 | struct lock_class_stats lock_stats(struct lock_class *class)
Change the calling conventions to directly operate on the caller's copy,
which apparently is what gcc does already.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250610092941.2642847-1-arnd@kernel.org
---
include/linux/lockdep_types.h | 2 +-
kernel/locking/lockdep.c | 27 ++++++++++++---------------
kernel/locking/lockdep_proc.c | 2 +-
3 files changed, 14 insertions(+), 17 deletions(-)
From: Arnd Bergmann <arnd@arndb.de>
gcc warns about 'static const' variables even in headers when building
with -Wunused-const-variables enabled:
In file included from kernel/locking/lockdep_proc.c:25:
kernel/locking/lockdep_internals.h:69:28: error: 'LOCKF_USED_IN_IRQ_READ' defined but not used [-Werror=unused-const-variable=]
69 | static const unsigned long LOCKF_USED_IN_IRQ_READ =
| ^~~~~~~~~~~~~~~~~~~~~~
kernel/locking/lockdep_internals.h:63:28: error: 'LOCKF_ENABLED_IRQ_READ' defined but not used [-Werror=unused-const-variable=]
63 | static const unsigned long LOCKF_ENABLED_IRQ_READ =
| ^~~~~~~~~~~~~~~~~~~~~~
kernel/locking/lockdep_internals.h:57:28: error: 'LOCKF_USED_IN_IRQ' defined but not used [-Werror=unused-const-variable=]
57 | static const unsigned long LOCKF_USED_IN_IRQ =
| ^~~~~~~~~~~~~~~~~
kernel/locking/lockdep_internals.h:51:28: error: 'LOCKF_ENABLED_IRQ' defined but not used [-Werror=unused-const-variable=]
51 | static const unsigned long LOCKF_ENABLED_IRQ =
| ^~~~~~~~~~~~~~~~~
This one is easy to avoid by changing the generated constant definition
into an equivalent enum.
Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250409122314.2848028-6-arnd@kernel.org
---
kernel/locking/lockdep_internals.h | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
From: Ran Xiaokai <redacted>
hung_task_{set,clear}_blocker() is already guarded by
CONFIG_DETECT_HUNG_TASK_BLOCKER in hung_task.h, So remove
the redudant check of #ifdef.
Signed-off-by: Ran Xiaokai <redacted>
Acked-by: Waiman Long <longman@redhat.com>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250704015218.359754-1-ranxiaokai627@163.com
---
kernel/locking/mutex.c | 4 ----
1 file changed, 4 deletions(-)
From: Breno Leitao <leitao@debian.org>
lockdep_unregister_key() is called from critical code paths, including
sections where rtnl_lock() is held. For example, when replacing a qdisc
in a network device, network egress traffic is disabled while
__qdisc_destroy() is called for every network queue.
If lockdep is enabled, __qdisc_destroy() calls lockdep_unregister_key(),
which gets blocked waiting for synchronize_rcu() to complete.
For example, a simple tc command to replace a qdisc could take 13
seconds:
# time /usr/sbin/tc qdisc replace dev eth0 root handle 0x1: mq
real 0m13.195s
user 0m0.001s
sys 0m2.746s
During this time, network egress is completely frozen while waiting for
RCU synchronization.
Use synchronize_rcu_expedited() instead to minimize the impact on
critical operations like network connectivity changes.
This improves 10x the function call to tc, when replacing the qdisc for
a network card.
# time /usr/sbin/tc qdisc replace dev eth0 root handle 0x1: mq
real 0m1.789s
user 0m0.000s
sys 0m1.613s
[boqun: Fixed the comment and add more information for the temporary
workaround, and add TODO information for hazptr]
Reported-by: Erik Lundgren <redacted>
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Eric Dumazet <redacted>
Signed-off-by: Boqun Feng <redacted>
Link: https://lore.kernel.org/r/20250321-lockdep-v1-1-78b732d195fb@debian.org
---
kernel/locking/lockdep.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)