Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

locking/mutex: Introduce devm_mutex_init()

Using of devm API leads to a certain order of releasing resources.
So all dependent resources which are not devm-wrapped should be deleted
with respect to devm-release order. Mutex is one of such objects that
often is bound to other resources and has no own devm wrapping.
Since mutex_destroy() actually does nothing in non-debug builds
frequently calling mutex_destroy() is just ignored which is safe for now
but wrong formally and can lead to a problem if mutex_destroy() will be
extended so introduce devm_mutex_init().

Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: George Stark <gnstark@salutedevices.com>
Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Marek Behún <kabel@kernel.org>
Acked-by: Waiman Long <longman@redhat.com>
Link: https://lore.kernel.org/r/20240411161032.609544-2-gnstark@salutedevices.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

George Stark and committed by
Lee Jones
4cd47222 4cece764

+39
+27
include/linux/mutex.h
··· 22 22 #include <linux/cleanup.h> 23 23 #include <linux/mutex_types.h> 24 24 25 + struct device; 26 + 25 27 #ifdef CONFIG_DEBUG_LOCK_ALLOC 26 28 # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ 27 29 , .dep_map = { \ ··· 118 116 __mutex_init((mutex), #mutex, &__key); \ 119 117 } while (0) 120 118 #endif /* CONFIG_PREEMPT_RT */ 119 + 120 + #ifdef CONFIG_DEBUG_MUTEXES 121 + 122 + int __devm_mutex_init(struct device *dev, struct mutex *lock); 123 + 124 + #else 125 + 126 + static inline int __devm_mutex_init(struct device *dev, struct mutex *lock) 127 + { 128 + /* 129 + * When CONFIG_DEBUG_MUTEXES is off mutex_destroy() is just a nop so 130 + * no really need to register it in the devm subsystem. 131 + */ 132 + return 0; 133 + } 134 + 135 + #endif 136 + 137 + #define devm_mutex_init(dev, mutex) \ 138 + ({ \ 139 + typeof(mutex) mutex_ = (mutex); \ 140 + \ 141 + mutex_init(mutex_); \ 142 + __devm_mutex_init(dev, mutex_); \ 143 + }) 121 144 122 145 /* 123 146 * See kernel/locking/mutex.c for detailed documentation of these APIs.
+12
kernel/locking/mutex-debug.c
··· 12 12 */ 13 13 #include <linux/mutex.h> 14 14 #include <linux/delay.h> 15 + #include <linux/device.h> 15 16 #include <linux/export.h> 16 17 #include <linux/poison.h> 17 18 #include <linux/sched.h> ··· 89 88 #endif 90 89 lock->magic = lock; 91 90 } 91 + 92 + static void devm_mutex_release(void *res) 93 + { 94 + mutex_destroy(res); 95 + } 96 + 97 + int __devm_mutex_init(struct device *dev, struct mutex *lock) 98 + { 99 + return devm_add_action_or_reset(dev, devm_mutex_release, lock); 100 + } 101 + EXPORT_SYMBOL_GPL(__devm_mutex_init); 92 102 93 103 /*** 94 104 * mutex_destroy - mark a mutex unusable