Skip to content

Commit

Permalink
test/timeout: add timeout lock -> eventfd signal lock ordering
Browse files Browse the repository at this point in the history
A recent kernel commit changed the timeout lock to be a raw spinlock,
but this can conflict with eventfd signaling which uses a regular lock.
This is usually fine as they are the same lock type, however on kernels
with PREEMPT_RT enabled, a raw spinlock is a classic spinlock, and the
normal spinlock is a sleeping lock. Nesting the sleeping lock inside
the raw spinlock will throw a warning.

Based on the syzbot test case.

Link: https://lore.kernel.org/io-uring/[email protected]/
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Dec 30, 2024
1 parent e22d2fa commit 423897a
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions test/timeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/eventfd.h>

#include "helpers.h"
#include "liburing.h"
Expand Down Expand Up @@ -1559,6 +1560,44 @@ static int test_timeout_multishot_overflow(struct io_uring *ring)
return 1;
}

static int test_eventfd(void)
{
struct __kernel_timespec ts = { .tv_sec = 5, };
struct io_uring_sqe *sqe;
struct io_uring ring;
int ev, ret;

ret = io_uring_queue_init(2, &ring, IORING_SETUP_DEFER_TASKRUN |
IORING_SETUP_SINGLE_ISSUER);
if (ret == -EINVAL) {
return T_EXIT_SKIP;
} else if (ret < 0) {
fprintf(stderr, "queue_init: %d\n", ret);
return T_EXIT_FAIL;
}

ev = eventfd(0, 0);
if (ev < 0) {
perror("eventfd");
return T_EXIT_SKIP;
}

ret = io_uring_register_eventfd(&ring, ev);
if (ret) {
fprintf(stderr, "register_eventfd: %d\n", ret);
return ret;
}

sqe = io_uring_get_sqe(&ring);
io_uring_prep_timeout(sqe, &ts, 100, 0);
sqe->user_data = 0x1234;
sqe->flags |= IOSQE_ASYNC;
io_uring_submit(&ring);

io_uring_queue_exit(&ring);
close(ev);
return T_EXIT_PASS;
}

int main(int argc, char *argv[])
{
Expand Down Expand Up @@ -1762,6 +1801,12 @@ int main(int argc, char *argv[])
}
}

ret = test_eventfd();
if (ret == T_EXIT_FAIL) {
fprintf(stderr, "test_eventfd failed\n");
return ret;
}

/*
* this test must go last, it kills the ring
*/
Expand Down

0 comments on commit 423897a

Please sign in to comment.