Waiting for epoll and io_uring simultaneously
Asked Answered
T

1

6

I'm migrating my project to io_uring for better performance. However, some part of the system depends on epoll being event system and not movable to io_uring (ex: database drivers, they write to socket internally and I get notification read/write events, never seeing what's written to the raw sockets). Forcing me to use epoll and io_uring together. Creating two threads, one for epoll and another for io_uring is not an option for various reasons.

My plan was to poll io_uring after epoll in my event loop, Like the following

while(keep_running) {
    epoll_wait();
    io_uring_peek_batch_cqe();

    ... // handle events
}

This turns out not viable. It's likely that there's no ongoing database activity, causing epoll_wait block until timeout, thus all operations on io_uring waiting for the same timeout. Nor inverting the order and call io_uring_wait_cqe any better. It's possible that there's DB traffic but nothing submitted to io_uring. Causing epoll to wait for io_uring timeout.

So far I've considered reducing the timeout. But it's not an elegant solution. It increases CPU usage and adds unnecessary latency. Is there a way to wait for epoll and io_uring at the same time? i.e. Some function that unblocks as soon as either epoll or io_uring has something to process.

Tati answered 27/11, 2021 at 7:22 Comment(0)
R
7

io_uring can monitor file descriptors for readiness using IORING_OP_POLL_ADD. Epoll fd becomes read-ready once there are some events pending. One solution is to use io_uring as the primary event notification facility. Epoll fd should be monitored by io_uring.

One could do it the other way around - use epoll as the primary event notification facility. Configure io_uring to post readiness notifications using eventfd and add that to epoll: https://unixism.net/loti/tutorial/register_eventfd.html

Rohn answered 27/12, 2021 at 18:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.