io_uring task_work cleanups
Jens Axboe
maintainercover io_uring task_work cleanups
Nothing exciting here, just a set of cleanups around task_work.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/2 io_uring: abstract out task work running
Provide a helper to run task_work instead of checking and running manually in a bunch of different spots. While doing so, also move the task run state setting where we run the task work. Then we can move it out of the callback helpers. This also helps ensure we only do this once per task_work list run, not per task_work item.
Suggested-by Oleg Nesterov <[email protected]>
Signed-off-by Jens Axboe <[email protected]>
--- fs/io_uring.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-)
fs/io_uring.c +19 -17
@@ -1714,7 +1714,6 @@ static void __io_req_task_submit(struct io_kiocb *req) {struct io_ring_ctx *ctx = req->ctx; -__set_current_state (TASK_RUNNING );if (!__io_sq_thread_acquire_mm (ctx)) {mutex_lock (&ctx->uring_lock);__io_queue_sqe (req,NULL ,NULL );
@@ -1899,6 +1898,17 @@ static int io_put_kbuf(struct io_kiocb *req)return cflags; } +static inline bool io_run_task_work (void ) +{ +if (current->task_works) { +__set_current_state (TASK_RUNNING ); +task_work_run (); +return true; + } + +return false; +} +static void io_iopoll_queue (struct list_head *again) {struct io_kiocb *req;
@@ -2079,8 +2089,7 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events,*/ if (!(++iters &7 )) {mutex_unlock (&ctx->uring_lock); -if (current->task_works) -task_work_run (); +io_run_task_work ();mutex_lock (&ctx->uring_lock); }
@@ -2176,8 +2185,6 @@ static void io_rw_resubmit(struct callback_head *cb)struct io_ring_ctx *ctx = req->ctx;int err; -__set_current_state (TASK_RUNNING ); - err =io_sq_thread_acquire_mm (ctx, req);if (io_resubmit_prep (req, err)) {
@@ -6353,8 +6360,7 @@ static int io_sq_thread(void *data)if (!list_empty (&ctx->poll_list) ||need_resched () || (!time_after (jiffies, timeout) && ret != -EBUSY && !percpu_ref_is_dying (&ctx->refs))) { -if (current->task_works) -task_work_run (); +io_run_task_work ();cond_resched ();continue ; }
@@ -6386,8 +6392,7 @@ static int io_sq_thread(void *data)finish_wait (&ctx->sqo_wait, &wait);break ; } -if (current->task_works) { -task_work_run (); +if (io_run_task_work ()) {finish_wait (&ctx->sqo_wait, &wait);continue ; }
@@ -6412,8 +6417,7 @@ static int io_sq_thread(void *data) timeout = jiffies + ctx->sq_thread_idle; } -if (current->task_works) -task_work_run (); +io_run_task_work ();io_sq_thread_drop_mm (ctx);revert_creds (old_cred);
@@ -6478,9 +6482,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,do {if (io_cqring_events (ctx, false) >= min_events)return 0 ; -if (!current->task_works) +if (!io_run_task_work ())break ; -task_work_run (); }while (1 );if (sig) {
@@ -6502,8 +6505,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,prepare_to_wait_exclusive (&ctx->wait, &iowq.wq,TASK_INTERRUPTIBLE );/* make sure we run task_work before checking for signals */ -if (current->task_works) -task_work_run (); +if (io_run_task_work ()) +continue ;if (signal_pending (current)) { ret = -ERESTARTSYS ;break ;
@@ -7938,8 +7941,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,int submitted =0 ;struct fd f; -if (current->task_works) -task_work_run (); +io_run_task_work ();if (flags & ~(IORING_ENTER_GETEVENTS |IORING_ENTER_SQ_WAKEUP ))return -EINVAL ;
Signature · 1 line
2.27.0
Jens Axboe
maintainerPATCH 2/2 io_uring: use new io_req_task_work_add() helper throughout
In reply to Jens AxboeSince we now have that in the 5.9 branch, convert the existing users of task_work_add() to use this new helper.
Signed-off-by Jens Axboe <[email protected]>
--- fs/io_uring.c | 62 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 32 deletions(-)
fs/io_uring.c +30 -32
@@ -1689,6 +1689,22 @@ static struct io_kiocb *io_req_find_next(struct io_kiocb *req)return __io_req_find_next (req); } +static int io_req_task_work_add (struct io_kiocb *req,struct callback_head *cb, +int notify) +{ +const bool is_sqthread = (req->ctx->flags &IORING_SETUP_SQPOLL ) !=0 ; +struct task_struct *tsk = req->task; +int ret; + +if (is_sqthread) + notify =0 ; + + ret =task_work_add (tsk, cb, notify); +if (!ret) +wake_up_process (tsk); +return ret; +} +static void __io_req_task_cancel (struct io_kiocb *req,int error) {struct io_ring_ctx *ctx = req->ctx;
@@ -1732,18 +1748,19 @@ static void io_req_task_submit(struct callback_head *cb)static void io_req_task_queue (struct io_kiocb *req) { -struct task_struct *tsk = req->task;int ret;init_task_work (&req->task_work, io_req_task_submit); - ret =task_work_add (tsk, &req->task_work, true); + ret =io_req_task_work_add (req, &req->task_work,TWA_RESUME );if (unlikely (ret)) { +struct task_struct *tsk; +init_task_work (&req->task_work, io_req_task_cancel); tsk =io_wq_get_task (req->ctx->io_wq); -task_work_add (tsk, &req->task_work, true); +task_work_add (tsk, &req->task_work,0 ); +wake_up_process (tsk); } -wake_up_process (tsk); }static void io_queue_next (struct io_kiocb *req)
@@ -2197,19 +2214,15 @@ static void io_rw_resubmit(struct callback_head *cb)static bool io_rw_reissue (struct io_kiocb *req,long res) {#ifdef CONFIG_BLOCK -struct task_struct *tsk;int ret;if ((res != -EAGAIN && res != -EOPNOTSUPP ) ||io_wq_current_is_worker ())return false; - tsk = req->task;init_task_work (&req->task_work, io_rw_resubmit); - ret =task_work_add (tsk, &req->task_work, true); -if (!ret) { -wake_up_process (tsk); + ret =io_req_task_work_add (req, &req->task_work,TWA_RESUME ); +if (!ret)return true; - }#endif return false; }
@@ -2909,7 +2922,6 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,struct io_kiocb *req = wait->private;struct io_async_rw *rw = &req->io->rw;struct wait_page_key *key = arg; -struct task_struct *tsk;int ret; wpq = container_of(wait, struct wait_page_queue, wait);
@@ -2923,15 +2935,16 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,init_task_work (&rw->task_work, io_async_buf_retry);/* submit ref gets dropped, acquire a new one */ refcount_inc (&req->refs); - tsk = req->task; - ret =task_work_add (tsk, &rw->task_work, true); + ret =io_req_task_work_add (req, &rw->task_work,TWA_RESUME );if (unlikely (ret)) { +struct task_struct *tsk; +/* queue just for cancelation */ init_task_work (&rw->task_work, io_async_buf_cancel); tsk =io_wq_get_task (req->ctx->io_wq); -task_work_add (tsk, &rw->task_work, true); +task_work_add (tsk, &rw->task_work,0 ); +wake_up_process (tsk); } -wake_up_process (tsk);return 1 ; }
@@ -4424,25 +4437,9 @@ struct io_poll_table {int error; }; -static int io_req_task_work_add (struct io_kiocb *req,struct callback_head *cb, -int notify) -{ -struct task_struct *tsk = req->task; -int ret; - -if (req->ctx->flags &IORING_SETUP_SQPOLL ) - notify =0 ; - - ret =task_work_add (tsk, cb, notify); -if (!ret) -wake_up_process (tsk); -return ret; -} -static int __io_async_wake (struct io_kiocb *req,struct io_poll_iocb *poll,__poll_t mask,task_work_func_t func) { -struct task_struct *tsk;int ret;/* for instances that support it check for an event match first: */
@@ -4453,7 +4450,6 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,list_del_init (&poll->wait.entry); - tsk = req->task; req->result = mask;init_task_work (&req->task_work, func);/*
@@ -4464,6 +4460,8 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,*/ ret =io_req_task_work_add (req, &req->task_work,TWA_SIGNAL );if (unlikely (ret)) { +struct task_struct *tsk; +WRITE_ONCE (poll->canceled, true); tsk =io_wq_get_task (req->ctx->io_wq);task_work_add (tsk, &req->task_work,0 );
Signature · 1 line
2.27.0