Skip to content

Commit 72b8944

Browse files
committed
Merge tag 'locking-core-2025-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking updates from Ingo Molnar: "Locking primitives: - Mark devm_mutex_init() as __must_check and fix drivers that didn't check the return code (Thomas Weißschuh) - Reorganize <linux/local_lock.h> to better expose the internal APIs to local variables (Sebastian Andrzej Siewior) - Remove OWNER_SPINNABLE in rwsem (Jinliang Zheng) - Remove redundant #ifdefs in the mutex code (Ran Xiaokai) Lockdep: - Avoid returning struct in lock_stats() (Arnd Bergmann) - Change `static const` into enum for LOCKF_*_IRQ_* (Arnd Bergmann) - Temporarily use synchronize_rcu_expedited() in lockdep_unregister_key() to speed things up. (Breno Leitao) Rust runtime: - Add #[must_use] to Lock::try_lock() (Jason Devers)" * tag 'locking-core-2025-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: lockdep: Speed up lockdep_unregister_key() with expedited RCU synchronization locking/mutex: Remove redundant #ifdefs locking/lockdep: Change 'static const' variables to enum values locking/lockdep: Avoid struct return in lock_stats() locking/rwsem: Use OWNER_NONSPINNABLE directly instead of OWNER_SPINNABLE rust: sync: Add #[must_use] to Lock::try_lock() locking/mutex: Mark devm_mutex_init() as __must_check leds: lp8860: Check return value of devm_mutex_init() spi: spi-nxp-fspi: Check return value of devm_mutex_init() local_lock: Move this_cpu_ptr() notation from internal to main header
2 parents bcb48dd + ba28549 commit 72b8944

File tree

12 files changed

+75
-65
lines changed

12 files changed

+75
-65
lines changed

drivers/leds/leds-lp8860.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,9 @@ static int lp8860_probe(struct i2c_client *client)
307307
led->client = client;
308308
led->led_dev.brightness_set_blocking = lp8860_brightness_set;
309309

310-
devm_mutex_init(&client->dev, &led->lock);
310+
ret = devm_mutex_init(&client->dev, &led->lock);
311+
if (ret)
312+
return dev_err_probe(&client->dev, ret, "Failed to initialize lock\n");
311313

312314
led->regmap = devm_regmap_init_i2c(client, &lp8860_regmap_config);
313315
if (IS_ERR(led->regmap)) {

drivers/spi/spi-nxp-fspi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,9 @@ static int nxp_fspi_probe(struct platform_device *pdev)
12721272
if (ret)
12731273
return dev_err_probe(dev, ret, "Failed to request irq\n");
12741274

1275-
devm_mutex_init(dev, &f->lock);
1275+
ret = devm_mutex_init(dev, &f->lock);
1276+
if (ret)
1277+
return dev_err_probe(dev, ret, "Failed to initialize lock\n");
12761278

12771279
ctlr->bus_num = -1;
12781280
ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;

include/linux/local_lock.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
* local_lock - Acquire a per CPU local lock
1414
* @lock: The lock variable
1515
*/
16-
#define local_lock(lock) __local_lock(lock)
16+
#define local_lock(lock) __local_lock(this_cpu_ptr(lock))
1717

1818
/**
1919
* local_lock_irq - Acquire a per CPU local lock and disable interrupts
2020
* @lock: The lock variable
2121
*/
22-
#define local_lock_irq(lock) __local_lock_irq(lock)
22+
#define local_lock_irq(lock) __local_lock_irq(this_cpu_ptr(lock))
2323

2424
/**
2525
* local_lock_irqsave - Acquire a per CPU local lock, save and disable
@@ -28,19 +28,19 @@
2828
* @flags: Storage for interrupt flags
2929
*/
3030
#define local_lock_irqsave(lock, flags) \
31-
__local_lock_irqsave(lock, flags)
31+
__local_lock_irqsave(this_cpu_ptr(lock), flags)
3232

3333
/**
3434
* local_unlock - Release a per CPU local lock
3535
* @lock: The lock variable
3636
*/
37-
#define local_unlock(lock) __local_unlock(lock)
37+
#define local_unlock(lock) __local_unlock(this_cpu_ptr(lock))
3838

3939
/**
4040
* local_unlock_irq - Release a per CPU local lock and enable interrupts
4141
* @lock: The lock variable
4242
*/
43-
#define local_unlock_irq(lock) __local_unlock_irq(lock)
43+
#define local_unlock_irq(lock) __local_unlock_irq(this_cpu_ptr(lock))
4444

4545
/**
4646
* local_unlock_irqrestore - Release a per CPU local lock and restore
@@ -49,7 +49,7 @@
4949
* @flags: Interrupt flags to restore
5050
*/
5151
#define local_unlock_irqrestore(lock, flags) \
52-
__local_unlock_irqrestore(lock, flags)
52+
__local_unlock_irqrestore(this_cpu_ptr(lock), flags)
5353

5454
/**
5555
* local_lock_init - Runtime initialize a lock instance
@@ -64,7 +64,7 @@
6464
* locking constrains it will _always_ fail to acquire the lock in NMI or
6565
* HARDIRQ context on PREEMPT_RT.
6666
*/
67-
#define local_trylock(lock) __local_trylock(lock)
67+
#define local_trylock(lock) __local_trylock(this_cpu_ptr(lock))
6868

6969
/**
7070
* local_trylock_irqsave - Try to acquire a per CPU local lock, save and disable
@@ -77,7 +77,7 @@
7777
* HARDIRQ context on PREEMPT_RT.
7878
*/
7979
#define local_trylock_irqsave(lock, flags) \
80-
__local_trylock_irqsave(lock, flags)
80+
__local_trylock_irqsave(this_cpu_ptr(lock), flags)
8181

8282
DEFINE_GUARD(local_lock, local_lock_t __percpu*,
8383
local_lock(_T),
@@ -91,10 +91,10 @@ DEFINE_LOCK_GUARD_1(local_lock_irqsave, local_lock_t __percpu,
9191
unsigned long flags)
9292

9393
#define local_lock_nested_bh(_lock) \
94-
__local_lock_nested_bh(_lock)
94+
__local_lock_nested_bh(this_cpu_ptr(_lock))
9595

9696
#define local_unlock_nested_bh(_lock) \
97-
__local_unlock_nested_bh(_lock)
97+
__local_unlock_nested_bh(this_cpu_ptr(_lock))
9898

9999
DEFINE_GUARD(local_lock_nested_bh, local_lock_t __percpu*,
100100
local_lock_nested_bh(_T),

include/linux/local_lock_internal.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ do { \
9999
local_trylock_t *tl; \
100100
local_lock_t *l; \
101101
\
102-
l = (local_lock_t *)this_cpu_ptr(lock); \
102+
l = (local_lock_t *)(lock); \
103103
tl = (local_trylock_t *)l; \
104104
_Generic((lock), \
105-
__percpu local_trylock_t *: ({ \
105+
local_trylock_t *: ({ \
106106
lockdep_assert(tl->acquired == 0); \
107107
WRITE_ONCE(tl->acquired, 1); \
108108
}), \
109-
__percpu local_lock_t *: (void)0); \
109+
local_lock_t *: (void)0); \
110110
local_lock_acquire(l); \
111111
} while (0)
112112

@@ -133,7 +133,7 @@ do { \
133133
local_trylock_t *tl; \
134134
\
135135
preempt_disable(); \
136-
tl = this_cpu_ptr(lock); \
136+
tl = (lock); \
137137
if (READ_ONCE(tl->acquired)) { \
138138
preempt_enable(); \
139139
tl = NULL; \
@@ -150,7 +150,7 @@ do { \
150150
local_trylock_t *tl; \
151151
\
152152
local_irq_save(flags); \
153-
tl = this_cpu_ptr(lock); \
153+
tl = (lock); \
154154
if (READ_ONCE(tl->acquired)) { \
155155
local_irq_restore(flags); \
156156
tl = NULL; \
@@ -167,15 +167,15 @@ do { \
167167
local_trylock_t *tl; \
168168
local_lock_t *l; \
169169
\
170-
l = (local_lock_t *)this_cpu_ptr(lock); \
170+
l = (local_lock_t *)(lock); \
171171
tl = (local_trylock_t *)l; \
172172
local_lock_release(l); \
173173
_Generic((lock), \
174-
__percpu local_trylock_t *: ({ \
174+
local_trylock_t *: ({ \
175175
lockdep_assert(tl->acquired == 1); \
176176
WRITE_ONCE(tl->acquired, 0); \
177177
}), \
178-
__percpu local_lock_t *: (void)0); \
178+
local_lock_t *: (void)0); \
179179
} while (0)
180180

181181
#define __local_unlock(lock) \
@@ -199,11 +199,11 @@ do { \
199199
#define __local_lock_nested_bh(lock) \
200200
do { \
201201
lockdep_assert_in_softirq(); \
202-
local_lock_acquire(this_cpu_ptr(lock)); \
202+
local_lock_acquire((lock)); \
203203
} while (0)
204204

205205
#define __local_unlock_nested_bh(lock) \
206-
local_lock_release(this_cpu_ptr(lock))
206+
local_lock_release((lock))
207207

208208
#else /* !CONFIG_PREEMPT_RT */
209209

@@ -227,7 +227,7 @@ typedef spinlock_t local_trylock_t;
227227
#define __local_lock(__lock) \
228228
do { \
229229
migrate_disable(); \
230-
spin_lock(this_cpu_ptr((__lock))); \
230+
spin_lock((__lock)); \
231231
} while (0)
232232

233233
#define __local_lock_irq(lock) __local_lock(lock)
@@ -241,7 +241,7 @@ typedef spinlock_t local_trylock_t;
241241

242242
#define __local_unlock(__lock) \
243243
do { \
244-
spin_unlock(this_cpu_ptr((__lock))); \
244+
spin_unlock((__lock)); \
245245
migrate_enable(); \
246246
} while (0)
247247

@@ -252,12 +252,12 @@ typedef spinlock_t local_trylock_t;
252252
#define __local_lock_nested_bh(lock) \
253253
do { \
254254
lockdep_assert_in_softirq_func(); \
255-
spin_lock(this_cpu_ptr(lock)); \
255+
spin_lock((lock)); \
256256
} while (0)
257257

258258
#define __local_unlock_nested_bh(lock) \
259259
do { \
260-
spin_unlock(this_cpu_ptr((lock))); \
260+
spin_unlock((lock)); \
261261
} while (0)
262262

263263
#define __local_trylock(lock) \
@@ -268,7 +268,7 @@ do { \
268268
__locked = 0; \
269269
} else { \
270270
migrate_disable(); \
271-
__locked = spin_trylock(this_cpu_ptr((lock))); \
271+
__locked = spin_trylock((lock)); \
272272
if (!__locked) \
273273
migrate_enable(); \
274274
} \

include/linux/lockdep_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ struct lock_class_stats {
175175
unsigned long bounces[nr_bounce_types];
176176
};
177177

178-
struct lock_class_stats lock_stats(struct lock_class *class);
178+
void lock_stats(struct lock_class *class, struct lock_class_stats *stats);
179179
void clear_lock_stats(struct lock_class *class);
180180
#endif
181181

include/linux/mutex.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,11 @@ do { \
126126

127127
#ifdef CONFIG_DEBUG_MUTEXES
128128

129-
int __devm_mutex_init(struct device *dev, struct mutex *lock);
129+
int __must_check __devm_mutex_init(struct device *dev, struct mutex *lock);
130130

131131
#else
132132

133-
static inline int __devm_mutex_init(struct device *dev, struct mutex *lock)
133+
static inline int __must_check __devm_mutex_init(struct device *dev, struct mutex *lock)
134134
{
135135
/*
136136
* When CONFIG_DEBUG_MUTEXES is off mutex_destroy() is just a nop so
@@ -141,14 +141,17 @@ static inline int __devm_mutex_init(struct device *dev, struct mutex *lock)
141141

142142
#endif
143143

144-
#define devm_mutex_init(dev, mutex) \
144+
#define __mutex_init_ret(mutex) \
145145
({ \
146146
typeof(mutex) mutex_ = (mutex); \
147147
\
148148
mutex_init(mutex_); \
149-
__devm_mutex_init(dev, mutex_); \
149+
mutex_; \
150150
})
151151

152+
#define devm_mutex_init(dev, mutex) \
153+
__devm_mutex_init(dev, __mutex_init_ret(mutex))
154+
152155
/*
153156
* See kernel/locking/mutex.c for detailed documentation of these APIs.
154157
* Also see Documentation/locking/mutex-design.rst.

kernel/locking/lockdep.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -297,33 +297,30 @@ static inline void lock_time_add(struct lock_time *src, struct lock_time *dst)
297297
dst->nr += src->nr;
298298
}
299299

300-
struct lock_class_stats lock_stats(struct lock_class *class)
300+
void lock_stats(struct lock_class *class, struct lock_class_stats *stats)
301301
{
302-
struct lock_class_stats stats;
303302
int cpu, i;
304303

305-
memset(&stats, 0, sizeof(struct lock_class_stats));
304+
memset(stats, 0, sizeof(struct lock_class_stats));
306305
for_each_possible_cpu(cpu) {
307306
struct lock_class_stats *pcs =
308307
&per_cpu(cpu_lock_stats, cpu)[class - lock_classes];
309308

310-
for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++)
311-
stats.contention_point[i] += pcs->contention_point[i];
309+
for (i = 0; i < ARRAY_SIZE(stats->contention_point); i++)
310+
stats->contention_point[i] += pcs->contention_point[i];
312311

313-
for (i = 0; i < ARRAY_SIZE(stats.contending_point); i++)
314-
stats.contending_point[i] += pcs->contending_point[i];
312+
for (i = 0; i < ARRAY_SIZE(stats->contending_point); i++)
313+
stats->contending_point[i] += pcs->contending_point[i];
315314

316-
lock_time_add(&pcs->read_waittime, &stats.read_waittime);
317-
lock_time_add(&pcs->write_waittime, &stats.write_waittime);
315+
lock_time_add(&pcs->read_waittime, &stats->read_waittime);
316+
lock_time_add(&pcs->write_waittime, &stats->write_waittime);
318317

319-
lock_time_add(&pcs->read_holdtime, &stats.read_holdtime);
320-
lock_time_add(&pcs->write_holdtime, &stats.write_holdtime);
318+
lock_time_add(&pcs->read_holdtime, &stats->read_holdtime);
319+
lock_time_add(&pcs->write_holdtime, &stats->write_holdtime);
321320

322-
for (i = 0; i < ARRAY_SIZE(stats.bounces); i++)
323-
stats.bounces[i] += pcs->bounces[i];
321+
for (i = 0; i < ARRAY_SIZE(stats->bounces); i++)
322+
stats->bounces[i] += pcs->bounces[i];
324323
}
325-
326-
return stats;
327324
}
328325

329326
void clear_lock_stats(struct lock_class *class)
@@ -6619,8 +6616,16 @@ void lockdep_unregister_key(struct lock_class_key *key)
66196616
if (need_callback)
66206617
call_rcu(&delayed_free.rcu_head, free_zapped_rcu);
66216618

6622-
/* Wait until is_dynamic_key() has finished accessing k->hash_entry. */
6623-
synchronize_rcu();
6619+
/*
6620+
* Wait until is_dynamic_key() has finished accessing k->hash_entry.
6621+
*
6622+
* Some operations like __qdisc_destroy() will call this in a debug
6623+
* kernel, and the network traffic is disabled while waiting, hence
6624+
* the delay of the wait matters in debugging cases. Currently use a
6625+
* synchronize_rcu_expedited() to speed up the wait at the cost of
6626+
* system IPIs. TODO: Replace RCU with hazptr for this.
6627+
*/
6628+
synchronize_rcu_expedited();
66246629
}
66256630
EXPORT_SYMBOL_GPL(lockdep_unregister_key);
66266631

kernel/locking/lockdep_internals.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,31 @@ enum {
4747
__LOCKF(USED_READ)
4848
};
4949

50+
enum {
5051
#define LOCKDEP_STATE(__STATE) LOCKF_ENABLED_##__STATE |
51-
static const unsigned long LOCKF_ENABLED_IRQ =
52+
LOCKF_ENABLED_IRQ =
5253
#include "lockdep_states.h"
53-
0;
54+
0,
5455
#undef LOCKDEP_STATE
5556

5657
#define LOCKDEP_STATE(__STATE) LOCKF_USED_IN_##__STATE |
57-
static const unsigned long LOCKF_USED_IN_IRQ =
58+
LOCKF_USED_IN_IRQ =
5859
#include "lockdep_states.h"
59-
0;
60+
0,
6061
#undef LOCKDEP_STATE
6162

6263
#define LOCKDEP_STATE(__STATE) LOCKF_ENABLED_##__STATE##_READ |
63-
static const unsigned long LOCKF_ENABLED_IRQ_READ =
64+
LOCKF_ENABLED_IRQ_READ =
6465
#include "lockdep_states.h"
65-
0;
66+
0,
6667
#undef LOCKDEP_STATE
6768

6869
#define LOCKDEP_STATE(__STATE) LOCKF_USED_IN_##__STATE##_READ |
69-
static const unsigned long LOCKF_USED_IN_IRQ_READ =
70+
LOCKF_USED_IN_IRQ_READ =
7071
#include "lockdep_states.h"
71-
0;
72+
0,
7273
#undef LOCKDEP_STATE
74+
};
7375

7476
#define LOCKF_ENABLED_IRQ_ALL (LOCKF_ENABLED_IRQ | LOCKF_ENABLED_IRQ_READ)
7577
#define LOCKF_USED_IN_IRQ_ALL (LOCKF_USED_IN_IRQ | LOCKF_USED_IN_IRQ_READ)

kernel/locking/lockdep_proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ static int lock_stat_open(struct inode *inode, struct file *file)
657657
if (!test_bit(idx, lock_classes_in_use))
658658
continue;
659659
iter->class = class;
660-
iter->stats = lock_stats(class);
660+
lock_stats(class, &iter->stats);
661661
iter++;
662662
}
663663

kernel/locking/mutex.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,7 @@ static void
191191
__mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
192192
struct list_head *list)
193193
{
194-
#ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER
195194
hung_task_set_blocker(lock, BLOCKER_TYPE_MUTEX);
196-
#endif
197195
debug_mutex_add_waiter(lock, waiter, current);
198196

199197
list_add_tail(&waiter->list, list);
@@ -209,9 +207,7 @@ __mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter)
209207
__mutex_clear_flag(lock, MUTEX_FLAGS);
210208

211209
debug_mutex_remove_waiter(lock, waiter, current);
212-
#ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER
213210
hung_task_clear_blocker();
214-
#endif
215211
}
216212

217213
/*

0 commit comments

Comments
 (0)