[RFC PATCH 24/30] wait: Clean up waitqueue_entry initialization

Suren Baghdasaryan
2022-08-30T21:53:52Z

From: Kent Overstreet <kent.overstreet@linux.dev>

Cleanup for code tagging latency tracking:

Add an initializer, WAIT_FUNC_INITIALIZER(), to be used by initializers
for structs that include wait_queue_entries.

Also, change init_wait(), init_wait_entry etc. to be a wrapper around
the new __init_waitqueue_entry(); more de-duplication prep work.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
include/linux/sbitmap.h | 6 +----
include/linux/wait.h | 52 +++++++++++++++++++---------------------
include/linux/wait_bit.h | 7 +-----
kernel/sched/wait.c | 9 -------
4 files changed, 27 insertions(+), 47 deletions(-)

diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h
index 8f5a86e210b9..f696c29d9ab3 100644
--- a/include/linux/sbitmap.h
+++ b/include/linux/sbitmap.h
@@ -596,11 +596,7 @@ struct sbq_wait {
#define DEFINE_SBQ_WAIT(name) \
struct sbq_wait name = { \
.sbq = NULL, \
- .wait = { \
- .private = current, \
- .func = autoremove_wake_function, \
- .entry = LIST_HEAD_INIT((name).wait.entry), \
- } \
+ .wait = WAIT_FUNC_INITIALIZER((name).wait, autoremove_wake_function),\
}

/*
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 58cfbf81447c..91ced6a118bc 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -79,21 +79,38 @@ extern void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *n
# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name)
#endif

-static inline void init_waitqueue_entry(struct wait_queue_entry *wq_entry, struct task_struct *p)
-{
- wq_entry->flags = 0;
- wq_entry->private = p;
- wq_entry->func = default_wake_function;
+#define WAIT_FUNC_INITIALIZER(name, function) { \
+ .private = current, \
+ .func = function, \
+ .entry = LIST_HEAD_INIT((name).entry), \
}

+#define DEFINE_WAIT_FUNC(name, function) \
+ struct wait_queue_entry name = WAIT_FUNC_INITIALIZER(name, function)
+
+#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
+
static inline void
-init_waitqueue_func_entry(struct wait_queue_entry *wq_entry, wait_queue_func_t func)
+__init_waitqueue_entry(struct wait_queue_entry *wq_entry, unsigned int flags,
+ void *private, wait_queue_func_t func)
{
- wq_entry->flags = 0;
- wq_entry->private = NULL;
+ wq_entry->flags = flags;
+ wq_entry->private = private;
wq_entry->func = func;
+ INIT_LIST_HEAD(&wq_entry->entry);
}

+#define init_waitqueue_func_entry(_wq_entry, _func) \
+ __init_waitqueue_entry(_wq_entry, 0, NULL, _func)
+
+#define init_waitqueue_entry(_wq_entry, _task) \
+ __init_waitqueue_entry(_wq_entry, 0, _task, default_wake_function)
+
+#define init_wait_entry(_wq_entry, _flags) \
+ __init_waitqueue_entry(_wq_entry, _flags, current, autoremove_wake_function)
+
+#define init_wait(wait) init_wait_entry(wait, 0)
+
/**
* waitqueue_active -- locklessly test for waiters on the queue
* @wq_head: the waitqueue to test for waiters
@@ -283,8 +300,6 @@ static inline void wake_up_pollfree(struct wait_queue_head *wq_head)
(!__builtin_constant_p(state) || \
state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE) \

-extern void init_wait_entry(struct wait_queue_entry *wq_entry, int flags);
-
/*
* The below macro ___wait_event() has an explicit shadow of the __ret
* variable when used from the wait_event_*() macros.
@@ -1170,23 +1185,6 @@ long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout);
int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key);
int autoremove_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key);

-#define DEFINE_WAIT_FUNC(name, function) \
- struct wait_queue_entry name = { \
- .private = current, \
- .func = function, \
- .entry = LIST_HEAD_INIT((name).entry), \
- }
-
-#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
-
-#define init_wait(wait) \
- do { \
- (wait)->private = current; \
- (wait)->func = autoremove_wake_function; \
- INIT_LIST_HEAD(&(wait)->entry); \
- (wait)->flags = 0; \
- } while (0)
-
typedef int (*task_call_f)(struct task_struct *p, void *arg);
extern int task_call_func(struct task_struct *p, task_call_f func, void *arg);

diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h
index 7725b7579b78..267ca0fe9fd9 100644
--- a/include/linux/wait_bit.h
+++ b/include/linux/wait_bit.h
@@ -38,12 +38,7 @@ int wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync
#define DEFINE_WAIT_BIT(name, word, bit) \
struct wait_bit_queue_entry name = { \
.key = __WAIT_BIT_KEY_INITIALIZER(word, bit), \
- .wq_entry = { \
- .private = current, \
- .func = wake_bit_function, \
- .entry = \
- LIST_HEAD_INIT((name).wq_entry.entry), \
- }, \
+ .wq_entry = WAIT_FUNC_INITIALIZER((name).wq_entry, wake_bit_function),\
}

extern int bit_wait(struct wait_bit_key *key, int mode);
diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c
index 9860bb9a847c..b9922346077d 100644
--- a/kernel/sched/wait.c
+++ b/kernel/sched/wait.c
@@ -289,15 +289,6 @@ prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_ent
}
EXPORT_SYMBOL(prepare_to_wait_exclusive);

-void init_wait_entry(struct wait_queue_entry *wq_entry, int flags)
-{
- wq_entry->flags = flags;
- wq_entry->private = current;
- wq_entry->func = autoremove_wake_function;
- INIT_LIST_HEAD(&wq_entry->entry);
-}
-EXPORT_SYMBOL(init_wait_entry);
-
long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
{
unsigned long flags;
--
2.37.2.672.g94769d06f0-goog