Add one bpf operation & related framework and prepare for extending io_uring with bpf. Signed-off-by: Ming Lei --- include/uapi/linux/io_uring.h | 1 + init/Kconfig | 7 +++++++ io_uring/Makefile | 1 + io_uring/bpf_op.c | 26 ++++++++++++++++++++++++++ io_uring/bpf_op.h | 15 +++++++++++++++ io_uring/opdef.c | 16 ++++++++++++++++ 6 files changed, 66 insertions(+) create mode 100644 io_uring/bpf_op.c create mode 100644 io_uring/bpf_op.h diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index b5b23c0d5283..30406cfb2e21 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -303,6 +303,7 @@ enum io_uring_op { IORING_OP_PIPE, IORING_OP_NOP128, IORING_OP_URING_CMD128, + IORING_OP_BPF, /* this goes last, obviously */ IORING_OP_LAST, diff --git a/init/Kconfig b/init/Kconfig index fa79feb8fe57..b2f2a5473538 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1868,6 +1868,13 @@ config IO_URING applications to submit and complete IO through submission and completion rings that are shared between the kernel and application. +config IO_URING_BPF_OP + bool "Enable IO uring bpf extension" if EXPERT + depends on IO_URING && BPF + help + This option enables bpf extension for the io_uring interface, so + application can define its own io_uring operation by bpf program. + config GCOV_PROFILE_URING bool "Enable GCOV profiling on the io_uring subsystem" depends on IO_URING && GCOV_KERNEL diff --git a/io_uring/Makefile b/io_uring/Makefile index bc4e4a3fa0a5..b2db2b334cee 100644 --- a/io_uring/Makefile +++ b/io_uring/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_NET_RX_BUSY_POLL) += napi.o obj-$(CONFIG_NET) += net.o cmd_net.o obj-$(CONFIG_PROC_FS) += fdinfo.o obj-$(CONFIG_IO_URING_MOCK_FILE) += mock_file.o +obj-$(CONFIG_IO_URING_BPF_OP) += bpf_op.o diff --git a/io_uring/bpf_op.c b/io_uring/bpf_op.c new file mode 100644 index 000000000000..2ab6f93bbad8 --- /dev/null +++ b/io_uring/bpf_op.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Red Hat */ + +#include +#include +#include +#include "io_uring.h" +#include "bpf_op.h" + +int io_uring_bpf_issue(struct io_kiocb *req, unsigned int issue_flags) +{ + return -EOPNOTSUPP; +} + +int io_uring_bpf_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) +{ + return -EOPNOTSUPP; +} + +void io_uring_bpf_fail(struct io_kiocb *req) +{ +} + +void io_uring_bpf_cleanup(struct io_kiocb *req) +{ +} diff --git a/io_uring/bpf_op.h b/io_uring/bpf_op.h new file mode 100644 index 000000000000..7b61612c28c4 --- /dev/null +++ b/io_uring/bpf_op.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef IOU_BPF_OP_H +#define IOU_BPF_OP_H + +struct io_kiocb; +struct io_uring_sqe; + +#ifdef CONFIG_IO_URING_BPF_OP +int io_uring_bpf_issue(struct io_kiocb *req, unsigned int issue_flags); +int io_uring_bpf_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); +void io_uring_bpf_fail(struct io_kiocb *req); +void io_uring_bpf_cleanup(struct io_kiocb *req); +#endif + +#endif diff --git a/io_uring/opdef.c b/io_uring/opdef.c index df52d760240e..289107f3c00a 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -38,6 +38,7 @@ #include "futex.h" #include "truncate.h" #include "zcrx.h" +#include "bpf_op.h" static int io_no_issue(struct io_kiocb *req, unsigned int issue_flags) { @@ -593,6 +594,14 @@ const struct io_issue_def io_issue_defs[] = { .prep = io_uring_cmd_prep, .issue = io_uring_cmd, }, + [IORING_OP_BPF] = { +#if defined(CONFIG_IO_URING_BPF_OP) + .prep = io_uring_bpf_prep, + .issue = io_uring_bpf_issue, +#else + .prep = io_eopnotsupp_prep, +#endif + }, }; const struct io_cold_def io_cold_defs[] = { @@ -851,6 +860,13 @@ const struct io_cold_def io_cold_defs[] = { .sqe_copy = io_uring_cmd_sqe_copy, .cleanup = io_uring_cmd_cleanup, }, + [IORING_OP_BPF] = { + .name = "BPF", +#if defined(CONFIG_IO_URING_BPF_OP) + .cleanup = io_uring_bpf_cleanup, + .fail = io_uring_bpf_fail, +#endif + }, }; const char *io_uring_get_opcode(u8 opcode) -- 2.47.0