[RFC 2/4] io_uring: frame out futex op

From: Pavel Begunkov
Date: Tue Jun 01 2021 - 10:59:05 EST


Add userspace futex request definitions and draft some internal
functions.

Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx>
---
fs/io_uring.c | 23 +++++++++++++++++++++++
include/uapi/linux/io_uring.h | 9 +++++++++
2 files changed, 32 insertions(+)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index fc9325472e8d..2c6b14a3a4f6 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -77,6 +77,7 @@
#include <linux/splice.h>
#include <linux/task_work.h>
#include <linux/pagemap.h>
+#include <linux/futex.h>
#include <linux/io_uring.h>

#define CREATE_TRACE_POINTS
@@ -665,6 +666,10 @@ struct io_unlink {
struct filename *filename;
};

+struct io_futex {
+ struct file *file;
+};
+
struct io_completion {
struct file *file;
struct list_head list;
@@ -809,6 +814,7 @@ struct io_kiocb {
struct io_shutdown shutdown;
struct io_rename rename;
struct io_unlink unlink;
+ struct io_futex futex;
/* use only after cleaning per-op data, see io_clean_op() */
struct io_completion compl;
};
@@ -1021,6 +1027,7 @@ static const struct io_op_def io_op_defs[] = {
},
[IORING_OP_RENAMEAT] = {},
[IORING_OP_UNLINKAT] = {},
+ [IORING_OP_FUTEX] = {},
};

static bool io_disarm_next(struct io_kiocb *req);
@@ -5865,6 +5872,16 @@ static int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
return 0;
}

+static int io_futex_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ return -EINVAL;
+}
+
+static int io_futex(struct io_kiocb *req, unsigned int issue_flags)
+{
+ return -EINVAL;
+}
+
static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
switch (req->opcode) {
@@ -5936,6 +5953,8 @@ static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return io_renameat_prep(req, sqe);
case IORING_OP_UNLINKAT:
return io_unlinkat_prep(req, sqe);
+ case IORING_OP_FUTEX:
+ return io_futex_prep(req, sqe);
}

printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
@@ -6203,6 +6222,9 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
case IORING_OP_UNLINKAT:
ret = io_unlinkat(req, issue_flags);
break;
+ case IORING_OP_FUTEX:
+ ret = io_futex(req, issue_flags);
+ break;
default:
ret = -EINVAL;
break;
@@ -10158,6 +10180,7 @@ static int __init io_uring_init(void)
BUILD_BUG_SQE_ELEM(28, __u32, statx_flags);
BUILD_BUG_SQE_ELEM(28, __u32, fadvise_advice);
BUILD_BUG_SQE_ELEM(28, __u32, splice_flags);
+ BUILD_BUG_SQE_ELEM(28, __u32, futex_flags);
BUILD_BUG_SQE_ELEM(32, __u64, user_data);
BUILD_BUG_SQE_ELEM(40, __u16, buf_index);
BUILD_BUG_SQE_ELEM(42, __u16, personality);
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index e1ae46683301..6a1af5bb2ddf 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -44,6 +44,7 @@ struct io_uring_sqe {
__u32 splice_flags;
__u32 rename_flags;
__u32 unlink_flags;
+ __u32 futex_flags;
};
__u64 user_data; /* data to be passed back at completion time */
union {
@@ -137,6 +138,7 @@ enum {
IORING_OP_SHUTDOWN,
IORING_OP_RENAMEAT,
IORING_OP_UNLINKAT,
+ IORING_OP_FUTEX,

/* this goes last, obviously */
IORING_OP_LAST,
@@ -174,6 +176,13 @@ enum {
#define IORING_POLL_UPDATE_EVENTS (1U << 1)
#define IORING_POLL_UPDATE_USER_DATA (1U << 2)

+enum {
+ IORING_FUTEX_WAKE_OP = 0,
+
+ IORING_FUTEX_LAST,
+};
+
+
/*
* IO completion data structure (Completion Queue Entry)
*/
--
2.31.1