Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/cmd: allow multishot polled commands

Some commands like timestamping in the next patch can make use of
multishot polling, i.e. REQ_F_APOLL_MULTISHOT. Add support for that,
which is condensed in a single helper called io_cmd_poll_multishot().

The user who wants to continue with a request in a multishot mode must
call the function, and only if it returns 0 the user is free to proceed.
Apart from normal terminal errors, it can also end up with -EIOCBQUEUED,
in which case the user must forward it to the core io_uring. It's
forbidden to use task work while the request is executing in a multishot
mode.

The API is not foolproof, hence it's not exported to modules nor exposed
in public headers.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/bcf97c31659662c72b69fc8fcdf2a88cfc16e430.1750065793.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Pavel Begunkov and committed by
Jens Axboe
b9557549 16215188

+26
+23
io_uring/uring_cmd.c
··· 12 12 #include "alloc_cache.h" 13 13 #include "rsrc.h" 14 14 #include "uring_cmd.h" 15 + #include "poll.h" 15 16 16 17 void io_cmd_cache_free(const void *entry) 17 18 { ··· 137 136 { 138 137 struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); 139 138 139 + if (WARN_ON_ONCE(req->flags & REQ_F_APOLL_MULTISHOT)) 140 + return; 141 + 140 142 ioucmd->task_work_cb = task_work_cb; 141 143 req->io_task_work.func = io_uring_cmd_work; 142 144 __io_req_task_work_add(req, flags); ··· 161 157 unsigned issue_flags) 162 158 { 163 159 struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); 160 + 161 + if (WARN_ON_ONCE(req->flags & REQ_F_APOLL_MULTISHOT)) 162 + return; 164 163 165 164 io_uring_cmd_del_cancelable(ioucmd, issue_flags); 166 165 ··· 311 304 struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); 312 305 313 306 io_req_queue_iowq(req); 307 + } 308 + 309 + int io_cmd_poll_multishot(struct io_uring_cmd *cmd, 310 + unsigned int issue_flags, __poll_t mask) 311 + { 312 + struct io_kiocb *req = cmd_to_io_kiocb(cmd); 313 + int ret; 314 + 315 + if (likely(req->flags & REQ_F_APOLL_MULTISHOT)) 316 + return 0; 317 + 318 + req->flags |= REQ_F_APOLL_MULTISHOT; 319 + mask &= ~EPOLLONESHOT; 320 + 321 + ret = io_arm_apoll(req, issue_flags, mask); 322 + return ret == IO_APOLL_OK ? -EIOCBQUEUED : -ECANCELED; 314 323 }
+3
io_uring/uring_cmd.h
··· 18 18 struct io_uring_task *tctx, bool cancel_all); 19 19 20 20 void io_cmd_cache_free(const void *entry); 21 + 22 + int io_cmd_poll_multishot(struct io_uring_cmd *cmd, 23 + unsigned int issue_flags, __poll_t mask);