The ordinary wait queue and completion declarations statically initialize their embedded locks. Automatic objects need runtime initialization so lockdep receives persistent class keys. Add ASSERT_STATIC_STORAGE() to DECLARE_WAIT_QUEUE_HEAD(), DECLARE_SWAIT_QUEUE_HEAD() and DECLARE_COMPLETION(). Keep the _ONSTACK variants usable without CONFIG_LOCKDEP by expanding to the underlying initializer instead of an asserted declaration. Convert the two automatic completions in the AMS PMU driver to DECLARE_COMPLETION_ONSTACK(). Assisted-by: OpenAI Codex Signed-off-by: Yury Norov --- drivers/macintosh/ams/ams-pmu.c | 4 ++-- include/linux/completion.h | 10 +++++++--- include/linux/swait.h | 6 ++++-- include/linux/wait.h | 7 +++++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/macintosh/ams/ams-pmu.c b/drivers/macintosh/ams/ams-pmu.c index 1c3ce39e9a59..046a7d5dc5b2 100644 --- a/drivers/macintosh/ams/ams-pmu.c +++ b/drivers/macintosh/ams/ams-pmu.c @@ -48,7 +48,7 @@ static void ams_pmu_req_complete(struct adb_request *req) static void ams_pmu_set_register(u8 reg, u8 value) { static struct adb_request req; - DECLARE_COMPLETION(req_complete); + DECLARE_COMPLETION_ONSTACK(req_complete); req.arg = &req_complete; if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value)) @@ -61,7 +61,7 @@ static void ams_pmu_set_register(u8 reg, u8 value) static u8 ams_pmu_get_register(u8 reg) { static struct adb_request req; - DECLARE_COMPLETION(req_complete); + DECLARE_COMPLETION_ONSTACK(req_complete); req.arg = &req_complete; if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg)) diff --git a/include/linux/completion.h b/include/linux/completion.h index fb2915676574..b514b5555722 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h @@ -9,6 +9,7 @@ * See kernel/sched/completion.c for details. */ +#include #include /* @@ -50,7 +51,8 @@ static inline void complete_release(struct completion *x) {} * variables. */ #define DECLARE_COMPLETION(work) \ - struct completion work = COMPLETION_INITIALIZER(work) + struct completion work = COMPLETION_INITIALIZER(work); \ + ASSERT_STATIC_STORAGE(work) /* * Lockdep needs to run a non-constant initializer for on-stack @@ -70,8 +72,10 @@ static inline void complete_release(struct completion *x) {} # define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \ struct completion work = COMPLETION_INITIALIZER_ONSTACK_MAP(work, map) #else -# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work) -# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) DECLARE_COMPLETION(work) +# define DECLARE_COMPLETION_ONSTACK(work) \ + struct completion work = COMPLETION_INITIALIZER(work) +# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \ + DECLARE_COMPLETION_ONSTACK(work) #endif /** diff --git a/include/linux/swait.h b/include/linux/swait.h index d324419482a0..caa3028d1dd0 100644 --- a/include/linux/swait.h +++ b/include/linux/swait.h @@ -2,6 +2,7 @@ #ifndef _LINUX_SWAIT_H #define _LINUX_SWAIT_H +#include #include #include #include @@ -64,7 +65,8 @@ struct swait_queue { } #define DECLARE_SWAIT_QUEUE_HEAD(name) \ - struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name) + struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name); \ + ASSERT_STATIC_STORAGE(name) extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name, struct lock_class_key *key); @@ -82,7 +84,7 @@ extern void __init_swait_queue_head(struct swait_queue_head *q, const char *name struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INIT_ONSTACK(name) #else # define DECLARE_SWAIT_QUEUE_HEAD_ONSTACK(name) \ - DECLARE_SWAIT_QUEUE_HEAD(name) + struct swait_queue_head name = __SWAIT_QUEUE_HEAD_INITIALIZER(name) #endif /** diff --git a/include/linux/wait.h b/include/linux/wait.h index 7e215330199c..5c7d49187396 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -4,6 +4,7 @@ /* * Linux wait queue related types and methods */ +#include #include #include #include @@ -57,7 +58,8 @@ struct task_struct; .head = LIST_HEAD_INIT(name.head) } #define DECLARE_WAIT_QUEUE_HEAD(name) \ - struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name) + struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name); \ + ASSERT_STATIC_STORAGE(name) extern void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *name, struct lock_class_key *); @@ -74,7 +76,8 @@ extern void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *n # define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \ struct wait_queue_head name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) #else -# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name) +# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \ + struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name) #endif static inline void init_waitqueue_entry(struct wait_queue_entry *wq_entry, struct task_struct *p) -- 2.53.0