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 <[email protected]>
---
 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 <linux/compiler.h>
 #include <linux/swait.h>
 
 /*
@@ -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 <linux/compiler.h>
 #include <linux/list.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
@@ -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 <linux/compiler.h>
 #include <linux/list.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
@@ -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


Reply via email to