Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

io_uring_prep_link_timeout return -EINVAL with valid timespec and flag #1210

Open
buracchi opened this issue Aug 26, 2024 · 5 comments
Open

Comments

@buracchi
Copy link

A snippet to reproduce this behavior was not trivial, I could try to provide it if required.

I have a single thread worker running jobs that can submit SQEs into the worker io_uring.

One such job execute something equivalent to

    sqe = io_uring_get_sqe(ring);
    io_uring_prep_recvmsg(sqe, fd, &msghdr, 0);
    io_uring_sqe_set_data(sqe, &listener_job);
    io_uring_sqe_set_flags(sqe, IOSQE_IO_LINK);
    sqe = io_uring_get_sqe(ring);
    io_uring_prep_link_timeout(sqe, &timeout_timespec, 0);
    io_uring_sqe_set_data(sqe, &timeout_job);
    io_uring_submit(ring);

If I try to overload with a high enough number of parallel requests the worker (having a load balancing mechanism to guarantee the CQ to not overflow) after a sufficient ammount of execution time a cqe resulting from the timeout with a ret value of -EINVAL is produced.

The timeout_timespec is a valid memory location from the submission to the completion of the timeout entry and it is set to a reasonable timeout value.

As a side note, I once encountered the undocumented ret value -ESUCCESS from the linked timeout while testing the -EINVAL issue but I couldn't reproduce it again.

Repository owner deleted a comment Aug 26, 2024
@axboe
Copy link
Owner

axboe commented Aug 26, 2024

-EINVAL or -EINTR? Subject was one thing, body another. And by -ESUCCESS, do you mean 0?

@buracchi buracchi changed the title io_uring_prep_link_timeout return -EINTR with valid timespec and flag io_uring_prep_link_timeout return -EINVAL with valid timespec and flag Aug 26, 2024
@buracchi
Copy link
Author

I didn't notice, my bad.
By -ESUCCESS I mean 0, yes.

@axboe
Copy link
Owner

axboe commented Aug 26, 2024

Just a guess, is your timespec struct going out of scope before you submit the IO? That could cause garbage in the tv_sec/tv_nsec, and that could cause an -EINVAL to be returned (eg if either of them ended up being less than 0).

@buracchi
Copy link
Author

At first I thought this was the problem too, so I replaced my previous compound literal expression

io_uring_prep_link_timeout(sqe, &(struct __kernel_timespec) {.tv_sec = 1}, 0);

with a named object whose lifetime persists for the entire duration of the program

io_uring_prep_link_timeout(sqe, &timeout_timespec, 0);

@axboe
Copy link
Owner

axboe commented Aug 26, 2024

There aren't really any post-prep side -EINVAL possible for a linked timeout, hence why I was suspecting it's something that the prep side doesn't like (like, for example, an invalid timeout).

timeout_flags will always get set, and that's 0 in your case, so won't cause anything.
That then really leaves the timeout itself being invalid (less than 0 for tv_sec/tv_nsec), or not having something to link against. The linked timeout must be submitted within the same submit call as the request being linked against. Is it possible that you ever submit in between those two preparations?

Outside of those few conditions, nothing else would cause -EINVAL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants