Skip to content
Snippets Groups Projects
Commit 8ae1f189 authored by Florian Fischer's avatar Florian Fischer
Browse files

IoContext: register the worker io_uring fds on Linux >= 5.18

Linux 5.18 introduces IORING_REGISTER_RING_FDS with
e7a6c00dc77aedf27a601738ea509f1caea6d673.

Registering the io_uring's fd prevents having to look it up for each
io_uring_enter call reducing contention on the process file table.
Jens Axboe reports good results in his fio based benchmarks and
I see no reason for EMPER to not register the io_uring fds, especially
because we never pass or share rings.

Do not register the global io_uring since it is shared in the SINGLE_URING
case or it is passed by the main thread to the completer thread breaking the
assumption liburing has about the registered io_uring fd.
parent 171ae9d4
No related branches found
No related tags found
1 merge request!364incorporate new io_uring features
......@@ -510,6 +510,7 @@ template auto IoContext::reapCompletionsLocked<CallerEnvironment::ANYWHERE,
IoContext::IoContext(Runtime &runtime, size_t uring_entries, unsigned unboundedIowMax)
: runtime(runtime) {
const bool isWorkerIo = runtime.globalIo != nullptr;
struct io_uring_params params;
memset(&params, 0, sizeof(params));
......@@ -528,9 +529,8 @@ IoContext::IoContext(Runtime &runtime, size_t uring_entries, unsigned unboundedI
// We use a single poller -> attach to the global io_uring
if constexpr (emper::IO_SQ_POLLER == IoSqPoller::one) {
auto *gio = runtime.globalIo;
if (gio) {
pollerRingFd = gio->ring.ring_fd;
if (isWorkerIo) {
pollerRingFd = runtime.globalIo->ring.ring_fd;
}
// One sq poller thread per numa node
// The CPU with the lowest id in a node is responsible to create a poller.
......@@ -593,6 +593,25 @@ IoContext::IoContext(Runtime &runtime, size_t uring_entries, unsigned unboundedI
}
}
// Detect IORING_REGISTER_RING_FDS support
// Liburing hides the details of calling io_uring_enter with the index of the
// registered io_uring fd instead of the fd itself.
// We only have to register our io_uring's fd.
// Added with Linux: e7a6c00dc77aedf27a601738ea509f1caea6d673
// Do not register the ring fd on the global io_uring because it is created on
// the main thread and afterwards used on the completer thread.
// Registering on the main thread breaks the assumption done in
// liburing that the registered offset is valid on the using thread.
// Registering the global io_uring is also not possible when using SINGLE_URING.
if (EMPER_LINUX_GE("5.18") && isWorkerIo) {
ret = io_uring_register_ring_fd(&ring);
if (unlikely(ret < 0)) {
errno = -ret;
DIE_MSG_ERRNO("registering our io_uring fd " << ring.ring_fd << " failed");
}
}
// Limit the number of unbounded iow thread created by this io_uring
// By default the number of unbounded iow worker threads is RLIMIT_NPROC
// which may be excessive.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment