Skip to content

Commit 51d7a05

Browse files
Sebastian Andrzej Siewioringomolnar
authored andcommitted
locking/mutex: Redo __mutex_init() to reduce generated code size
mutex_init() invokes __mutex_init() providing the name of the lock and a pointer to a the lock class. With LOCKDEP enabled this information is useful but without LOCKDEP it not used at all. Passing the pointer information of the lock class might be considered negligible but the name of the lock is passed as well and the string is stored. This information is wasting storage. Split __mutex_init() into a _genereic() variant doing the initialisation of the lock and a _lockdep() version which does _genereic() plus the lockdep bits. Restrict the lockdep version to lockdep enabled builds allowing the compiler to remove the unused parameter. This results in the following size reduction: text data bss dec filename | 30237599 8161430 1176624 39575653 vmlinux.defconfig | 3023326 8149142 1176560 39558971 vmlinux.defconfig.patched -4.2KiB -12KiB | 32455099 8471098 12934684 53860881 vmlinux.defconfig.lockdep | 32455100 8471098 12934684 53860882 vmlinux.defconfig.patched.lockdep | 27152407 7191822 2068040 3641226 vmlinux.defconfig.preempt_rt | 27145937 7183630 2067976 36397543 vmlinux.defconfig.patched.preempt_rt -6.3KiB -8KiB | 29382020 7505742 13784608 50672370 vmlinux.defconfig.preempt_rt.lockdep | 29376229 7505742 13784544 50666515 vmlinux.defconfig.patched.preempt_rt.lockdep -5.6KiB [peterz: folded fix from boqun] Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Waiman Long <longman@redhat.com> Link: https://lkml.kernel.org/r/20251125145425.68319-1-boqun.feng@gmail.com Link: https://patch.msgid.link/20251105142350.Tfeevs2N@linutronix.de
1 parent f74cf39 commit 51d7a05

5 files changed

Lines changed: 75 additions & 32 deletions

File tree

include/linux/mutex.h

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,23 @@ do { \
8686
#define DEFINE_MUTEX(mutexname) \
8787
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
8888

89-
extern void __mutex_init(struct mutex *lock, const char *name,
90-
struct lock_class_key *key);
89+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
90+
void mutex_init_lockep(struct mutex *lock, const char *name, struct lock_class_key *key);
91+
92+
static inline void __mutex_init(struct mutex *lock, const char *name,
93+
struct lock_class_key *key)
94+
{
95+
mutex_init_lockep(lock, name, key);
96+
}
97+
#else
98+
extern void mutex_init_generic(struct mutex *lock);
99+
100+
static inline void __mutex_init(struct mutex *lock, const char *name,
101+
struct lock_class_key *key)
102+
{
103+
mutex_init_generic(lock);
104+
}
105+
#endif /* !CONFIG_DEBUG_LOCK_ALLOC */
91106

92107
/**
93108
* mutex_is_locked - is the mutex locked
@@ -111,17 +126,27 @@ extern bool mutex_is_locked(struct mutex *lock);
111126
#define DEFINE_MUTEX(mutexname) \
112127
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
113128

114-
extern void __mutex_rt_init(struct mutex *lock, const char *name,
115-
struct lock_class_key *key);
116-
117129
#define mutex_is_locked(l) rt_mutex_base_is_locked(&(l)->rtmutex)
118130

119-
#define __mutex_init(mutex, name, key) \
120-
do { \
121-
rt_mutex_base_init(&(mutex)->rtmutex); \
122-
__mutex_rt_init((mutex), name, key); \
123-
} while (0)
131+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
132+
extern void mutex_rt_init_lockdep(struct mutex *mutex, const char *name,
133+
struct lock_class_key *key);
134+
135+
static inline void __mutex_init(struct mutex *lock, const char *name,
136+
struct lock_class_key *key)
137+
{
138+
mutex_rt_init_lockdep(lock, name, key);
139+
}
124140

141+
#else
142+
extern void mutex_rt_init_generic(struct mutex *mutex);
143+
144+
static inline void __mutex_init(struct mutex *lock, const char *name,
145+
struct lock_class_key *key)
146+
{
147+
mutex_rt_init_generic(lock);
148+
}
149+
#endif /* !CONFIG_LOCKDEP */
125150
#endif /* CONFIG_PREEMPT_RT */
126151

127152
#ifdef CONFIG_DEBUG_MUTEXES

kernel/locking/mutex-debug.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,8 @@ void debug_mutex_unlock(struct mutex *lock)
7878
}
7979
}
8080

81-
void debug_mutex_init(struct mutex *lock, const char *name,
82-
struct lock_class_key *key)
81+
void debug_mutex_init(struct mutex *lock)
8382
{
84-
#ifdef CONFIG_DEBUG_LOCK_ALLOC
85-
/*
86-
* Make sure we are not reinitializing a held lock:
87-
*/
88-
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
89-
lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP);
90-
#endif
9183
lock->magic = lock;
9284
}
9385

kernel/locking/mutex.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,16 @@
4343
# define MUTEX_WARN_ON(cond)
4444
#endif
4545

46-
void
47-
__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
46+
static void __mutex_init_generic(struct mutex *lock)
4847
{
4948
atomic_long_set(&lock->owner, 0);
5049
raw_spin_lock_init(&lock->wait_lock);
5150
INIT_LIST_HEAD(&lock->wait_list);
5251
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
5352
osq_lock_init(&lock->osq);
5453
#endif
55-
56-
debug_mutex_init(lock, name, key);
54+
debug_mutex_init(lock);
5755
}
58-
EXPORT_SYMBOL(__mutex_init);
5956

6057
static inline struct task_struct *__owner_task(unsigned long owner)
6158
{
@@ -142,6 +139,11 @@ static inline bool __mutex_trylock(struct mutex *lock)
142139
* There is nothing that would stop spreading the lockdep annotations outwards
143140
* except more code.
144141
*/
142+
void mutex_init_generic(struct mutex *lock)
143+
{
144+
__mutex_init_generic(lock);
145+
}
146+
EXPORT_SYMBOL(mutex_init_generic);
145147

146148
/*
147149
* Optimistic trylock that only works in the uncontended case. Make sure to
@@ -166,7 +168,21 @@ static __always_inline bool __mutex_unlock_fast(struct mutex *lock)
166168

167169
return atomic_long_try_cmpxchg_release(&lock->owner, &curr, 0UL);
168170
}
169-
#endif
171+
172+
#else /* !CONFIG_DEBUG_LOCK_ALLOC */
173+
174+
void mutex_init_lockep(struct mutex *lock, const char *name, struct lock_class_key *key)
175+
{
176+
__mutex_init_generic(lock);
177+
178+
/*
179+
* Make sure we are not reinitializing a held lock:
180+
*/
181+
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
182+
lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP);
183+
}
184+
EXPORT_SYMBOL(mutex_init_lockep);
185+
#endif /* !CONFIG_DEBUG_LOCK_ALLOC */
170186

171187
static inline void __mutex_set_flag(struct mutex *lock, unsigned long flag)
172188
{

kernel/locking/mutex.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,14 @@ extern void debug_mutex_add_waiter(struct mutex *lock,
5959
extern void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
6060
struct task_struct *task);
6161
extern void debug_mutex_unlock(struct mutex *lock);
62-
extern void debug_mutex_init(struct mutex *lock, const char *name,
63-
struct lock_class_key *key);
62+
extern void debug_mutex_init(struct mutex *lock);
6463
#else /* CONFIG_DEBUG_MUTEXES */
6564
# define debug_mutex_lock_common(lock, waiter) do { } while (0)
6665
# define debug_mutex_wake_waiter(lock, waiter) do { } while (0)
6766
# define debug_mutex_free_waiter(waiter) do { } while (0)
6867
# define debug_mutex_add_waiter(lock, waiter, ti) do { } while (0)
6968
# define debug_mutex_remove_waiter(lock, waiter, ti) do { } while (0)
7069
# define debug_mutex_unlock(lock) do { } while (0)
71-
# define debug_mutex_init(lock, name, key) do { } while (0)
70+
# define debug_mutex_init(lock) do { } while (0)
7271
#endif /* !CONFIG_DEBUG_MUTEXES */
7372
#endif /* CONFIG_PREEMPT_RT */

kernel/locking/rtmutex_api.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,13 +515,11 @@ void rt_mutex_debug_task_free(struct task_struct *task)
515515

516516
#ifdef CONFIG_PREEMPT_RT
517517
/* Mutexes */
518-
void __mutex_rt_init(struct mutex *mutex, const char *name,
519-
struct lock_class_key *key)
518+
static void __mutex_rt_init_generic(struct mutex *mutex)
520519
{
520+
rt_mutex_base_init(&mutex->rtmutex);
521521
debug_check_no_locks_freed((void *)mutex, sizeof(*mutex));
522-
lockdep_init_map_wait(&mutex->dep_map, name, key, 0, LD_WAIT_SLEEP);
523522
}
524-
EXPORT_SYMBOL(__mutex_rt_init);
525523

526524
static __always_inline int __mutex_lock_common(struct mutex *lock,
527525
unsigned int state,
@@ -542,6 +540,13 @@ static __always_inline int __mutex_lock_common(struct mutex *lock,
542540
}
543541

544542
#ifdef CONFIG_DEBUG_LOCK_ALLOC
543+
void mutex_rt_init_lockdep(struct mutex *mutex, const char *name, struct lock_class_key *key)
544+
{
545+
__mutex_rt_init_generic(mutex);
546+
lockdep_init_map_wait(&mutex->dep_map, name, key, 0, LD_WAIT_SLEEP);
547+
}
548+
EXPORT_SYMBOL(mutex_rt_init_lockdep);
549+
545550
void __sched mutex_lock_nested(struct mutex *lock, unsigned int subclass)
546551
{
547552
__mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass, NULL, _RET_IP_);
@@ -598,6 +603,12 @@ int __sched _mutex_trylock_nest_lock(struct mutex *lock,
598603
EXPORT_SYMBOL_GPL(_mutex_trylock_nest_lock);
599604
#else /* CONFIG_DEBUG_LOCK_ALLOC */
600605

606+
void mutex_rt_init_generic(struct mutex *mutex)
607+
{
608+
__mutex_rt_init_generic(mutex);
609+
}
610+
EXPORT_SYMBOL(mutex_rt_init_generic);
611+
601612
void __sched mutex_lock(struct mutex *lock)
602613
{
603614
__mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, NULL, _RET_IP_);

0 commit comments

Comments
 (0)