]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
block: introduce init_wait_func()
authorMuchun Song <songmuchun@bytedance.com>
Sat, 8 Feb 2025 09:04:15 +0000 (17:04 +0800)
committerJens Axboe <axboe@kernel.dk>
Tue, 11 Feb 2025 20:04:11 +0000 (13:04 -0700)
There is already a macro DEFINE_WAIT_FUNC() to declare a wait_queue_entry
with a specified waking function. But there is not a counterpart for
initializing one wait_queue_entry with a specified waking function. So
introducing init_wait_func() for this, which also could be used in iocost
and rq-qos. Using default_wake_function() in rq_qos_wait() to wake up
waiters, which could remove ->task field from rq_qos_wait_data.

Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Muchun Song <songmuchun@bytedance.com>
Acked-by: Tejun Heo <tj@kernel.org>
Link: https://lore.kernel.org/r/20250208090416.38642-1-songmuchun@bytedance.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-iocost.c
block/blk-rq-qos.c
include/linux/wait.h

index 65a1d4427ccf4beefeaf2e5b3478b8d300f47189..6be46e28459be93617b5d4302b2837fa56a4f06b 100644 (file)
@@ -2718,8 +2718,7 @@ retry_lock:
         * All waiters are on iocg->waitq and the wait states are
         * synchronized using waitq.lock.
         */
-       init_waitqueue_func_entry(&wait.wait, iocg_wake_fn);
-       wait.wait.private = current;
+       init_wait_func(&wait.wait, iocg_wake_fn);
        wait.bio = bio;
        wait.abs_cost = abs_cost;
        wait.committed = false; /* will be set true by waker */
index d4d4f4dc0e23fed61b4d65ab4492c673ba584383..0ed3c81723bbb3daeb7c43d9ff423236deda4916 100644 (file)
@@ -196,7 +196,6 @@ bool rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle)
 
 struct rq_qos_wait_data {
        struct wait_queue_entry wq;
-       struct task_struct *task;
        struct rq_wait *rqw;
        acquire_inflight_cb_t *cb;
        void *private_data;
@@ -218,7 +217,12 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr,
                return -1;
 
        data->got_token = true;
-       wake_up_process(data->task);
+       /*
+        * autoremove_wake_function() removes the wait entry only when it
+        * actually changed the task state. We want the wait always removed.
+        * Remove explicitly and use default_wake_function().
+        */
+       default_wake_function(curr, mode, wake_flags, key);
        list_del_init_careful(&curr->entry);
        return 1;
 }
@@ -244,11 +248,6 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
                 cleanup_cb_t *cleanup_cb)
 {
        struct rq_qos_wait_data data = {
-               .wq = {
-                       .func   = rq_qos_wake_function,
-                       .entry  = LIST_HEAD_INIT(data.wq.entry),
-               },
-               .task = current,
                .rqw = rqw,
                .cb = acquire_inflight_cb,
                .private_data = private_data,
@@ -259,6 +258,7 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
        if (!has_sleeper && acquire_inflight_cb(rqw, private_data))
                return;
 
+       init_wait_func(&data.wq, rq_qos_wake_function);
        has_sleeper = !prepare_to_wait_exclusive(&rqw->wait, &data.wq,
                                                 TASK_UNINTERRUPTIBLE);
        do {
index 6d90ad97440876082512beeb0a59d2e09d082f23..2bdc8f47963bf8a8cbf84b2c15d8aa437fd520e9 100644 (file)
@@ -1207,14 +1207,16 @@ int autoremove_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, i
 
 #define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
 
-#define init_wait(wait)                                                                \
+#define init_wait_func(wait, function)                                         \
        do {                                                                    \
                (wait)->private = current;                                      \
-               (wait)->func = autoremove_wake_function;                        \
+               (wait)->func = function;                                        \
                INIT_LIST_HEAD(&(wait)->entry);                                 \
                (wait)->flags = 0;                                              \
        } while (0)
 
+#define init_wait(wait)        init_wait_func(wait, autoremove_wake_function)
+
 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);