diff --git a/man/io_uring_setup.2 b/man/io_uring_setup.2 index 2f877831e..f226db04e 100644 --- a/man/io_uring_setup.2 +++ b/man/io_uring_setup.2 @@ -78,7 +78,15 @@ in question. For NVMe devices, the nvme driver must be loaded with the parameter set to the desired number of polling queues. The polling queues will be shared appropriately between the CPUs in the system, if the number is less than the number of online CPU threads. - +.TP +.B IORING_SETUP_HYBRID_IOPOLL +This flag must be used with +.B IORING_SETUP_IOPOLL +flag. Hybrid io polling is a feature based on iopoll, it differs from strict +polling in that it will delay a bit before doing completion side polling, to +avoid wasting too much CPU resources. Like +.B IOPOLL +, it requires that devices support polling. .TP .B IORING_SETUP_SQPOLL When this flag is specified, a kernel thread is created to perform diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h index 20bc570e3..d16364c2a 100644 --- a/src/include/liburing/io_uring.h +++ b/src/include/liburing/io_uring.h @@ -200,6 +200,9 @@ enum io_uring_sqe_flags_bit { */ #define IORING_SETUP_NO_SQARRAY (1U << 16) +/* Use hybrid poll in iopoll process */ +#define IORING_SETUP_HYBRID_IOPOLL (1U << 17) + enum io_uring_op { IORING_OP_NOP, IORING_OP_READV, diff --git a/test/io_uring_passthrough.c b/test/io_uring_passthrough.c index f18a1862c..bea4f39f4 100644 --- a/test/io_uring_passthrough.c +++ b/test/io_uring_passthrough.c @@ -254,7 +254,7 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read, } static int test_io(const char *file, int tc, int read, int sqthread, - int fixed, int nonvec) + int fixed, int nonvec, int hybrid) { struct io_uring ring; int ret, ring_flags = 0; @@ -265,6 +265,9 @@ static int test_io(const char *file, int tc, int read, int sqthread, if (sqthread) ring_flags |= IORING_SETUP_SQPOLL; + if (hybrid) + ring_flags |= IORING_SETUP_IOPOLL | IORING_SETUP_HYBRID_IOPOLL; + ret = t_create_ring(64, &ring, ring_flags); if (ret == T_SETUP_SKIP) return 0; @@ -449,18 +452,19 @@ int main(int argc, char *argv[]) vecs = t_create_buffers(BUFFERS, BS); - for (i = 0; i < 16; i++) { + for (i = 0; i < 32; i++) { int read = (i & 1) != 0; int sqthread = (i & 2) != 0; int fixed = (i & 4) != 0; int nonvec = (i & 8) != 0; + int hybrid = (i & 16) != 0; - ret = test_io(fname, i, read, sqthread, fixed, nonvec); + ret = test_io(fname, i, read, sqthread, fixed, nonvec, hybrid); if (no_pt) break; if (ret) { - fprintf(stderr, "test_io failed %d/%d/%d/%d\n", - read, sqthread, fixed, nonvec); + fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n", + read, sqthread, fixed, nonvec, hybrid); goto err; } } diff --git a/test/iopoll.c b/test/iopoll.c index 2e0f7ea2b..5ff26a4be 100644 --- a/test/iopoll.c +++ b/test/iopoll.c @@ -351,7 +351,7 @@ static int test_io_uring_submit_enters(const char *file) } static int test_io(const char *file, int write, int sqthread, int fixed, - int buf_select, int defer) + int hybrid, int buf_select, int defer) { struct io_uring ring; int ret, ring_flags = IORING_SETUP_IOPOLL; @@ -363,6 +363,9 @@ static int test_io(const char *file, int write, int sqthread, int fixed, ring_flags |= IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN; + if (hybrid) + ring_flags |= IORING_SETUP_HYBRID_IOPOLL; + ret = t_create_ring(64, &ring, ring_flags); if (ret == T_SETUP_SKIP) return 0; @@ -418,22 +421,23 @@ int main(int argc, char *argv[]) vecs = t_create_buffers(BUFFERS, BS); - nr = 32; + nr = 64; if (no_buf_select) - nr = 8; - else if (!t_probe_defer_taskrun()) nr = 16; + else if (!t_probe_defer_taskrun()) + nr = 32; for (i = 0; i < nr; i++) { int write = (i & 1) != 0; int sqthread = (i & 2) != 0; int fixed = (i & 4) != 0; - int buf_select = (i & 8) != 0; - int defer = (i & 16) != 0; + int hybrid = (i & 8) != 0; + int buf_select = (i & 16) != 0; + int defer = (i & 32) != 0; - ret = test_io(fname, write, sqthread, fixed, buf_select, defer); + ret = test_io(fname, write, sqthread, fixed, hybrid, buf_select, defer); if (ret) { - fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n", - write, sqthread, fixed, buf_select, defer); + fprintf(stderr, "test_io failed %d/%d/%d/%d/%d/%d\n", + write, sqthread, fixed, hybrid, buf_select, defer); goto err; } if (no_iopoll)