Skip to content

Commit ba28549

Browse files
author
Peter Zijlstra
committed
Merge tag 'lockdep-for-tip.2025.07.16' of git://git.kernel.org/pub/scm/linux/kernel/git/boqun/linux into locking/core
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. Signed-off-by: Peter Zijlstra <[email protected]>
2 parents 7ff495e + 7a3ceda commit ba28549

File tree

10 files changed

+50
-40
lines changed

10 files changed

+50
-40
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
@@ -1273,7 +1273,9 @@ static int nxp_fspi_probe(struct platform_device *pdev)
12731273
if (ret)
12741274
return dev_err_probe(dev, ret, "Failed to request irq\n");
12751275

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

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

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
/*

kernel/locking/rwsem.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,6 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
727727
return ret;
728728
}
729729

730-
#define OWNER_SPINNABLE (OWNER_NULL | OWNER_WRITER | OWNER_READER)
731-
732730
static inline enum owner_state
733731
rwsem_owner_state(struct task_struct *owner, unsigned long flags)
734732
{
@@ -835,7 +833,7 @@ static bool rwsem_optimistic_spin(struct rw_semaphore *sem)
835833
enum owner_state owner_state;
836834

837835
owner_state = rwsem_spin_on_owner(sem);
838-
if (!(owner_state & OWNER_SPINNABLE))
836+
if (owner_state == OWNER_NONSPINNABLE)
839837
break;
840838

841839
/*

rust/kernel/sync/lock.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ impl<T: ?Sized, B: Backend> Lock<T, B> {
175175
/// Tries to acquire the lock.
176176
///
177177
/// Returns a guard that can be used to access the data protected by the lock if successful.
178+
// `Option<T>` is not `#[must_use]` even if `T` is, thus the attribute is needed here.
179+
#[must_use = "if unused, the lock will be immediately unlocked"]
178180
pub fn try_lock(&self) -> Option<Guard<'_, T, B>> {
179181
// SAFETY: The constructor of the type calls `init`, so the existence of the object proves
180182
// that `init` was called.

0 commit comments

Comments
 (0)