ectly accessed by the userspace, however we can give BPF the ability to peek at them. It can be used to take a look at in-buffer app level headers to decide what to do with data next and issuing IO using it. - Smarter request ordering and linking. Request links are pretty limited and inflexible as they can't pass information from one request to another. With BPF we can peek at CQEs and memory and compile a subsequent request. - Feature semi-deprecation. It can be used to simplify handling of deprecated features by moving it into the callback out core io_uring. For example, it should be trivial to simulate IOSQE_IO_DRAIN. Another target could be request linking logic. - It can serve as a base for custom algorithms and fine tuning. Often, it'd be impractical to introduce a generic feature because it's either niche or requires a lot of configuration. For example, there is support min-wait, however BPF can help to further fine tune it by doing it in multiple steps with different number of CQEs / timeouts. Another feature people were asking about is allowing to over queue SQEs but make the kernel to maintain a given QD. - Smarter polling. Napi polling is performed only once per syscall and then it switches to waiting. We can do smarter and intermix polling with waiting using the hook. It might need more specialised kfuncs in the future, but the core functionality is implemented with just two simple functions. One returns region memory, which gives BPF access to CQ/SQ/etc. And the second is for submitting requests. It's also given a structure as an argument, which is used to pass waiting parameters. It showed good numbers in a test that sequentially executes N nop requests, where BPF was more than twice as fast than a 2-nop request link implementation. v10: - Remove internal wrapper struct around loop params for now - Improve nr_wait checks - Kill selftests v9: - Update mini_liburing - Clean up the nop test, bound the CQ processing by a separate constant and not CQ_ENTRIES. - Add helpers for sharing code b/w examples - Enable IORING_SETUP_SQ_REWIND - Use io_uring regions for parameter passing. v8: - Remove an check that is "always true" to silence smatch - Kill unused variables from selftests v7: - Fix CQ overflow flushing deadlock and add a selftest v6: - Fix inversed check on ejection leaving function pointer and add a selftest checking that. - Add spdx headers - Remove sqe reassignment in selftests v5: - Selftests are now using vmlinux.h - Checking for unexpected loop return codes - Remove KF_TRUSTED_ARGS (default) - Squashed one of the patches, it's more sensible this way v4: - Separated the event loop from the normal waiting path. - Improved the selftest. v3: - Removed most of utility kfuncs and replaced it with a single helper returning the ring memory. - Added KF_TRUSTED_ARGS to kfuncs - Fix ifdef guarding - Added a selftest - Adjusted the waiting loop - Reused the bpf lock section for task_work execution Pavel Begunkov (4): io_uring: introduce callback driven main loop io_uring/bpf-ops: implement loop_step with BPF struct_ops io_uring/bpf-ops: add kfunc helpers io_uring/bpf-ops: implement bpf ops registration include/linux/io_uring_types.h | 10 ++ io_uring/Kconfig | 5 + io_uring/Makefile | 3 +- io_uring/bpf-ops.c | 270 +++++++++++++++++++++++++++++++++ io_uring/bpf-ops.h | 28 ++++ io_uring/io_uring.c | 13 ++ io_uring/loop.c | 91 +++++++++++ io_uring/loop.h | 27 ++++ io_uring/wait.h | 1 + 9 files changed, 447 insertions(+), 1 deletion(-) create mode 100644 io_uring/bpf-ops.c create mode 100644 io_uring/bpf-ops.h create mode 100644 io_uring/loop.c create mode 100644 io_uring/loop.h -- 2.53.0[PATCH v10 0/4] BPF controlled io_uringPavel Begunkov undefinedio-uring@vger.kernel.org undefined undefined undefined undefined