uringmachine 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/dependabot.yml +12 -0
- data/.github/workflows/test.yml +35 -0
- data/.gitignore +59 -0
- data/.gitmodules +3 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +11 -0
- data/Rakefile +39 -0
- data/TODO.md +0 -0
- data/examples/echo_server.rb +52 -0
- data/examples/event_loop.rb +69 -0
- data/examples/fibers.rb +105 -0
- data/examples/http_server.rb +56 -0
- data/examples/http_server_multishot.rb +57 -0
- data/examples/http_server_simpler.rb +34 -0
- data/ext/um/extconf.rb +71 -0
- data/ext/um/iou.h +101 -0
- data/ext/um/op_ctx.c +138 -0
- data/ext/um/ring.c +755 -0
- data/ext/um/um.c +267 -0
- data/ext/um/um.h +97 -0
- data/ext/um/um_class.c +175 -0
- data/ext/um/um_ext.c +11 -0
- data/ext/um/um_op.c +87 -0
- data/ext/um/um_utils.c +23 -0
- data/lib/uringmachine/version.rb +3 -0
- data/lib/uringmachine.rb +8 -0
- data/test/helper.rb +70 -0
- data/test/test_iou.rb +876 -0
- data/test/test_um.rb +168 -0
- data/uringmachine.gemspec +27 -0
- data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
- data/vendor/liburing/.github/pull_request_template.md +86 -0
- data/vendor/liburing/.github/workflows/build.yml +137 -0
- data/vendor/liburing/.github/workflows/codespell.yml +25 -0
- data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
- data/vendor/liburing/.gitignore +41 -0
- data/vendor/liburing/CHANGELOG +111 -0
- data/vendor/liburing/CITATION.cff +11 -0
- data/vendor/liburing/COPYING +502 -0
- data/vendor/liburing/COPYING.GPL +339 -0
- data/vendor/liburing/LICENSE +20 -0
- data/vendor/liburing/Makefile +96 -0
- data/vendor/liburing/Makefile.common +7 -0
- data/vendor/liburing/Makefile.quiet +11 -0
- data/vendor/liburing/README +106 -0
- data/vendor/liburing/SECURITY.md +6 -0
- data/vendor/liburing/configure +624 -0
- data/vendor/liburing/debian/README.Debian +7 -0
- data/vendor/liburing/debian/changelog +38 -0
- data/vendor/liburing/debian/control +39 -0
- data/vendor/liburing/debian/copyright +49 -0
- data/vendor/liburing/debian/liburing-dev.install +4 -0
- data/vendor/liburing/debian/liburing-dev.manpages +5 -0
- data/vendor/liburing/debian/liburing2.install +1 -0
- data/vendor/liburing/debian/liburing2.symbols +56 -0
- data/vendor/liburing/debian/patches/series +1 -0
- data/vendor/liburing/debian/rules +29 -0
- data/vendor/liburing/debian/source/format +1 -0
- data/vendor/liburing/debian/source/local-options +2 -0
- data/vendor/liburing/debian/source/options +1 -0
- data/vendor/liburing/debian/watch +3 -0
- data/vendor/liburing/examples/Makefile +53 -0
- data/vendor/liburing/examples/helpers.c +62 -0
- data/vendor/liburing/examples/helpers.h +7 -0
- data/vendor/liburing/examples/io_uring-close-test.c +123 -0
- data/vendor/liburing/examples/io_uring-cp.c +282 -0
- data/vendor/liburing/examples/io_uring-test.c +112 -0
- data/vendor/liburing/examples/io_uring-udp.c +403 -0
- data/vendor/liburing/examples/link-cp.c +193 -0
- data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
- data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
- data/vendor/liburing/examples/poll-bench.c +101 -0
- data/vendor/liburing/examples/proxy.c +2461 -0
- data/vendor/liburing/examples/proxy.h +102 -0
- data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
- data/vendor/liburing/examples/send-zerocopy.c +658 -0
- data/vendor/liburing/examples/ucontext-cp.c +258 -0
- data/vendor/liburing/liburing-ffi.pc.in +12 -0
- data/vendor/liburing/liburing.pc.in +12 -0
- data/vendor/liburing/liburing.spec +66 -0
- data/vendor/liburing/make-debs.sh +55 -0
- data/vendor/liburing/src/Makefile +129 -0
- data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
- data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
- data/vendor/liburing/src/arch/generic/lib.h +17 -0
- data/vendor/liburing/src/arch/generic/syscall.h +100 -0
- data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
- data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
- data/vendor/liburing/src/arch/syscall-defs.h +94 -0
- data/vendor/liburing/src/arch/x86/lib.h +11 -0
- data/vendor/liburing/src/arch/x86/syscall.h +296 -0
- data/vendor/liburing/src/ffi.c +15 -0
- data/vendor/liburing/src/include/liburing/barrier.h +81 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
- data/vendor/liburing/src/include/liburing.h +1602 -0
- data/vendor/liburing/src/int_flags.h +11 -0
- data/vendor/liburing/src/lib.h +52 -0
- data/vendor/liburing/src/liburing-ffi.map +211 -0
- data/vendor/liburing/src/liburing.map +104 -0
- data/vendor/liburing/src/nolibc.c +55 -0
- data/vendor/liburing/src/queue.c +468 -0
- data/vendor/liburing/src/register.c +374 -0
- data/vendor/liburing/src/setup.c +689 -0
- data/vendor/liburing/src/setup.h +9 -0
- data/vendor/liburing/src/syscall.c +29 -0
- data/vendor/liburing/src/syscall.h +53 -0
- data/vendor/liburing/src/version.c +21 -0
- data/vendor/liburing/test/232c93d07b74.c +305 -0
- data/vendor/liburing/test/35fa71a030ca.c +329 -0
- data/vendor/liburing/test/500f9fbadef8.c +91 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
- data/vendor/liburing/test/8a9973408177.c +107 -0
- data/vendor/liburing/test/917257daa0fe.c +54 -0
- data/vendor/liburing/test/Makefile +297 -0
- data/vendor/liburing/test/a0908ae19763.c +59 -0
- data/vendor/liburing/test/a4c0b3decb33.c +181 -0
- data/vendor/liburing/test/accept-link.c +255 -0
- data/vendor/liburing/test/accept-non-empty.c +256 -0
- data/vendor/liburing/test/accept-reuse.c +163 -0
- data/vendor/liburing/test/accept-test.c +83 -0
- data/vendor/liburing/test/accept.c +919 -0
- data/vendor/liburing/test/across-fork.c +284 -0
- data/vendor/liburing/test/b19062a56726.c +54 -0
- data/vendor/liburing/test/b5837bd5311d.c +78 -0
- data/vendor/liburing/test/bind-listen.c +408 -0
- data/vendor/liburing/test/buf-ring-nommap.c +123 -0
- data/vendor/liburing/test/buf-ring-put.c +83 -0
- data/vendor/liburing/test/buf-ring.c +473 -0
- data/vendor/liburing/test/ce593a6c480a.c +139 -0
- data/vendor/liburing/test/close-opath.c +123 -0
- data/vendor/liburing/test/config +14 -0
- data/vendor/liburing/test/connect-rep.c +204 -0
- data/vendor/liburing/test/connect.c +442 -0
- data/vendor/liburing/test/coredump.c +60 -0
- data/vendor/liburing/test/cq-full.c +97 -0
- data/vendor/liburing/test/cq-overflow.c +530 -0
- data/vendor/liburing/test/cq-peek-batch.c +103 -0
- data/vendor/liburing/test/cq-ready.c +95 -0
- data/vendor/liburing/test/cq-size.c +65 -0
- data/vendor/liburing/test/d4ae271dfaae.c +96 -0
- data/vendor/liburing/test/d77a67ed5f27.c +65 -0
- data/vendor/liburing/test/defer-taskrun.c +391 -0
- data/vendor/liburing/test/defer-tw-timeout.c +173 -0
- data/vendor/liburing/test/defer.c +319 -0
- data/vendor/liburing/test/double-poll-crash.c +195 -0
- data/vendor/liburing/test/drop-submit.c +94 -0
- data/vendor/liburing/test/eeed8b54e0df.c +120 -0
- data/vendor/liburing/test/empty-eownerdead.c +45 -0
- data/vendor/liburing/test/eploop.c +74 -0
- data/vendor/liburing/test/eventfd-disable.c +179 -0
- data/vendor/liburing/test/eventfd-reg.c +77 -0
- data/vendor/liburing/test/eventfd-ring.c +98 -0
- data/vendor/liburing/test/eventfd.c +113 -0
- data/vendor/liburing/test/evloop.c +73 -0
- data/vendor/liburing/test/exec-target.c +6 -0
- data/vendor/liburing/test/exit-no-cleanup.c +117 -0
- data/vendor/liburing/test/fadvise.c +202 -0
- data/vendor/liburing/test/fallocate.c +265 -0
- data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
- data/vendor/liburing/test/fd-install.c +500 -0
- data/vendor/liburing/test/fd-pass.c +237 -0
- data/vendor/liburing/test/fdinfo.c +419 -0
- data/vendor/liburing/test/file-register.c +1189 -0
- data/vendor/liburing/test/file-update.c +231 -0
- data/vendor/liburing/test/file-verify.c +654 -0
- data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
- data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
- data/vendor/liburing/test/fixed-buf-iter.c +115 -0
- data/vendor/liburing/test/fixed-buf-merge.c +101 -0
- data/vendor/liburing/test/fixed-hugepage.c +411 -0
- data/vendor/liburing/test/fixed-link.c +90 -0
- data/vendor/liburing/test/fixed-reuse.c +160 -0
- data/vendor/liburing/test/fpos.c +255 -0
- data/vendor/liburing/test/fsnotify.c +118 -0
- data/vendor/liburing/test/fsync.c +224 -0
- data/vendor/liburing/test/futex.c +571 -0
- data/vendor/liburing/test/hardlink.c +170 -0
- data/vendor/liburing/test/helpers.c +318 -0
- data/vendor/liburing/test/helpers.h +108 -0
- data/vendor/liburing/test/ignore-single-mmap.c +48 -0
- data/vendor/liburing/test/init-mem.c +164 -0
- data/vendor/liburing/test/io-cancel.c +561 -0
- data/vendor/liburing/test/io_uring_enter.c +264 -0
- data/vendor/liburing/test/io_uring_passthrough.c +482 -0
- data/vendor/liburing/test/io_uring_register.c +503 -0
- data/vendor/liburing/test/io_uring_setup.c +110 -0
- data/vendor/liburing/test/iopoll-leak.c +85 -0
- data/vendor/liburing/test/iopoll-overflow.c +118 -0
- data/vendor/liburing/test/iopoll.c +465 -0
- data/vendor/liburing/test/lfs-openat-write.c +119 -0
- data/vendor/liburing/test/lfs-openat.c +273 -0
- data/vendor/liburing/test/link-timeout.c +1108 -0
- data/vendor/liburing/test/link.c +497 -0
- data/vendor/liburing/test/link_drain.c +255 -0
- data/vendor/liburing/test/madvise.c +195 -0
- data/vendor/liburing/test/min-timeout-wait.c +354 -0
- data/vendor/liburing/test/min-timeout.c +233 -0
- data/vendor/liburing/test/mkdir.c +112 -0
- data/vendor/liburing/test/msg-ring-fd.c +331 -0
- data/vendor/liburing/test/msg-ring-flags.c +212 -0
- data/vendor/liburing/test/msg-ring-overflow.c +159 -0
- data/vendor/liburing/test/msg-ring.c +467 -0
- data/vendor/liburing/test/multicqes_drain.c +429 -0
- data/vendor/liburing/test/napi-test.c +215 -0
- data/vendor/liburing/test/napi-test.sh +48 -0
- data/vendor/liburing/test/no-mmap-inval.c +42 -0
- data/vendor/liburing/test/nolibc.c +62 -0
- data/vendor/liburing/test/nop-all-sizes.c +99 -0
- data/vendor/liburing/test/nop.c +177 -0
- data/vendor/liburing/test/nvme.h +169 -0
- data/vendor/liburing/test/ooo-file-unreg.c +82 -0
- data/vendor/liburing/test/open-close.c +261 -0
- data/vendor/liburing/test/open-direct-link.c +188 -0
- data/vendor/liburing/test/open-direct-pick.c +180 -0
- data/vendor/liburing/test/openat2.c +312 -0
- data/vendor/liburing/test/personality.c +204 -0
- data/vendor/liburing/test/pipe-bug.c +95 -0
- data/vendor/liburing/test/pipe-eof.c +83 -0
- data/vendor/liburing/test/pipe-reuse.c +105 -0
- data/vendor/liburing/test/poll-cancel-all.c +496 -0
- data/vendor/liburing/test/poll-cancel-ton.c +135 -0
- data/vendor/liburing/test/poll-cancel.c +228 -0
- data/vendor/liburing/test/poll-link.c +221 -0
- data/vendor/liburing/test/poll-many.c +230 -0
- data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
- data/vendor/liburing/test/poll-mshot-update.c +323 -0
- data/vendor/liburing/test/poll-race-mshot.c +276 -0
- data/vendor/liburing/test/poll-race.c +105 -0
- data/vendor/liburing/test/poll-ring.c +48 -0
- data/vendor/liburing/test/poll-v-poll.c +353 -0
- data/vendor/liburing/test/poll.c +327 -0
- data/vendor/liburing/test/probe.c +135 -0
- data/vendor/liburing/test/read-before-exit.c +129 -0
- data/vendor/liburing/test/read-mshot-empty.c +153 -0
- data/vendor/liburing/test/read-mshot.c +404 -0
- data/vendor/liburing/test/read-write.c +1013 -0
- data/vendor/liburing/test/recv-msgall-stream.c +398 -0
- data/vendor/liburing/test/recv-msgall.c +263 -0
- data/vendor/liburing/test/recv-multishot.c +602 -0
- data/vendor/liburing/test/recvsend_bundle.c +691 -0
- data/vendor/liburing/test/reg-fd-only.c +131 -0
- data/vendor/liburing/test/reg-hint.c +56 -0
- data/vendor/liburing/test/reg-reg-ring.c +90 -0
- data/vendor/liburing/test/regbuf-merge.c +91 -0
- data/vendor/liburing/test/register-restrictions.c +633 -0
- data/vendor/liburing/test/rename.c +132 -0
- data/vendor/liburing/test/ring-leak.c +283 -0
- data/vendor/liburing/test/ring-leak2.c +249 -0
- data/vendor/liburing/test/ringbuf-read.c +196 -0
- data/vendor/liburing/test/ringbuf-status.c +242 -0
- data/vendor/liburing/test/rsrc_tags.c +461 -0
- data/vendor/liburing/test/runtests-loop.sh +16 -0
- data/vendor/liburing/test/runtests-quiet.sh +11 -0
- data/vendor/liburing/test/runtests.sh +168 -0
- data/vendor/liburing/test/rw_merge_test.c +98 -0
- data/vendor/liburing/test/self.c +91 -0
- data/vendor/liburing/test/send-zerocopy.c +971 -0
- data/vendor/liburing/test/send_recv.c +412 -0
- data/vendor/liburing/test/send_recvmsg.c +444 -0
- data/vendor/liburing/test/shared-wq.c +84 -0
- data/vendor/liburing/test/short-read.c +75 -0
- data/vendor/liburing/test/shutdown.c +165 -0
- data/vendor/liburing/test/sigfd-deadlock.c +88 -0
- data/vendor/liburing/test/single-issuer.c +169 -0
- data/vendor/liburing/test/skip-cqe.c +428 -0
- data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
- data/vendor/liburing/test/socket-io-cmd.c +237 -0
- data/vendor/liburing/test/socket-rw-eagain.c +149 -0
- data/vendor/liburing/test/socket-rw-offset.c +149 -0
- data/vendor/liburing/test/socket-rw.c +137 -0
- data/vendor/liburing/test/socket.c +408 -0
- data/vendor/liburing/test/splice.c +512 -0
- data/vendor/liburing/test/sq-full-cpp.cc +45 -0
- data/vendor/liburing/test/sq-full.c +45 -0
- data/vendor/liburing/test/sq-poll-dup.c +211 -0
- data/vendor/liburing/test/sq-poll-kthread.c +169 -0
- data/vendor/liburing/test/sq-poll-share.c +138 -0
- data/vendor/liburing/test/sq-space_left.c +159 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
- data/vendor/liburing/test/sqpoll-exec.c +132 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
- data/vendor/liburing/test/sqpoll-sleep.c +69 -0
- data/vendor/liburing/test/statx.c +172 -0
- data/vendor/liburing/test/stdout.c +232 -0
- data/vendor/liburing/test/submit-and-wait.c +108 -0
- data/vendor/liburing/test/submit-link-fail.c +156 -0
- data/vendor/liburing/test/submit-reuse.c +237 -0
- data/vendor/liburing/test/symlink.c +117 -0
- data/vendor/liburing/test/sync-cancel.c +235 -0
- data/vendor/liburing/test/teardowns.c +58 -0
- data/vendor/liburing/test/test.h +36 -0
- data/vendor/liburing/test/thread-exit.c +143 -0
- data/vendor/liburing/test/timeout-new.c +256 -0
- data/vendor/liburing/test/timeout.c +1798 -0
- data/vendor/liburing/test/truncate.c +186 -0
- data/vendor/liburing/test/tty-write-dpoll.c +60 -0
- data/vendor/liburing/test/unlink.c +112 -0
- data/vendor/liburing/test/version.c +25 -0
- data/vendor/liburing/test/wait-timeout.c +287 -0
- data/vendor/liburing/test/waitid.c +373 -0
- data/vendor/liburing/test/wakeup-hang.c +162 -0
- data/vendor/liburing/test/wq-aff.c +146 -0
- data/vendor/liburing/test/xattr.c +442 -0
- metadata +412 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: generic tests for io_uring drain io
|
|
4
|
+
*
|
|
5
|
+
* The main idea is to randomly generate different type of sqe to
|
|
6
|
+
* challenge the drain logic. There are some restrictions for the
|
|
7
|
+
* generated sqes, details in io_uring maillist:
|
|
8
|
+
* https://lore.kernel.org/io-uring/39a49b4c-27c2-1035-b250-51daeccaab9b@linux.alibaba.com/
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
#include <errno.h>
|
|
12
|
+
#include <stdio.h>
|
|
13
|
+
#include <unistd.h>
|
|
14
|
+
#include <stdlib.h>
|
|
15
|
+
#include <string.h>
|
|
16
|
+
#include <time.h>
|
|
17
|
+
#include <poll.h>
|
|
18
|
+
|
|
19
|
+
#include "liburing.h"
|
|
20
|
+
#include "helpers.h"
|
|
21
|
+
|
|
22
|
+
enum {
|
|
23
|
+
multi,
|
|
24
|
+
single,
|
|
25
|
+
nop,
|
|
26
|
+
cancel,
|
|
27
|
+
op_last,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
struct sqe_info {
|
|
31
|
+
__u8 op;
|
|
32
|
+
unsigned flags;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
#define max_entry 50
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* sqe_flags: combination of sqe flags
|
|
39
|
+
* multi_sqes: record the user_data/index of all the multishot sqes
|
|
40
|
+
* cnt: how many entries there are in multi_sqes
|
|
41
|
+
* we can leverage multi_sqes array for cancelation: we randomly pick
|
|
42
|
+
* up an entry in multi_sqes when form a cancelation sqe.
|
|
43
|
+
* multi_cap: limitation of number of multishot sqes
|
|
44
|
+
*/
|
|
45
|
+
static const unsigned sqe_flags[4] = {
|
|
46
|
+
0,
|
|
47
|
+
IOSQE_IO_LINK,
|
|
48
|
+
IOSQE_IO_DRAIN,
|
|
49
|
+
IOSQE_IO_LINK | IOSQE_IO_DRAIN
|
|
50
|
+
};
|
|
51
|
+
static int multi_sqes[max_entry], cnt = 0;
|
|
52
|
+
static int multi_cap = max_entry / 5;
|
|
53
|
+
|
|
54
|
+
static int write_pipe(int pipe, char *str)
|
|
55
|
+
{
|
|
56
|
+
int ret;
|
|
57
|
+
do {
|
|
58
|
+
errno = 0;
|
|
59
|
+
ret = write(pipe, str, 3);
|
|
60
|
+
} while (ret == -1 && errno == EINTR);
|
|
61
|
+
return ret;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static void read_pipe(int pipe)
|
|
65
|
+
{
|
|
66
|
+
char str[4] = {0};
|
|
67
|
+
int ret;
|
|
68
|
+
|
|
69
|
+
ret = read(pipe, &str, 3);
|
|
70
|
+
if (ret < 0)
|
|
71
|
+
perror("read");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static int trigger_event(struct io_uring *ring, int p[])
|
|
75
|
+
{
|
|
76
|
+
int ret;
|
|
77
|
+
if ((ret = write_pipe(p[1], "foo")) != 3) {
|
|
78
|
+
fprintf(stderr, "bad write return %d\n", ret);
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
usleep(1000);
|
|
82
|
+
io_uring_get_events(ring);
|
|
83
|
+
read_pipe(p[0]);
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe,
|
|
88
|
+
unsigned sqe_flags, int arg)
|
|
89
|
+
{
|
|
90
|
+
switch (op) {
|
|
91
|
+
case multi:
|
|
92
|
+
io_uring_prep_poll_add(sqe, arg, POLLIN);
|
|
93
|
+
sqe->len |= IORING_POLL_ADD_MULTI;
|
|
94
|
+
break;
|
|
95
|
+
case single:
|
|
96
|
+
io_uring_prep_poll_add(sqe, arg, POLLIN);
|
|
97
|
+
break;
|
|
98
|
+
case nop:
|
|
99
|
+
io_uring_prep_nop(sqe);
|
|
100
|
+
break;
|
|
101
|
+
case cancel:
|
|
102
|
+
io_uring_prep_poll_remove(sqe, arg);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
sqe->flags = sqe_flags;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static __u8 generate_flags(int sqe_op)
|
|
109
|
+
{
|
|
110
|
+
__u8 flags = 0;
|
|
111
|
+
/*
|
|
112
|
+
* drain sqe must be put after multishot sqes canceled
|
|
113
|
+
*/
|
|
114
|
+
do {
|
|
115
|
+
flags = sqe_flags[rand() % 4];
|
|
116
|
+
} while ((flags & IOSQE_IO_DRAIN) && cnt);
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
* cancel req cannot have drain or link flag
|
|
120
|
+
*/
|
|
121
|
+
if (sqe_op == cancel) {
|
|
122
|
+
flags &= ~(IOSQE_IO_DRAIN | IOSQE_IO_LINK);
|
|
123
|
+
}
|
|
124
|
+
/*
|
|
125
|
+
* avoid below case:
|
|
126
|
+
* sqe0(multishot, link)->sqe1(nop, link)->sqe2(nop)->sqe3(cancel_sqe0)
|
|
127
|
+
* sqe3 may execute before sqe0 so that sqe0 isn't canceled
|
|
128
|
+
*/
|
|
129
|
+
if (sqe_op == multi)
|
|
130
|
+
flags &= ~IOSQE_IO_LINK;
|
|
131
|
+
|
|
132
|
+
return flags;
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
* function to generate opcode of a sqe
|
|
138
|
+
* several restrictions here:
|
|
139
|
+
* - cancel all the previous multishot sqes as soon as possible when
|
|
140
|
+
* we reach high watermark.
|
|
141
|
+
* - ensure there is some multishot sqe when generating a cancel sqe
|
|
142
|
+
* - ensure a cancel/multshot sqe is not in a linkchain
|
|
143
|
+
* - ensure number of multishot sqes doesn't exceed multi_cap
|
|
144
|
+
* - don't generate multishot sqes after high watermark
|
|
145
|
+
*/
|
|
146
|
+
static int generate_opcode(int i, int pre_flags)
|
|
147
|
+
{
|
|
148
|
+
int sqe_op;
|
|
149
|
+
int high_watermark = max_entry - max_entry / 5;
|
|
150
|
+
bool retry0 = false, retry1 = false, retry2 = false;
|
|
151
|
+
|
|
152
|
+
if ((i >= high_watermark) && cnt) {
|
|
153
|
+
sqe_op = cancel;
|
|
154
|
+
} else {
|
|
155
|
+
do {
|
|
156
|
+
sqe_op = rand() % op_last;
|
|
157
|
+
retry0 = (sqe_op == cancel) && (!cnt || (pre_flags & IOSQE_IO_LINK));
|
|
158
|
+
retry1 = (sqe_op == multi) && ((multi_cap - 1 < 0) || i >= high_watermark);
|
|
159
|
+
retry2 = (sqe_op == multi) && (pre_flags & IOSQE_IO_LINK);
|
|
160
|
+
} while (retry0 || retry1 || retry2);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (sqe_op == multi)
|
|
164
|
+
multi_cap--;
|
|
165
|
+
return sqe_op;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static inline void add_multishot_sqe(int index)
|
|
169
|
+
{
|
|
170
|
+
multi_sqes[cnt++] = index;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static int remove_multishot_sqe(void)
|
|
174
|
+
{
|
|
175
|
+
int ret;
|
|
176
|
+
|
|
177
|
+
int rem_index = rand() % cnt;
|
|
178
|
+
ret = multi_sqes[rem_index];
|
|
179
|
+
multi_sqes[rem_index] = multi_sqes[cnt - 1];
|
|
180
|
+
cnt--;
|
|
181
|
+
|
|
182
|
+
return ret;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static int test_generic_drain(struct io_uring *ring)
|
|
186
|
+
{
|
|
187
|
+
struct io_uring_cqe *cqe;
|
|
188
|
+
struct io_uring_sqe *sqe[max_entry];
|
|
189
|
+
struct sqe_info si[max_entry];
|
|
190
|
+
int cqe_data[max_entry << 1], cqe_res[max_entry << 1];
|
|
191
|
+
int i, j, ret, arg = 0;
|
|
192
|
+
int pipes[max_entry][2];
|
|
193
|
+
int pre_flags = 0;
|
|
194
|
+
|
|
195
|
+
for (i = 0; i < max_entry; i++) {
|
|
196
|
+
if (pipe(pipes[i]) != 0) {
|
|
197
|
+
perror("pipe");
|
|
198
|
+
return 1;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
srand((unsigned)time(NULL));
|
|
203
|
+
for (i = 0; i < max_entry; i++) {
|
|
204
|
+
sqe[i] = io_uring_get_sqe(ring);
|
|
205
|
+
if (!sqe[i]) {
|
|
206
|
+
printf("get sqe failed\n");
|
|
207
|
+
goto err;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
int sqe_op = generate_opcode(i, pre_flags);
|
|
211
|
+
__u8 flags = generate_flags(sqe_op);
|
|
212
|
+
|
|
213
|
+
if (sqe_op == cancel)
|
|
214
|
+
arg = remove_multishot_sqe();
|
|
215
|
+
if (sqe_op == multi || sqe_op == single)
|
|
216
|
+
arg = pipes[i][0];
|
|
217
|
+
io_uring_sqe_prep(sqe_op, sqe[i], flags, arg);
|
|
218
|
+
sqe[i]->user_data = i;
|
|
219
|
+
si[i].op = sqe_op;
|
|
220
|
+
si[i].flags = flags;
|
|
221
|
+
pre_flags = flags;
|
|
222
|
+
if (sqe_op == multi)
|
|
223
|
+
add_multishot_sqe(i);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
ret = io_uring_submit(ring);
|
|
227
|
+
if (ret < 0) {
|
|
228
|
+
printf("sqe submit failed\n");
|
|
229
|
+
goto err;
|
|
230
|
+
} else if (ret < max_entry) {
|
|
231
|
+
printf("Submitted only %d\n", ret);
|
|
232
|
+
goto err;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
sleep(1);
|
|
236
|
+
// TODO: randomize event triggering order
|
|
237
|
+
for (i = 0; i < max_entry; i++) {
|
|
238
|
+
if (si[i].op != multi && si[i].op != single)
|
|
239
|
+
continue;
|
|
240
|
+
|
|
241
|
+
if (trigger_event(ring, pipes[i]))
|
|
242
|
+
goto err;
|
|
243
|
+
}
|
|
244
|
+
sleep(1);
|
|
245
|
+
i = 0;
|
|
246
|
+
while (!io_uring_peek_cqe(ring, &cqe)) {
|
|
247
|
+
cqe_data[i] = cqe->user_data;
|
|
248
|
+
cqe_res[i++] = cqe->res;
|
|
249
|
+
io_uring_cqe_seen(ring, cqe);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/*
|
|
253
|
+
* compl_bits is a bit map to record completions.
|
|
254
|
+
* eg. sqe[0], sqe[1], sqe[2] fully completed
|
|
255
|
+
* then compl_bits is 000...00111b
|
|
256
|
+
*
|
|
257
|
+
*/
|
|
258
|
+
unsigned long long compl_bits = 0;
|
|
259
|
+
for (j = 0; j < i; j++) {
|
|
260
|
+
int index = cqe_data[j];
|
|
261
|
+
if ((si[index].flags & IOSQE_IO_DRAIN) && index) {
|
|
262
|
+
if ((~compl_bits) & ((1ULL << index) - 1)) {
|
|
263
|
+
printf("drain failed\n");
|
|
264
|
+
goto err;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/*
|
|
268
|
+
* for multishot sqes, record them only when it is canceled
|
|
269
|
+
*/
|
|
270
|
+
if ((si[index].op != multi) || (cqe_res[j] == -ECANCELED))
|
|
271
|
+
compl_bits |= (1ULL << index);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return 0;
|
|
275
|
+
err:
|
|
276
|
+
return 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
static int test_simple_drain(struct io_uring *ring)
|
|
280
|
+
{
|
|
281
|
+
struct io_uring_cqe *cqe;
|
|
282
|
+
struct io_uring_sqe *sqe[2];
|
|
283
|
+
int i, ret;
|
|
284
|
+
int pipe1[2], pipe2[2];
|
|
285
|
+
|
|
286
|
+
if (pipe(pipe1) != 0 || pipe(pipe2) != 0) {
|
|
287
|
+
perror("pipe");
|
|
288
|
+
return 1;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
for (i = 0; i < 2; i++) {
|
|
292
|
+
sqe[i] = io_uring_get_sqe(ring);
|
|
293
|
+
if (!sqe[i]) {
|
|
294
|
+
printf("get sqe failed\n");
|
|
295
|
+
goto err;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
io_uring_prep_poll_multishot(sqe[0], pipe1[0], POLLIN);
|
|
300
|
+
sqe[0]->user_data = 0;
|
|
301
|
+
|
|
302
|
+
io_uring_prep_poll_add(sqe[1], pipe2[0], POLLIN);
|
|
303
|
+
sqe[1]->user_data = 1;
|
|
304
|
+
|
|
305
|
+
/* This test relies on multishot poll to trigger events continually.
|
|
306
|
+
* however with IORING_SETUP_DEFER_TASKRUN this will only happen when
|
|
307
|
+
* triggered with a get_events. Hence we sprinkle get_events whenever
|
|
308
|
+
* there might be work to process in order to get the same result
|
|
309
|
+
*/
|
|
310
|
+
ret = io_uring_submit_and_get_events(ring);
|
|
311
|
+
if (ret < 0) {
|
|
312
|
+
printf("sqe submit failed\n");
|
|
313
|
+
goto err;
|
|
314
|
+
} else if (ret < 2) {
|
|
315
|
+
printf("Submitted only %d\n", ret);
|
|
316
|
+
goto err;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
for (i = 0; i < 2; i++) {
|
|
320
|
+
if (trigger_event(ring, pipe1))
|
|
321
|
+
goto err;
|
|
322
|
+
}
|
|
323
|
+
if (trigger_event(ring, pipe2))
|
|
324
|
+
goto err;
|
|
325
|
+
|
|
326
|
+
for (i = 0; i < 2; i++) {
|
|
327
|
+
sqe[i] = io_uring_get_sqe(ring);
|
|
328
|
+
if (!sqe[i]) {
|
|
329
|
+
printf("get sqe failed\n");
|
|
330
|
+
goto err;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
io_uring_prep_poll_remove(sqe[0], 0);
|
|
335
|
+
sqe[0]->user_data = 2;
|
|
336
|
+
|
|
337
|
+
io_uring_prep_nop(sqe[1]);
|
|
338
|
+
sqe[1]->flags |= IOSQE_IO_DRAIN;
|
|
339
|
+
sqe[1]->user_data = 3;
|
|
340
|
+
|
|
341
|
+
ret = io_uring_submit(ring);
|
|
342
|
+
if (ret < 0) {
|
|
343
|
+
printf("sqe submit failed\n");
|
|
344
|
+
goto err;
|
|
345
|
+
} else if (ret < 2) {
|
|
346
|
+
printf("Submitted only %d\n", ret);
|
|
347
|
+
goto err;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
for (i = 0; i < 6; i++) {
|
|
351
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
352
|
+
if (ret < 0) {
|
|
353
|
+
printf("wait completion %d\n", ret);
|
|
354
|
+
goto err;
|
|
355
|
+
}
|
|
356
|
+
if ((i == 5) && (cqe->user_data != 3))
|
|
357
|
+
goto err;
|
|
358
|
+
io_uring_cqe_seen(ring, cqe);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
close(pipe1[0]);
|
|
362
|
+
close(pipe1[1]);
|
|
363
|
+
close(pipe2[0]);
|
|
364
|
+
close(pipe2[1]);
|
|
365
|
+
return 0;
|
|
366
|
+
err:
|
|
367
|
+
return 1;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static int test(bool defer_taskrun)
|
|
371
|
+
{
|
|
372
|
+
struct io_uring ring;
|
|
373
|
+
int i, ret;
|
|
374
|
+
unsigned int flags = 0;
|
|
375
|
+
|
|
376
|
+
if (defer_taskrun)
|
|
377
|
+
flags = IORING_SETUP_SINGLE_ISSUER |
|
|
378
|
+
IORING_SETUP_DEFER_TASKRUN;
|
|
379
|
+
|
|
380
|
+
ret = io_uring_queue_init(1024, &ring, flags);
|
|
381
|
+
if (ret) {
|
|
382
|
+
printf("ring setup failed\n");
|
|
383
|
+
return T_EXIT_FAIL;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
for (i = 0; i < 5; i++) {
|
|
387
|
+
ret = test_simple_drain(&ring);
|
|
388
|
+
if (ret) {
|
|
389
|
+
fprintf(stderr, "test_simple_drain failed\n");
|
|
390
|
+
return T_EXIT_FAIL;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
for (i = 0; i < 5; i++) {
|
|
395
|
+
ret = test_generic_drain(&ring);
|
|
396
|
+
if (ret) {
|
|
397
|
+
fprintf(stderr, "test_generic_drain failed\n");
|
|
398
|
+
return T_EXIT_FAIL;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
io_uring_queue_exit(&ring);
|
|
403
|
+
|
|
404
|
+
return T_EXIT_PASS;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
int main(int argc, char *argv[])
|
|
408
|
+
{
|
|
409
|
+
int ret;
|
|
410
|
+
|
|
411
|
+
if (argc > 1)
|
|
412
|
+
return T_EXIT_SKIP;
|
|
413
|
+
|
|
414
|
+
ret = test(false);
|
|
415
|
+
if (ret != T_EXIT_PASS) {
|
|
416
|
+
fprintf(stderr, "%s: test(false) failed\n", argv[0]);
|
|
417
|
+
return ret;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (t_probe_defer_taskrun()) {
|
|
421
|
+
ret = test(true);
|
|
422
|
+
if (ret != T_EXIT_PASS) {
|
|
423
|
+
fprintf(stderr, "%s: test(true) failed\n", argv[0]);
|
|
424
|
+
return ret;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return ret;
|
|
429
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: run NAPI receive test. Meant to be run from the associated
|
|
4
|
+
* script, napi-test.sh. That will invoke this test program
|
|
5
|
+
* as either a sender or receiver, with the queue flags passed
|
|
6
|
+
* in for testing.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <stdlib.h>
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
#include <assert.h>
|
|
13
|
+
#include <errno.h>
|
|
14
|
+
#include <fcntl.h>
|
|
15
|
+
#include <unistd.h>
|
|
16
|
+
#include <string.h>
|
|
17
|
+
#include <arpa/inet.h>
|
|
18
|
+
#include <linux/if_packet.h>
|
|
19
|
+
#include <linux/socket.h>
|
|
20
|
+
#include <sys/socket.h>
|
|
21
|
+
#include <sys/stat.h>
|
|
22
|
+
|
|
23
|
+
#include "liburing.h"
|
|
24
|
+
#include "helpers.h"
|
|
25
|
+
|
|
26
|
+
static const char receiver_address[] = "10.10.10.20";
|
|
27
|
+
static const int port = 9999;
|
|
28
|
+
#define BUF_SIZE 4096
|
|
29
|
+
|
|
30
|
+
static char buffer[BUF_SIZE];
|
|
31
|
+
static unsigned current_byte = 0;
|
|
32
|
+
|
|
33
|
+
static void do_setsockopt(int fd, int level, int optname, int val)
|
|
34
|
+
{
|
|
35
|
+
int ret = setsockopt(fd, level, optname, &val, sizeof(val));
|
|
36
|
+
|
|
37
|
+
assert(ret == 0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static int sender(void)
|
|
41
|
+
{
|
|
42
|
+
unsigned long long written = 0;
|
|
43
|
+
struct sockaddr_in addr;
|
|
44
|
+
int i, ret, fd;
|
|
45
|
+
|
|
46
|
+
memset(&addr, 0, sizeof(addr));
|
|
47
|
+
addr.sin_family = AF_INET;
|
|
48
|
+
addr.sin_port = htons(port);
|
|
49
|
+
ret = inet_pton(AF_INET, receiver_address, &addr.sin_addr);
|
|
50
|
+
assert(ret == 1);
|
|
51
|
+
|
|
52
|
+
fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
53
|
+
assert(fd >= 0);
|
|
54
|
+
|
|
55
|
+
/* don't race with receiver, give it 1 second to connect */
|
|
56
|
+
i = 0;
|
|
57
|
+
do {
|
|
58
|
+
ret = connect(fd, (void *)&addr, sizeof(addr));
|
|
59
|
+
if (!ret)
|
|
60
|
+
break;
|
|
61
|
+
if (ret == -1 && errno == ECONNREFUSED) {
|
|
62
|
+
if (i >= 10000) {
|
|
63
|
+
fprintf(stderr, "Gave up trying to connect\n");
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
usleep(100);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
i++;
|
|
70
|
+
} while (1);
|
|
71
|
+
|
|
72
|
+
while (written < 8 * 1024 * 1024) {
|
|
73
|
+
for (i = 0; i < BUF_SIZE; i++)
|
|
74
|
+
buffer[i] = current_byte + i;
|
|
75
|
+
|
|
76
|
+
ret = write(fd, buffer, BUF_SIZE);
|
|
77
|
+
if (ret <= 0) {
|
|
78
|
+
if (!ret || errno == ECONNRESET)
|
|
79
|
+
break;
|
|
80
|
+
fprintf(stderr, "write failed %i %i\n", ret, errno);
|
|
81
|
+
return 1;
|
|
82
|
+
}
|
|
83
|
+
written += ret;
|
|
84
|
+
current_byte += ret;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
close(fd);
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static int receiver(int queue_flags)
|
|
92
|
+
{
|
|
93
|
+
struct io_uring_sqe *sqe;
|
|
94
|
+
struct io_uring_cqe *cqe;
|
|
95
|
+
struct io_uring ring;
|
|
96
|
+
struct io_uring_napi napi = { };
|
|
97
|
+
struct sockaddr_in addr;
|
|
98
|
+
int fd, listen_fd;
|
|
99
|
+
int i, ret;
|
|
100
|
+
|
|
101
|
+
ret = io_uring_queue_init(8, &ring, queue_flags);
|
|
102
|
+
if (ret < 0) {
|
|
103
|
+
fprintf(stderr, "queue_init: %s\n", strerror(-ret));
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
napi.prefer_busy_poll = 1;
|
|
108
|
+
napi.busy_poll_to = 50;
|
|
109
|
+
io_uring_register_napi(&ring, &napi);
|
|
110
|
+
|
|
111
|
+
memset(&addr, 0, sizeof(addr));
|
|
112
|
+
addr.sin_family = AF_INET;
|
|
113
|
+
addr.sin_port = htons(port);
|
|
114
|
+
addr.sin_addr.s_addr = INADDR_ANY;
|
|
115
|
+
|
|
116
|
+
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
117
|
+
assert(listen_fd >= 0);
|
|
118
|
+
|
|
119
|
+
do_setsockopt(listen_fd, SOL_SOCKET, SO_REUSEPORT, 1);
|
|
120
|
+
ret = bind(listen_fd, (void *)&addr, sizeof(addr));
|
|
121
|
+
if (ret) {
|
|
122
|
+
fprintf(stderr, "bind failed %i %i\n", ret, errno);
|
|
123
|
+
return 1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
ret = listen(listen_fd, 8);
|
|
127
|
+
assert(ret == 0);
|
|
128
|
+
|
|
129
|
+
fd = accept(listen_fd, NULL, NULL);
|
|
130
|
+
assert(fd >= 0);
|
|
131
|
+
|
|
132
|
+
while (1) {
|
|
133
|
+
sqe = io_uring_get_sqe(&ring);
|
|
134
|
+
io_uring_prep_recv(sqe, fd, buffer, BUF_SIZE, 0);
|
|
135
|
+
|
|
136
|
+
ret = io_uring_submit(&ring);
|
|
137
|
+
if (ret != 1) {
|
|
138
|
+
fprintf(stderr, "io_uring_submit: %i\n", ret);
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
143
|
+
if (ret < 0) {
|
|
144
|
+
fprintf(stderr, "io_uring_wait_cqe: %i\n", ret);
|
|
145
|
+
return 1;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
ret = cqe->res;
|
|
149
|
+
if (ret <= 0) {
|
|
150
|
+
if (!ret)
|
|
151
|
+
break;
|
|
152
|
+
fprintf(stderr, "recv failed %i %i\n", ret, errno);
|
|
153
|
+
return 1;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (i = 0; i < ret; i++) {
|
|
157
|
+
char expected = current_byte + i;
|
|
158
|
+
|
|
159
|
+
if (buffer[i] != expected) {
|
|
160
|
+
fprintf(stderr, "data mismatch: idx %i, %c vs %c\n",
|
|
161
|
+
i, buffer[i], expected);
|
|
162
|
+
return 1;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
current_byte += ret;
|
|
167
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
close(fd);
|
|
171
|
+
io_uring_queue_exit(&ring);
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
int main(int argc, char **argv)
|
|
176
|
+
{
|
|
177
|
+
int queue_flags;
|
|
178
|
+
int is_rx;
|
|
179
|
+
|
|
180
|
+
if (geteuid()) {
|
|
181
|
+
fprintf(stdout, "NAPI test requires root\n");
|
|
182
|
+
return T_EXIT_SKIP;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (argc == 1) {
|
|
186
|
+
struct stat sb;
|
|
187
|
+
|
|
188
|
+
if (!stat("napi-test.sh", &sb)) {
|
|
189
|
+
return system("bash napi-test.sh");
|
|
190
|
+
} else if (!stat("test/napi-test.sh", &sb)) {
|
|
191
|
+
return system("bash test/napi-test.sh");
|
|
192
|
+
} else {
|
|
193
|
+
fprintf(stderr, "Can't find napi-test.sh\n");
|
|
194
|
+
return T_EXIT_SKIP;
|
|
195
|
+
}
|
|
196
|
+
} else if (argc == 2) {
|
|
197
|
+
return T_EXIT_SKIP;
|
|
198
|
+
} else if (argc != 3) {
|
|
199
|
+
return T_EXIT_SKIP;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (!strcmp(argv[1], "receive"))
|
|
203
|
+
is_rx = 1;
|
|
204
|
+
else if (!strcmp(argv[1], "send"))
|
|
205
|
+
is_rx = 0;
|
|
206
|
+
else
|
|
207
|
+
return T_EXIT_FAIL;
|
|
208
|
+
|
|
209
|
+
queue_flags = strtoul(argv[2], NULL, 16);
|
|
210
|
+
|
|
211
|
+
if (is_rx)
|
|
212
|
+
return receiver(queue_flags);
|
|
213
|
+
|
|
214
|
+
return sender();
|
|
215
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#! /usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
if [ ! -x "$(command -v ip)" ]; then
|
|
4
|
+
echo "Need ip installed"
|
|
5
|
+
exit 77
|
|
6
|
+
fi
|
|
7
|
+
if [ ! -x "$(command -v ethtool)" ]; then
|
|
8
|
+
echo "Need ethool installed"
|
|
9
|
+
exit 77
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
function clean_namespaces {
|
|
13
|
+
ip netns del iou-nscl
|
|
14
|
+
ip netns del iou-nsserv
|
|
15
|
+
}
|
|
16
|
+
trap clean_namespaces EXIT
|
|
17
|
+
|
|
18
|
+
ip link add iou-ptp-cl type veth peer name iou-ptp-serv
|
|
19
|
+
|
|
20
|
+
ip netns add iou-nscl
|
|
21
|
+
ip link set iou-ptp-cl netns iou-nscl
|
|
22
|
+
ip netns exec iou-nscl ip addr add '10.10.10.10/24' dev iou-ptp-cl
|
|
23
|
+
ip netns exec iou-nscl ethtool -K iou-ptp-cl tcp-segmentation-offload off
|
|
24
|
+
ip netns exec iou-nscl ethtool -K iou-ptp-cl generic-receive-offload on
|
|
25
|
+
ip netns exec iou-nscl ip link set dev iou-ptp-cl up
|
|
26
|
+
|
|
27
|
+
ip netns add iou-nsserv
|
|
28
|
+
ip link set iou-ptp-serv netns iou-nsserv
|
|
29
|
+
ip netns exec iou-nsserv ip addr add '10.10.10.20/24' dev iou-ptp-serv
|
|
30
|
+
ip netns exec iou-nsserv ethtool -K iou-ptp-serv tcp-segmentation-offload off
|
|
31
|
+
ip netns exec iou-nsserv ethtool -K iou-ptp-serv generic-receive-offload on
|
|
32
|
+
ip netns exec iou-nsserv ip link set dev iou-ptp-serv up
|
|
33
|
+
|
|
34
|
+
# test basic init, defer_taskrun, and sqpoll
|
|
35
|
+
QUEUE_FLAGS="0x0 0x3000 0x2"
|
|
36
|
+
for flags in $QUEUE_FLAGS; do
|
|
37
|
+
if [ -f "napi-test.t" ]; then
|
|
38
|
+
NAPI_TEST="./napi-test.t"
|
|
39
|
+
elif [ -f "test/napi-test.t" ]; then
|
|
40
|
+
NAPI_TEST="test/napi-test.t"
|
|
41
|
+
else
|
|
42
|
+
echo "Can't find napi-test.t"
|
|
43
|
+
exit 77
|
|
44
|
+
fi
|
|
45
|
+
ip netns exec iou-nsserv $NAPI_TEST receive $flags &
|
|
46
|
+
ip netns exec iou-nscl $NAPI_TEST send $flags
|
|
47
|
+
wait
|
|
48
|
+
done
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test that using SETUP_NO_MMAP with an invalid SQ ring
|
|
4
|
+
* address fails.
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
#include <sys/types.h>
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <unistd.h>
|
|
11
|
+
|
|
12
|
+
#include "liburing.h"
|
|
13
|
+
#include "helpers.h"
|
|
14
|
+
|
|
15
|
+
int main(int argc, char *argv[])
|
|
16
|
+
{
|
|
17
|
+
struct io_uring_params p = {
|
|
18
|
+
.sq_entries = 2,
|
|
19
|
+
.cq_entries = 4,
|
|
20
|
+
.flags = IORING_SETUP_NO_MMAP,
|
|
21
|
+
};
|
|
22
|
+
struct io_uring ring;
|
|
23
|
+
void *addr;
|
|
24
|
+
int ret;
|
|
25
|
+
|
|
26
|
+
if (argc > 1)
|
|
27
|
+
return T_EXIT_SKIP;
|
|
28
|
+
|
|
29
|
+
t_posix_memalign(&addr, sysconf(_SC_PAGESIZE), 8192);
|
|
30
|
+
p.cq_off.user_addr = (unsigned long long) (uintptr_t) addr;
|
|
31
|
+
|
|
32
|
+
ret = io_uring_queue_init_params(2, &ring, &p);
|
|
33
|
+
if (ret == -EINVAL) {
|
|
34
|
+
/* kernel doesn't support SETUP_NO_MMAP */
|
|
35
|
+
return T_EXIT_SKIP;
|
|
36
|
+
} else if (ret && (ret != -EFAULT && ret != -ENOMEM)) {
|
|
37
|
+
fprintf(stderr, "Got %d, wanted -EFAULT\n", ret);
|
|
38
|
+
return T_EXIT_FAIL;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return T_EXIT_PASS;
|
|
42
|
+
}
|