From: Jackie Liu <liuyun01@xxxxxxxxxx> Now we are dealing with link-drain in a much simpler way, so the test program is updated as well. Also fixed a bug that did not close fd when an error occurred. and some dead code has been modified, like commit e1420b89c do. Signed-off-by: Jackie Liu <liuyun01@xxxxxxxxxx> --- resend that patch, because reject by mail-list. test/link_drain.c | 129 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 16 deletions(-) diff --git a/test/link_drain.c b/test/link_drain.c index c192a5d..ebc000b 100644 --- a/test/link_drain.c +++ b/test/link_drain.c @@ -11,13 +11,7 @@ #include "liburing.h" -char expect[3][5] = { - { 0, 1, 2, 3, 4 }, - { 0, 1, 2, 4, 3 }, - { 0, 1, 4, 2, 3 } -}; - -static int test_link_drain(struct io_uring *ring) +static int test_link_drain_one(struct io_uring *ring) { struct io_uring_cqe *cqe; struct io_uring_sqe *sqe[5]; @@ -25,6 +19,7 @@ static int test_link_drain(struct io_uring *ring) int i, fd, ret; off_t off = 0; char data[5] = {0}; + char expect[5] = {0, 1, 2, 3, 4}; fd = open("testfile", O_WRONLY | O_CREAT, 0644); if (fd < 0) { @@ -67,10 +62,10 @@ static int test_link_drain(struct io_uring *ring) ret = io_uring_submit(ring); if (ret < 5) { - printf("Submitted only %d\n", ret); + printf("sqe submit failed\n"); goto err; } else if (ret < 0) { - printf("sqe submit failed\n"); + printf("Submitted only %d\n", ret); goto err; } @@ -85,21 +80,121 @@ static int test_link_drain(struct io_uring *ring) io_uring_cqe_seen(ring, cqe); } + if (memcmp(data, expect, 5) != 0) + goto err; + free(iovecs.iov_base); close(fd); + unlink("testfile"); + return 0; +err: + free(iovecs.iov_base); + close(fd); + unlink("testfile"); + return 1; +} + +int test_link_drain_multi(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + struct io_uring_sqe *sqe[9]; + struct iovec iovecs; + int i, fd, ret; + off_t off = 0; + char data[9] = {0}; + char expect[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; - for (i = 0; i < 3; i++) { - if (memcmp(data, expect[i], 5) == 0) - break; + fd = open("testfile", O_WRONLY | O_CREAT, 0644); + if (fd < 0) { + perror("open"); + return 1; + } + + iovecs.iov_base = malloc(4096); + iovecs.iov_len = 4096; + + for (i = 0; i < 9; i++) { + sqe[i] = io_uring_get_sqe(ring); + if (!sqe[i]) { + printf("get sqe failed\n"); + goto err; + } } - if (i == 3) + + /* normal heavy io */ + io_uring_prep_writev(sqe[0], fd, &iovecs, 1, off); + sqe[0]->user_data = 0; + + /* link1 io head */ + io_uring_prep_nop(sqe[1]); + sqe[1]->flags |= IOSQE_IO_LINK; + sqe[1]->user_data = 1; + + /* link1 drain io */ + io_uring_prep_nop(sqe[2]); + sqe[2]->flags |= (IOSQE_IO_LINK | IOSQE_IO_DRAIN); + sqe[2]->user_data = 2; + + /* link1 io end*/ + io_uring_prep_nop(sqe[3]); + sqe[3]->user_data = 3; + + /* link2 io head */ + io_uring_prep_nop(sqe[4]); + sqe[4]->flags |= IOSQE_IO_LINK; + sqe[4]->user_data = 4; + + /* link2 io */ + io_uring_prep_nop(sqe[5]); + sqe[5]->flags |= IOSQE_IO_LINK; + sqe[5]->user_data = 5; + + /* link2 drain io */ + io_uring_prep_writev(sqe[6], fd, &iovecs, 1, off); + sqe[6]->flags |= (IOSQE_IO_LINK | IOSQE_IO_DRAIN); + sqe[6]->user_data = 6; + + /* link2 io end */ + io_uring_prep_nop(sqe[7]); + sqe[7]->user_data = 7; + + /* normal io */ + io_uring_prep_nop(sqe[8]); + sqe[8]->user_data = 8; + + ret = io_uring_submit(ring); + if (ret < 0) { + printf("sqe submit failed\n"); + goto err; + } else if (ret < 9) { + printf("Submitted only %d\n", ret); + goto err; + } + + for (i = 0; i < 9; i++) { + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + printf("child: wait completion %d\n", ret); + goto err; + } + + data[i] = cqe->user_data; + io_uring_cqe_seen(ring, cqe); + } + + if (memcmp(data, expect, 9) != 0) goto err; + free(iovecs.iov_base); + close(fd); unlink("testfile"); return 0; err: + free(iovecs.iov_base); + close(fd); unlink("testfile"); return 1; + } int main(int argc, char *argv[]) @@ -107,14 +202,16 @@ int main(int argc, char *argv[]) struct io_uring ring; int i, ret; - ret = io_uring_queue_init(5, &ring, 0); + ret = io_uring_queue_init(100, &ring, 0); if (ret) { printf("ring setup failed\n"); return 1; } - for (i = 0; i < 1000; i++) - ret |= test_link_drain(&ring); + for (i = 0; i < 1000; i++) { + ret |= test_link_drain_one(&ring); + ret |= test_link_drain_multi(&ring); + } if (ret) return ret; -- 2.17.1