Skip to content

Commit b6407e6

Browse files
axboeopsiff
authored andcommitted
io_uring: add IORING_OP_WAITID support
This adds support for an async version of waitid(2), in a fully async version. If an event isn't immediately available, wait for a callback to trigger a retry. The format of the sqe is as follows: sqe->len The 'which', the idtype being queried/waited for. sqe->fd The 'pid' (or id) being waited for. sqe->file_index The 'options' being set. sqe->addr2 A pointer to siginfo_t, if any, being filled in. buf_index, add3, and waitid_flags are reserved/unused for now. waitid_flags will be used for options for this request type. One interesting use case may be to add multi-shot support, so that the request stays armed and posts a notification every time a monitored process state change occurs. Note that this does not support rusage, on Arnd's recommendation. See the waitid(2) man page for details on the arguments. Signed-off-by: Jens Axboe <axboe@kernel.dk> (cherry picked from commit f31ecf6) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent daccbf3 commit b6407e6

8 files changed

Lines changed: 410 additions & 1 deletion

File tree

include/linux/io_uring_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ struct io_ring_ctx {
312312
struct list_head cq_overflow_list;
313313
struct io_hash_table cancel_table;
314314

315+
struct hlist_head waitid_list;
316+
315317
const struct cred *sq_creds; /* cred used for __io_sq_thread() */
316318
struct io_sq_data *sq_data; /* if using sq thread polling */
317319

include/uapi/linux/io_uring.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct io_uring_sqe {
6565
__u32 xattr_flags;
6666
__u32 msg_ring_flags;
6767
__u32 uring_cmd_flags;
68+
__u32 waitid_flags;
6869
};
6970
__u64 user_data; /* data to be passed back at completion time */
7071
/* pack this to avoid bogus arm OABI complaints */
@@ -241,6 +242,7 @@ enum io_uring_op {
241242
IORING_OP_SEND_ZC,
242243
IORING_OP_SENDMSG_ZC,
243244
IORING_OP_READ_MULTISHOT,
245+
IORING_OP_WAITID,
244246

245247
/* this goes last, obviously */
246248
IORING_OP_LAST,

io_uring/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ obj-$(CONFIG_IO_URING) += io_uring.o xattr.o nop.o fs.o splice.o \
77
openclose.o uring_cmd.o epoll.o \
88
statx.o net.o msg_ring.o timeout.o \
99
sqpoll.o fdinfo.o tctx.o poll.o \
10-
cancel.o kbuf.o rsrc.o rw.o opdef.o notif.o
10+
cancel.o kbuf.o rsrc.o rw.o opdef.o \
11+
notif.o waitid.o
1112
obj-$(CONFIG_IO_WQ) += io-wq.o

io_uring/cancel.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "tctx.h"
1616
#include "poll.h"
1717
#include "timeout.h"
18+
#include "waitid.h"
1819
#include "cancel.h"
1920

2021
struct io_cancel {
@@ -119,6 +120,10 @@ int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd,
119120
if (ret != -ENOENT)
120121
return ret;
121122

123+
ret = io_waitid_cancel(ctx, cd, issue_flags);
124+
if (ret != -ENOENT)
125+
return ret;
126+
122127
spin_lock(&ctx->completion_lock);
123128
if (!(cd->flags & IORING_ASYNC_CANCEL_FD))
124129
ret = io_timeout_cancel(ctx, cd);

io_uring/io_uring.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#include "cancel.h"
9292
#include "net.h"
9393
#include "notif.h"
94+
#include "waitid.h"
9495

9596
#include "timeout.h"
9697
#include "poll.h"
@@ -337,6 +338,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
337338
INIT_LIST_HEAD(&ctx->tctx_list);
338339
ctx->submit_state.free_list.next = NULL;
339340
INIT_WQ_LIST(&ctx->locked_free_list);
341+
INIT_HLIST_HEAD(&ctx->waitid_list);
340342
INIT_DELAYED_WORK(&ctx->fallback_work, io_fallback_req_func);
341343
INIT_WQ_LIST(&ctx->submit_state.compl_reqs);
342344
return ctx;
@@ -3416,6 +3418,7 @@ static __cold bool io_uring_try_cancel_requests(struct io_ring_ctx *ctx,
34163418
ret |= io_cancel_defer_files(ctx, task, cancel_all);
34173419
mutex_lock(&ctx->uring_lock);
34183420
ret |= io_poll_remove_all(ctx, task, cancel_all);
3421+
ret |= io_waitid_remove_all(ctx, task, cancel_all);
34193422
mutex_unlock(&ctx->uring_lock);
34203423
ret |= io_kill_timeouts(ctx, task, cancel_all);
34213424
if (task)

io_uring/opdef.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "poll.h"
3434
#include "cancel.h"
3535
#include "rw.h"
36+
#include "waitid.h"
3637

3738
static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags)
3839
{
@@ -440,6 +441,10 @@ const struct io_issue_def io_issue_defs[] = {
440441
.prep = io_read_mshot_prep,
441442
.issue = io_read_mshot,
442443
},
444+
[IORING_OP_WAITID] = {
445+
.prep = io_waitid_prep,
446+
.issue = io_waitid,
447+
},
443448
};
444449

445450
const struct io_cold_def io_cold_defs[] = {
@@ -662,6 +667,10 @@ const struct io_cold_def io_cold_defs[] = {
662667
[IORING_OP_READ_MULTISHOT] = {
663668
.name = "READ_MULTISHOT",
664669
},
670+
[IORING_OP_WAITID] = {
671+
.name = "WAITID",
672+
.async_size = sizeof(struct io_waitid_async),
673+
},
665674
};
666675

667676
const char *io_uring_get_opcode(u8 opcode)

0 commit comments

Comments
 (0)