I'm sorry for the mistakes I'm probably gonna make in this issue in advance, as I'm currently learning C and I'm still very new to Linux programming, in general.
When trying to use the io_uring_submit_and_wait_reg() function, given a properly setup timer and zero submitted SQEs, everything works fine. But as soon as I try to submit SQEs, I get a SIGSEGV error, specifically when not enough (or zero) SQEs have been completed before the deadline, triggering the timeout. It took me a good while to figure out what's wrong, but after stepping through in the debugger, I've found that a particular branch in the internal _io_uring_get_cqe() function tries to access memory that is... not memory at all. I'm not sure as to the specifics of this issue, but I was able to find that the culprit was this line:
// src/queue.c:106
if (looped && data->has_ts) {
struct io_uring_getevents_arg *arg = data->arg;
if (!cqe && arg->ts && !err) // <== arg->ts is illegal here
err = -ETIME;
break;
}
After some further digging up and down the call stack, I've found that the data->arg member field in this particular case is set not to an address, but to an offset (i.e. regular non-address integer):
// src/queue.c:338
int io_uring_submit_and_wait_reg(struct io_uring *ring,
struct io_uring_cqe **cqe_ptr,
unsigned wait_nr, int reg_index)
{
unsigned long offset = reg_index * sizeof(struct io_uring_reg_wait);
struct get_data data = {
.submit = __io_uring_flush_sq(ring),
.wait_nr = wait_nr,
.get_flags = IORING_ENTER_EXT_ARG | IORING_ENTER_EXT_ARG_REG,
.sz = sizeof(struct io_uring_reg_wait),
.has_ts = true,
.arg = (void *) (uintptr_t) offset, // <== Here's the offset being casted to an address
};
if (!(ring->features & IORING_FEAT_EXT_ARG))
return -EINVAL;
return _io_uring_get_cqe(ring, cqe_ptr, &data);
}
I was able to "fix" this by just removing the arg->ts check, but this most assuredly wrong:
// src/queue.c:106
if (looped && data->has_ts) {
struct io_uring_getevents_arg *arg = data->arg;
if (!cqe && !err) // <== arg->ts is removed
err = -ETIME;
break;
}
Is it indeed a bug, or is my liburing-jutsu lacking?
I'm sorry for the mistakes I'm probably gonna make in this issue in advance, as I'm currently learning C and I'm still very new to Linux programming, in general.
When trying to use the
io_uring_submit_and_wait_reg()function, given a properly setup timer and zero submitted SQEs, everything works fine. But as soon as I try to submit SQEs, I get a SIGSEGV error, specifically when not enough (or zero) SQEs have been completed before the deadline, triggering the timeout. It took me a good while to figure out what's wrong, but after stepping through in the debugger, I've found that a particular branch in the internal_io_uring_get_cqe()function tries to access memory that is... not memory at all. I'm not sure as to the specifics of this issue, but I was able to find that the culprit was this line:After some further digging up and down the call stack, I've found that the
data->argmember field in this particular case is set not to an address, but to an offset (i.e. regular non-address integer):I was able to "fix" this by just removing the
arg->tscheck, but this most assuredly wrong:Is it indeed a bug, or is my liburing-jutsu lacking?