uringmachine 0.3 → 0.5
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 +4 -4
- data/.github/workflows/test.yml +2 -1
- data/CHANGELOG.md +23 -0
- data/README.md +128 -0
- data/TODO.md +14 -0
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/echo_server.rb +18 -40
- data/examples/http_server.rb +42 -43
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +24 -23
- data/ext/um/um.c +524 -278
- data/ext/um/um.h +146 -44
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +217 -106
- data/ext/um/um_const.c +213 -0
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +86 -114
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +49 -4
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +28 -0
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +685 -46
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +6 -0
- data/vendor/liburing/CHANGELOG +16 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +64 -0
- data/vendor/liburing/examples/Makefile +9 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +59 -6
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +16 -0
- data/vendor/liburing/src/liburing.map +10 -0
- data/vendor/liburing/src/queue.c +28 -16
- data/vendor/liburing/src/register.c +106 -1
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +47 -19
- data/vendor/liburing/src/setup.h +6 -0
- data/vendor/liburing/test/35fa71a030ca.c +7 -0
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
- data/vendor/liburing/test/917257daa0fe.c +7 -0
- data/vendor/liburing/test/Makefile +38 -4
- data/vendor/liburing/test/a0908ae19763.c +7 -0
- data/vendor/liburing/test/a4c0b3decb33.c +7 -0
- data/vendor/liburing/test/accept.c +14 -4
- data/vendor/liburing/test/b19062a56726.c +7 -0
- data/vendor/liburing/test/bind-listen.c +2 -2
- data/vendor/liburing/test/buf-ring-nommap.c +10 -3
- data/vendor/liburing/test/buf-ring.c +2 -0
- data/vendor/liburing/test/cmd-discard.c +427 -0
- data/vendor/liburing/test/coredump.c +7 -0
- data/vendor/liburing/test/cq-overflow.c +13 -1
- data/vendor/liburing/test/d4ae271dfaae.c +11 -3
- data/vendor/liburing/test/defer-taskrun.c +2 -2
- data/vendor/liburing/test/defer-tw-timeout.c +4 -1
- data/vendor/liburing/test/defer.c +2 -2
- data/vendor/liburing/test/double-poll-crash.c +1 -1
- data/vendor/liburing/test/eeed8b54e0df.c +2 -0
- data/vendor/liburing/test/eventfd.c +0 -1
- data/vendor/liburing/test/exit-no-cleanup.c +11 -0
- data/vendor/liburing/test/fadvise.c +9 -26
- data/vendor/liburing/test/fdinfo.c +9 -1
- data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- data/vendor/liburing/test/file-register.c +14 -2
- data/vendor/liburing/test/file-update.c +1 -1
- data/vendor/liburing/test/file-verify.c +27 -16
- data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
- data/vendor/liburing/test/fixed-buf-iter.c +3 -1
- data/vendor/liburing/test/fixed-hugepage.c +12 -1
- data/vendor/liburing/test/fsnotify.c +1 -0
- data/vendor/liburing/test/futex.c +16 -4
- data/vendor/liburing/test/helpers.c +47 -0
- data/vendor/liburing/test/helpers.h +6 -0
- data/vendor/liburing/test/init-mem.c +5 -3
- data/vendor/liburing/test/io-cancel.c +0 -24
- data/vendor/liburing/test/io_uring_passthrough.c +4 -0
- data/vendor/liburing/test/io_uring_register.c +38 -8
- data/vendor/liburing/test/iopoll-leak.c +4 -0
- data/vendor/liburing/test/iopoll-overflow.c +1 -1
- data/vendor/liburing/test/iopoll.c +3 -3
- data/vendor/liburing/test/kallsyms.c +203 -0
- data/vendor/liburing/test/link-timeout.c +159 -0
- data/vendor/liburing/test/linked-defer-close.c +224 -0
- data/vendor/liburing/test/madvise.c +12 -25
- data/vendor/liburing/test/min-timeout-wait.c +0 -25
- data/vendor/liburing/test/min-timeout.c +0 -25
- data/vendor/liburing/test/mkdir.c +6 -0
- data/vendor/liburing/test/msg-ring.c +8 -2
- data/vendor/liburing/test/napi-test.c +16 -3
- data/vendor/liburing/test/no-mmap-inval.c +3 -1
- data/vendor/liburing/test/nop.c +44 -0
- data/vendor/liburing/test/ooo-file-unreg.c +1 -1
- data/vendor/liburing/test/open-close.c +40 -0
- data/vendor/liburing/test/openat2.c +37 -14
- data/vendor/liburing/test/poll-many.c +13 -7
- data/vendor/liburing/test/poll-mshot-update.c +17 -10
- data/vendor/liburing/test/poll-v-poll.c +6 -3
- data/vendor/liburing/test/pollfree.c +148 -0
- data/vendor/liburing/test/read-mshot-empty.c +158 -153
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +282 -27
- data/vendor/liburing/test/read-write.c +78 -13
- data/vendor/liburing/test/recv-msgall-stream.c +3 -0
- data/vendor/liburing/test/recv-msgall.c +5 -0
- data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
- data/vendor/liburing/test/recvsend_bundle.c +94 -31
- data/vendor/liburing/test/reg-fd-only.c +15 -5
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +645 -0
- data/vendor/liburing/test/regbuf-merge.c +7 -0
- data/vendor/liburing/test/register-restrictions.c +86 -85
- data/vendor/liburing/test/rename.c +59 -1
- data/vendor/liburing/test/resize-rings.c +643 -0
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/rsrc_tags.c +1 -1
- data/vendor/liburing/test/runtests.sh +16 -1
- data/vendor/liburing/test/send-zerocopy.c +59 -0
- data/vendor/liburing/test/short-read.c +1 -0
- data/vendor/liburing/test/socket.c +43 -0
- data/vendor/liburing/test/splice.c +3 -1
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +2 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
- data/vendor/liburing/test/sqpoll-sleep.c +40 -33
- data/vendor/liburing/test/sqwait.c +136 -0
- data/vendor/liburing/test/statx.c +89 -0
- data/vendor/liburing/test/stdout.c +2 -0
- data/vendor/liburing/test/submit-and-wait.c +1 -25
- data/vendor/liburing/test/submit-reuse.c +4 -26
- data/vendor/liburing/test/symlink.c +12 -1
- data/vendor/liburing/test/sync-cancel.c +56 -22
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +25 -34
- data/vendor/liburing/test/unlink.c +94 -1
- data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
- data/vendor/liburing/test/waitid.c +62 -8
- data/vendor/liburing/test/wq-aff.c +35 -0
- data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
- data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
- metadata +37 -6
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
@@ -0,0 +1,224 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Test that the final close of a file does indeed get it closed, if the
|
4
|
+
* ring is setup with DEFER_TASKRUN and the task is waiting in cqring_wait()
|
5
|
+
* during. Also see:
|
6
|
+
*
|
7
|
+
* https://github.com/axboe/liburing/issues/1235
|
8
|
+
*
|
9
|
+
* for a bug report, and the zig code on which this test program is based.
|
10
|
+
*/
|
11
|
+
#include <stdio.h>
|
12
|
+
#include <stdlib.h>
|
13
|
+
#include <string.h>
|
14
|
+
#include <unistd.h>
|
15
|
+
#include <errno.h>
|
16
|
+
#include <arpa/inet.h>
|
17
|
+
#include <sys/socket.h>
|
18
|
+
#include <signal.h>
|
19
|
+
#include <pthread.h>
|
20
|
+
|
21
|
+
#include "liburing.h"
|
22
|
+
#include "helpers.h"
|
23
|
+
|
24
|
+
enum {
|
25
|
+
IS_ACCEPT = 0,
|
26
|
+
IS_SEND = 0x100,
|
27
|
+
IS_SEND2 = 0x101,
|
28
|
+
IS_SEND3 = 0x102,
|
29
|
+
IS_CLOSE = 0x200,
|
30
|
+
};
|
31
|
+
|
32
|
+
struct thread_data {
|
33
|
+
int parent_pid;
|
34
|
+
};
|
35
|
+
|
36
|
+
static void *thread_fn(void *__data)
|
37
|
+
{
|
38
|
+
struct thread_data *data = __data;
|
39
|
+
struct sockaddr_in saddr;
|
40
|
+
int sockfd, ret;
|
41
|
+
char msg[64];
|
42
|
+
|
43
|
+
memset(&saddr, 0, sizeof(saddr));
|
44
|
+
saddr.sin_family = AF_INET;
|
45
|
+
saddr.sin_port = htons(9999);
|
46
|
+
inet_pton(AF_INET, "127.0.0.1", &saddr.sin_addr);
|
47
|
+
|
48
|
+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
49
|
+
if (sockfd < 0) {
|
50
|
+
perror("socket");
|
51
|
+
goto done;
|
52
|
+
}
|
53
|
+
|
54
|
+
ret = connect(sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
|
55
|
+
if (ret < 0) {
|
56
|
+
perror("connect");
|
57
|
+
close(sockfd);
|
58
|
+
goto done;
|
59
|
+
}
|
60
|
+
|
61
|
+
do {
|
62
|
+
memset(msg, 0, sizeof(msg));
|
63
|
+
ret = recv(sockfd, msg, sizeof(msg), 0);
|
64
|
+
} while (ret > 0);
|
65
|
+
|
66
|
+
close(sockfd);
|
67
|
+
done:
|
68
|
+
kill(data->parent_pid, SIGUSR1);
|
69
|
+
return NULL;
|
70
|
+
}
|
71
|
+
|
72
|
+
/* we got SIGUSR1, exit normally */
|
73
|
+
static void sig_usr1(int sig)
|
74
|
+
{
|
75
|
+
exit(T_EXIT_PASS);
|
76
|
+
}
|
77
|
+
|
78
|
+
/* timed out, failure */
|
79
|
+
static void sig_timeout(int sig)
|
80
|
+
{
|
81
|
+
exit(T_EXIT_FAIL);
|
82
|
+
}
|
83
|
+
|
84
|
+
int main(int argc, char *argv[])
|
85
|
+
{
|
86
|
+
struct io_uring ring;
|
87
|
+
struct io_uring_sqe *sqe;
|
88
|
+
struct io_uring_cqe *cqe;
|
89
|
+
struct sockaddr_in saddr;
|
90
|
+
char *msg1 = "message number 1\n";
|
91
|
+
char *msg2 = "message number 2\n";
|
92
|
+
char *msg3 = "message number 3\n";
|
93
|
+
int val, send_fd, ret, sockfd;
|
94
|
+
struct sigaction act[2] = { };
|
95
|
+
struct thread_data td;
|
96
|
+
pthread_t thread;
|
97
|
+
|
98
|
+
if (argc > 1)
|
99
|
+
return T_EXIT_SKIP;
|
100
|
+
|
101
|
+
memset(&saddr, 0, sizeof(saddr));
|
102
|
+
saddr.sin_family = AF_INET;
|
103
|
+
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
104
|
+
saddr.sin_port = htons(9999);
|
105
|
+
|
106
|
+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
107
|
+
if (sockfd < 0) {
|
108
|
+
perror("socket");
|
109
|
+
return T_EXIT_FAIL;
|
110
|
+
}
|
111
|
+
|
112
|
+
val = 1;
|
113
|
+
setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
|
114
|
+
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
115
|
+
|
116
|
+
ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
|
117
|
+
if (ret < 0) {
|
118
|
+
perror("bind");
|
119
|
+
close(sockfd);
|
120
|
+
return T_EXIT_FAIL;
|
121
|
+
}
|
122
|
+
|
123
|
+
ret = listen(sockfd, 1);
|
124
|
+
if (ret < 0) {
|
125
|
+
perror("listen");
|
126
|
+
close(sockfd);
|
127
|
+
return T_EXIT_FAIL;
|
128
|
+
}
|
129
|
+
|
130
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
|
131
|
+
IORING_SETUP_DEFER_TASKRUN);
|
132
|
+
if (ret == -EINVAL) {
|
133
|
+
close(sockfd);
|
134
|
+
return T_EXIT_SKIP;
|
135
|
+
}
|
136
|
+
|
137
|
+
sqe = io_uring_get_sqe(&ring);
|
138
|
+
io_uring_prep_multishot_accept(sqe, sockfd, NULL, NULL, 0);
|
139
|
+
sqe->user_data = IS_ACCEPT;
|
140
|
+
io_uring_submit(&ring);
|
141
|
+
|
142
|
+
/* check for no multishot accept */
|
143
|
+
ret = io_uring_peek_cqe(&ring, &cqe);
|
144
|
+
if (!ret && cqe->res == -EINVAL) {
|
145
|
+
close(sockfd);
|
146
|
+
return T_EXIT_SKIP;
|
147
|
+
}
|
148
|
+
|
149
|
+
/* expected exit */
|
150
|
+
act[0].sa_handler = sig_usr1;
|
151
|
+
sigaction(SIGUSR1, &act[0], NULL);
|
152
|
+
|
153
|
+
/* if this hits, we have failed */
|
154
|
+
act[1].sa_handler = sig_timeout;
|
155
|
+
sigaction(SIGALRM, &act[1], NULL);
|
156
|
+
alarm(5);
|
157
|
+
|
158
|
+
/* start receiver */
|
159
|
+
td.parent_pid = getpid();
|
160
|
+
pthread_create(&thread, NULL, thread_fn, &td);
|
161
|
+
|
162
|
+
do {
|
163
|
+
ret = io_uring_submit_and_wait(&ring, 1);
|
164
|
+
if (ret < 0) {
|
165
|
+
fprintf(stderr, "submit: %d\n", ret);
|
166
|
+
return T_EXIT_FAIL;
|
167
|
+
}
|
168
|
+
ret = io_uring_peek_cqe(&ring, &cqe);
|
169
|
+
if (ret) {
|
170
|
+
fprintf(stderr, "peek: %d\n", ret);
|
171
|
+
return T_EXIT_FAIL;
|
172
|
+
}
|
173
|
+
|
174
|
+
switch (cqe->user_data) {
|
175
|
+
case IS_ACCEPT:
|
176
|
+
send_fd = cqe->res;
|
177
|
+
io_uring_cqe_seen(&ring, cqe);
|
178
|
+
|
179
|
+
/*
|
180
|
+
* prep two sends, with the 2nd linked to a close
|
181
|
+
* operation. Once the close has been completed, that
|
182
|
+
* will terminate the receiving thread and that will
|
183
|
+
* in turn send this task a SIGUSR1 signal. If the
|
184
|
+
* kernel is buggy, then we never get SIGUSR1 and we
|
185
|
+
* will sit forever waiting and be timed out.
|
186
|
+
*/
|
187
|
+
sqe = io_uring_get_sqe(&ring);
|
188
|
+
io_uring_prep_send(sqe, send_fd, msg1, strlen(msg1), 0);
|
189
|
+
sqe->user_data = IS_SEND;
|
190
|
+
sqe->flags = IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_LINK;
|
191
|
+
|
192
|
+
sqe = io_uring_get_sqe(&ring);
|
193
|
+
io_uring_prep_send(sqe, send_fd, msg2, strlen(msg2), 0);
|
194
|
+
sqe->user_data = IS_SEND2;
|
195
|
+
sqe->flags = IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_LINK;
|
196
|
+
|
197
|
+
sqe = io_uring_get_sqe(&ring);
|
198
|
+
io_uring_prep_send(sqe, send_fd, msg3, strlen(msg3), 0);
|
199
|
+
sqe->user_data = IS_SEND3;
|
200
|
+
sqe->flags = IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_LINK;
|
201
|
+
|
202
|
+
sqe = io_uring_get_sqe(&ring);
|
203
|
+
io_uring_prep_close(sqe, send_fd);
|
204
|
+
sqe->user_data = IS_CLOSE;
|
205
|
+
sqe->flags = IOSQE_CQE_SKIP_SUCCESS;
|
206
|
+
break;
|
207
|
+
case IS_SEND:
|
208
|
+
case IS_SEND2:
|
209
|
+
fprintf(stderr, "Should not see send response\n");
|
210
|
+
io_uring_cqe_seen(&ring, cqe);
|
211
|
+
return T_EXIT_FAIL;
|
212
|
+
case IS_CLOSE:
|
213
|
+
fprintf(stderr, "Should not see close response\n");
|
214
|
+
io_uring_cqe_seen(&ring, cqe);
|
215
|
+
return T_EXIT_FAIL;
|
216
|
+
default:
|
217
|
+
fprintf(stderr, "got unknown cqe\n");
|
218
|
+
return T_EXIT_FAIL;
|
219
|
+
}
|
220
|
+
} while (1);
|
221
|
+
|
222
|
+
/* will never get here */
|
223
|
+
return T_EXIT_FAIL;
|
224
|
+
}
|
@@ -20,30 +20,6 @@
|
|
20
20
|
#define LOOPS 100
|
21
21
|
#define MIN_LOOPS 10
|
22
22
|
|
23
|
-
static unsigned long long utime_since(const struct timeval *s,
|
24
|
-
const struct timeval *e)
|
25
|
-
{
|
26
|
-
long long sec, usec;
|
27
|
-
|
28
|
-
sec = e->tv_sec - s->tv_sec;
|
29
|
-
usec = (e->tv_usec - s->tv_usec);
|
30
|
-
if (sec > 0 && usec < 0) {
|
31
|
-
sec--;
|
32
|
-
usec += 1000000;
|
33
|
-
}
|
34
|
-
|
35
|
-
sec *= 1000000;
|
36
|
-
return sec + usec;
|
37
|
-
}
|
38
|
-
|
39
|
-
static unsigned long long utime_since_now(struct timeval *tv)
|
40
|
-
{
|
41
|
-
struct timeval end;
|
42
|
-
|
43
|
-
gettimeofday(&end, NULL);
|
44
|
-
return utime_since(tv, &end);
|
45
|
-
}
|
46
|
-
|
47
23
|
static int do_madvise(struct io_uring *ring, void *addr, off_t len, int advice)
|
48
24
|
{
|
49
25
|
struct io_uring_sqe *sqe;
|
@@ -100,6 +76,8 @@ static int test_madvise(struct io_uring *ring, const char *filename)
|
|
100
76
|
|
101
77
|
fd = open(filename, O_RDONLY);
|
102
78
|
if (fd < 0) {
|
79
|
+
if (errno == EACCES || errno == EPERM)
|
80
|
+
return T_EXIT_SKIP;
|
103
81
|
perror("open");
|
104
82
|
return 1;
|
105
83
|
}
|
@@ -143,9 +121,12 @@ static int test_madvise(struct io_uring *ring, const char *filename)
|
|
143
121
|
return 1;
|
144
122
|
|
145
123
|
if (cached_read < uncached_read &&
|
146
|
-
cached_read2 < uncached_read)
|
124
|
+
cached_read2 < uncached_read) {
|
125
|
+
free(buf);
|
147
126
|
return 0;
|
127
|
+
}
|
148
128
|
|
129
|
+
free(buf);
|
149
130
|
return 2;
|
150
131
|
}
|
151
132
|
|
@@ -170,6 +151,8 @@ int main(int argc, char *argv[])
|
|
170
151
|
good = bad = 0;
|
171
152
|
for (i = 0; i < LOOPS; i++) {
|
172
153
|
ret = test_madvise(&ring, fname);
|
154
|
+
if (ret == T_EXIT_SKIP)
|
155
|
+
goto skip;
|
173
156
|
if (ret == 1) {
|
174
157
|
fprintf(stderr, "test_madvise failed\n");
|
175
158
|
goto err;
|
@@ -192,4 +175,8 @@ err:
|
|
192
175
|
if (fname != argv[1])
|
193
176
|
unlink(fname);
|
194
177
|
return T_EXIT_FAIL;
|
178
|
+
skip:
|
179
|
+
if (fname != argv[1])
|
180
|
+
unlink(fname);
|
181
|
+
return T_EXIT_SKIP;
|
195
182
|
}
|
@@ -22,31 +22,6 @@ struct data {
|
|
22
22
|
int nr_fds;
|
23
23
|
};
|
24
24
|
|
25
|
-
static unsigned long long mtime_since(const struct timeval *s,
|
26
|
-
const struct timeval *e)
|
27
|
-
{
|
28
|
-
long long sec, usec;
|
29
|
-
|
30
|
-
sec = e->tv_sec - s->tv_sec;
|
31
|
-
usec = (e->tv_usec - s->tv_usec);
|
32
|
-
if (sec > 0 && usec < 0) {
|
33
|
-
sec--;
|
34
|
-
usec += 1000000;
|
35
|
-
}
|
36
|
-
|
37
|
-
sec *= 1000;
|
38
|
-
usec /= 1000;
|
39
|
-
return sec + usec;
|
40
|
-
}
|
41
|
-
|
42
|
-
static unsigned long long mtime_since_now(struct timeval *tv)
|
43
|
-
{
|
44
|
-
struct timeval end;
|
45
|
-
|
46
|
-
gettimeofday(&end, NULL);
|
47
|
-
return mtime_since(tv, &end);
|
48
|
-
}
|
49
|
-
|
50
25
|
static int time_pass(struct timeval *start, unsigned long min_t,
|
51
26
|
unsigned long max_t, const char *name)
|
52
27
|
{
|
@@ -61,31 +61,6 @@ static int within_range(unsigned int target, unsigned int msec)
|
|
61
61
|
return (msec >= low && msec <= high);
|
62
62
|
}
|
63
63
|
|
64
|
-
static unsigned long long mtime_since(const struct timeval *s,
|
65
|
-
const struct timeval *e)
|
66
|
-
{
|
67
|
-
long long sec, usec;
|
68
|
-
|
69
|
-
sec = e->tv_sec - s->tv_sec;
|
70
|
-
usec = (e->tv_usec - s->tv_usec);
|
71
|
-
if (sec > 0 && usec < 0) {
|
72
|
-
sec--;
|
73
|
-
usec += 1000000;
|
74
|
-
}
|
75
|
-
|
76
|
-
sec *= 1000;
|
77
|
-
usec /= 1000;
|
78
|
-
return sec + usec;
|
79
|
-
}
|
80
|
-
|
81
|
-
static unsigned long long mtime_since_now(struct timeval *tv)
|
82
|
-
{
|
83
|
-
struct timeval end;
|
84
|
-
|
85
|
-
gettimeofday(&end, NULL);
|
86
|
-
return mtime_since(tv, &end);
|
87
|
-
}
|
88
|
-
|
89
64
|
static int test(int flags, int expected_ctx, int min_wait, int write_delay,
|
90
65
|
int nr_cqes, int msec_target)
|
91
66
|
{
|
@@ -97,6 +97,12 @@ int main(int argc, char *argv[])
|
|
97
97
|
goto err1;
|
98
98
|
}
|
99
99
|
|
100
|
+
ret = do_mkdirat(&ring, (const char *) (uintptr_t) 0x1234);
|
101
|
+
if (ret != -EFAULT) {
|
102
|
+
fprintf(stderr, "do_mkdirat bad address: %d\n", ret);
|
103
|
+
goto err1;
|
104
|
+
}
|
105
|
+
|
100
106
|
unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
|
101
107
|
io_uring_queue_exit(&ring);
|
102
108
|
return T_EXIT_PASS;
|
@@ -309,6 +309,8 @@ static int test_disabled_ring(struct io_uring *ring, int flags)
|
|
309
309
|
flags |= IORING_SETUP_R_DISABLED;
|
310
310
|
ret = io_uring_queue_init(8, &disabled_ring, flags);
|
311
311
|
if (ret) {
|
312
|
+
if (ret == -EINVAL)
|
313
|
+
return T_EXIT_SKIP;
|
312
314
|
fprintf(stderr, "ring setup failed: %d\n", ret);
|
313
315
|
return 1;
|
314
316
|
}
|
@@ -349,6 +351,8 @@ static int test(int ring_flags)
|
|
349
351
|
|
350
352
|
ret = io_uring_queue_init(8, &ring, ring_flags);
|
351
353
|
if (ret) {
|
354
|
+
if (ret == -EINVAL)
|
355
|
+
return T_EXIT_SKIP;
|
352
356
|
fprintf(stderr, "ring setup failed: %d\n", ret);
|
353
357
|
return T_EXIT_FAIL;
|
354
358
|
}
|
@@ -452,13 +456,15 @@ int main(int argc, char *argv[])
|
|
452
456
|
return T_EXIT_SKIP;
|
453
457
|
|
454
458
|
ret = test(0);
|
455
|
-
if (ret
|
459
|
+
if (ret == T_EXIT_FAIL) {
|
456
460
|
fprintf(stderr, "ring flags 0 failed\n");
|
457
461
|
return ret;
|
462
|
+
} else if (ret == T_EXIT_SKIP) {
|
463
|
+
return T_EXIT_SKIP;
|
458
464
|
}
|
459
465
|
|
460
466
|
ret = test(IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
|
461
|
-
if (ret
|
467
|
+
if (ret == T_EXIT_FAIL) {
|
462
468
|
fprintf(stderr, "ring flags defer failed\n");
|
463
469
|
return ret;
|
464
470
|
}
|
@@ -37,12 +37,23 @@ static void do_setsockopt(int fd, int level, int optname, int val)
|
|
37
37
|
assert(ret == 0);
|
38
38
|
}
|
39
39
|
|
40
|
-
static int sender(
|
40
|
+
static int sender(int queue_flags)
|
41
41
|
{
|
42
42
|
unsigned long long written = 0;
|
43
43
|
struct sockaddr_in addr;
|
44
|
+
struct io_uring ring;
|
44
45
|
int i, ret, fd;
|
45
46
|
|
47
|
+
/*
|
48
|
+
* Sender doesn't use the ring, but try and set one up with the same
|
49
|
+
* flags that the receiver will use. If that fails, we know the
|
50
|
+
* receiver will have failed too - just skip the test in that case.
|
51
|
+
*/
|
52
|
+
ret = io_uring_queue_init(1, &ring, queue_flags);
|
53
|
+
if (ret)
|
54
|
+
return T_EXIT_SKIP;
|
55
|
+
io_uring_queue_exit(&ring);
|
56
|
+
|
46
57
|
memset(&addr, 0, sizeof(addr));
|
47
58
|
addr.sin_family = AF_INET;
|
48
59
|
addr.sin_port = htons(port);
|
@@ -100,6 +111,8 @@ static int receiver(int queue_flags)
|
|
100
111
|
|
101
112
|
ret = io_uring_queue_init(8, &ring, queue_flags);
|
102
113
|
if (ret < 0) {
|
114
|
+
if (ret == -EINVAL)
|
115
|
+
return T_EXIT_SKIP;
|
103
116
|
fprintf(stderr, "queue_init: %s\n", strerror(-ret));
|
104
117
|
return 1;
|
105
118
|
}
|
@@ -134,7 +147,7 @@ static int receiver(int queue_flags)
|
|
134
147
|
io_uring_prep_recv(sqe, fd, buffer, BUF_SIZE, 0);
|
135
148
|
|
136
149
|
ret = io_uring_submit(&ring);
|
137
|
-
if (ret
|
150
|
+
if (ret < 0) {
|
138
151
|
fprintf(stderr, "io_uring_submit: %i\n", ret);
|
139
152
|
return 1;
|
140
153
|
}
|
@@ -211,5 +224,5 @@ int main(int argc, char **argv)
|
|
211
224
|
if (is_rx)
|
212
225
|
return receiver(queue_flags);
|
213
226
|
|
214
|
-
return sender();
|
227
|
+
return sender(queue_flags);
|
215
228
|
}
|
@@ -30,13 +30,15 @@ int main(int argc, char *argv[])
|
|
30
30
|
p.cq_off.user_addr = (unsigned long long) (uintptr_t) addr;
|
31
31
|
|
32
32
|
ret = io_uring_queue_init_params(2, &ring, &p);
|
33
|
-
if (ret == -EINVAL) {
|
33
|
+
if (ret == -EINVAL || ret == -ENOENT) {
|
34
34
|
/* kernel doesn't support SETUP_NO_MMAP */
|
35
|
+
free(addr);
|
35
36
|
return T_EXIT_SKIP;
|
36
37
|
} else if (ret && (ret != -EFAULT && ret != -ENOMEM)) {
|
37
38
|
fprintf(stderr, "Got %d, wanted -EFAULT\n", ret);
|
38
39
|
return T_EXIT_FAIL;
|
39
40
|
}
|
40
41
|
|
42
|
+
free(addr);
|
41
43
|
return T_EXIT_PASS;
|
42
44
|
}
|
data/vendor/liburing/test/nop.c
CHANGED
@@ -15,6 +15,45 @@
|
|
15
15
|
|
16
16
|
static int seq;
|
17
17
|
|
18
|
+
static int test_nop_inject(struct io_uring *ring, unsigned req_flags)
|
19
|
+
{
|
20
|
+
struct io_uring_cqe *cqe;
|
21
|
+
struct io_uring_sqe *sqe;
|
22
|
+
int ret;
|
23
|
+
|
24
|
+
sqe = io_uring_get_sqe(ring);
|
25
|
+
if (!sqe) {
|
26
|
+
fprintf(stderr, "get sqe failed\n");
|
27
|
+
goto err;
|
28
|
+
}
|
29
|
+
|
30
|
+
io_uring_prep_nop(sqe);
|
31
|
+
sqe->user_data = ++seq;
|
32
|
+
sqe->nop_flags = IORING_NOP_INJECT_RESULT;
|
33
|
+
sqe->flags |= req_flags;
|
34
|
+
sqe->len = -EFAULT;
|
35
|
+
|
36
|
+
ret = io_uring_submit(ring);
|
37
|
+
if (ret <= 0) {
|
38
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
39
|
+
goto err;
|
40
|
+
}
|
41
|
+
|
42
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
43
|
+
if (ret < 0) {
|
44
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
45
|
+
goto err;
|
46
|
+
}
|
47
|
+
if (cqe->res != -EINVAL && cqe->res != -EFAULT) {
|
48
|
+
fprintf(stderr, "expected injected result, got %d\n", cqe->res);
|
49
|
+
goto err;
|
50
|
+
}
|
51
|
+
io_uring_cqe_seen(ring, cqe);
|
52
|
+
return 0;
|
53
|
+
err:
|
54
|
+
return 1;
|
55
|
+
}
|
56
|
+
|
18
57
|
static int test_single_nop(struct io_uring *ring, unsigned req_flags)
|
19
58
|
{
|
20
59
|
struct io_uring_cqe *cqe;
|
@@ -151,6 +190,11 @@ static int test_ring(unsigned flags)
|
|
151
190
|
fprintf(stderr, "test_barrier_nop failed\n");
|
152
191
|
goto err;
|
153
192
|
}
|
193
|
+
ret = test_nop_inject(&ring, req_flags);
|
194
|
+
if (ret) {
|
195
|
+
fprintf(stderr, "test_nop_inject failed\n");
|
196
|
+
goto err;
|
197
|
+
}
|
154
198
|
}
|
155
199
|
err:
|
156
200
|
io_uring_queue_exit(&ring);
|
@@ -35,6 +35,36 @@ static int submit_wait(struct io_uring *ring)
|
|
35
35
|
return ret;
|
36
36
|
}
|
37
37
|
|
38
|
+
static int test_close_flush(void)
|
39
|
+
{
|
40
|
+
struct io_uring ring;
|
41
|
+
struct io_uring_sqe *sqe;
|
42
|
+
char buf[128];
|
43
|
+
int ret, fd;
|
44
|
+
|
45
|
+
sprintf(buf, "/sys/kernel/debug/tracing/per_cpu/cpu0/trace_pipe_raw");
|
46
|
+
fd = open(buf, O_RDONLY);
|
47
|
+
if (fd < 0)
|
48
|
+
return 0;
|
49
|
+
|
50
|
+
ret = io_uring_queue_init(8, &ring, 0);
|
51
|
+
if (ret) {
|
52
|
+
fprintf(stderr, "ring setup failed\n");
|
53
|
+
return -1;
|
54
|
+
}
|
55
|
+
|
56
|
+
sqe = io_uring_get_sqe(&ring);
|
57
|
+
io_uring_prep_close(sqe, fd);
|
58
|
+
ret = submit_wait(&ring);
|
59
|
+
if (ret) {
|
60
|
+
fprintf(stderr, "closefailed %i\n", ret);
|
61
|
+
return -1;
|
62
|
+
}
|
63
|
+
|
64
|
+
io_uring_queue_exit(&ring);
|
65
|
+
return 0;
|
66
|
+
}
|
67
|
+
|
38
68
|
static inline int try_close(struct io_uring *ring, int fd, int slot)
|
39
69
|
{
|
40
70
|
struct io_uring_sqe *sqe;
|
@@ -220,12 +250,16 @@ int main(int argc, char *argv[])
|
|
220
250
|
fprintf(stdout, "Open not supported, skipping\n");
|
221
251
|
goto done;
|
222
252
|
}
|
253
|
+
if (ret == -EPERM || ret == -EACCES)
|
254
|
+
return T_EXIT_SKIP;
|
223
255
|
fprintf(stderr, "test_openat absolute failed: %d\n", ret);
|
224
256
|
goto err;
|
225
257
|
}
|
226
258
|
|
227
259
|
ret = test_openat(&ring, path_rel, AT_FDCWD);
|
228
260
|
if (ret < 0) {
|
261
|
+
if (ret == -EPERM || ret == -EACCES)
|
262
|
+
return T_EXIT_SKIP;
|
229
263
|
fprintf(stderr, "test_openat relative failed: %d\n", ret);
|
230
264
|
goto err;
|
231
265
|
}
|
@@ -248,6 +282,12 @@ int main(int argc, char *argv[])
|
|
248
282
|
goto err;
|
249
283
|
}
|
250
284
|
|
285
|
+
ret = test_close_flush();
|
286
|
+
if (ret) {
|
287
|
+
fprintf(stderr, "test_close_flush failed\n");
|
288
|
+
goto err;
|
289
|
+
}
|
290
|
+
|
251
291
|
done:
|
252
292
|
unlink(path);
|
253
293
|
if (do_unlink)
|