block: introduce init_wait_func()
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>pull/1188/head
parent
3bee991f2b
commit
36d03cb327
|
|
@ -2718,8 +2718,7 @@ retry_lock:
|
||||||
* All waiters are on iocg->waitq and the wait states are
|
* All waiters are on iocg->waitq and the wait states are
|
||||||
* synchronized using waitq.lock.
|
* synchronized using waitq.lock.
|
||||||
*/
|
*/
|
||||||
init_waitqueue_func_entry(&wait.wait, iocg_wake_fn);
|
init_wait_func(&wait.wait, iocg_wake_fn);
|
||||||
wait.wait.private = current;
|
|
||||||
wait.bio = bio;
|
wait.bio = bio;
|
||||||
wait.abs_cost = abs_cost;
|
wait.abs_cost = abs_cost;
|
||||||
wait.committed = false; /* will be set true by waker */
|
wait.committed = false; /* will be set true by waker */
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,6 @@ bool rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle)
|
||||||
|
|
||||||
struct rq_qos_wait_data {
|
struct rq_qos_wait_data {
|
||||||
struct wait_queue_entry wq;
|
struct wait_queue_entry wq;
|
||||||
struct task_struct *task;
|
|
||||||
struct rq_wait *rqw;
|
struct rq_wait *rqw;
|
||||||
acquire_inflight_cb_t *cb;
|
acquire_inflight_cb_t *cb;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
|
|
@ -218,7 +217,12 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
data->got_token = true;
|
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);
|
list_del_init_careful(&curr->entry);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -244,11 +248,6 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data,
|
||||||
cleanup_cb_t *cleanup_cb)
|
cleanup_cb_t *cleanup_cb)
|
||||||
{
|
{
|
||||||
struct rq_qos_wait_data data = {
|
struct rq_qos_wait_data data = {
|
||||||
.wq = {
|
|
||||||
.func = rq_qos_wake_function,
|
|
||||||
.entry = LIST_HEAD_INIT(data.wq.entry),
|
|
||||||
},
|
|
||||||
.task = current,
|
|
||||||
.rqw = rqw,
|
.rqw = rqw,
|
||||||
.cb = acquire_inflight_cb,
|
.cb = acquire_inflight_cb,
|
||||||
.private_data = private_data,
|
.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))
|
if (!has_sleeper && acquire_inflight_cb(rqw, private_data))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
init_wait_func(&data.wq, rq_qos_wake_function);
|
||||||
has_sleeper = !prepare_to_wait_exclusive(&rqw->wait, &data.wq,
|
has_sleeper = !prepare_to_wait_exclusive(&rqw->wait, &data.wq,
|
||||||
TASK_UNINTERRUPTIBLE);
|
TASK_UNINTERRUPTIBLE);
|
||||||
do {
|
do {
|
||||||
|
|
|
||||||
|
|
@ -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 DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
|
||||||
|
|
||||||
#define init_wait(wait) \
|
#define init_wait_func(wait, function) \
|
||||||
do { \
|
do { \
|
||||||
(wait)->private = current; \
|
(wait)->private = current; \
|
||||||
(wait)->func = autoremove_wake_function; \
|
(wait)->func = function; \
|
||||||
INIT_LIST_HEAD(&(wait)->entry); \
|
INIT_LIST_HEAD(&(wait)->entry); \
|
||||||
(wait)->flags = 0; \
|
(wait)->flags = 0; \
|
||||||
} while (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);
|
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);
|
extern int task_call_func(struct task_struct *p, task_call_f func, void *arg);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue