uringmachine 0.8.2 → 0.11

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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/TODO.md +0 -1
  4. data/examples/bm_side_running.rb +83 -0
  5. data/examples/bm_sqlite.rb +1 -1
  6. data/ext/um/um.c +66 -4
  7. data/ext/um/um.h +36 -0
  8. data/ext/um/um_class.c +6 -0
  9. data/ext/um/um_const.c +36 -0
  10. data/ext/um/um_ext.c +2 -0
  11. data/ext/um/um_stream.c +344 -0
  12. data/ext/um/um_stream_class.c +140 -0
  13. data/ext/um/um_utils.c +4 -0
  14. data/lib/uringmachine/actor.rb +1 -1
  15. data/lib/uringmachine/version.rb +1 -1
  16. data/lib/uringmachine.rb +35 -17
  17. data/test/test_fiber.rb +23 -3
  18. data/test/test_stream.rb +133 -0
  19. data/test/test_um.rb +109 -2
  20. data/uringmachine.gemspec +0 -2
  21. data/vendor/liburing/.github/workflows/{build.yml → ci.yml} +107 -42
  22. data/vendor/liburing/.gitignore +1 -0
  23. data/vendor/liburing/CHANGELOG +10 -0
  24. data/vendor/liburing/README +5 -0
  25. data/vendor/liburing/configure +1 -1
  26. data/vendor/liburing/examples/Makefile +1 -0
  27. data/vendor/liburing/examples/helpers.c +25 -0
  28. data/vendor/liburing/examples/helpers.h +13 -0
  29. data/vendor/liburing/examples/io_uring-test.c +3 -0
  30. data/vendor/liburing/examples/proxy.c +1 -1
  31. data/vendor/liburing/examples/reg-wait.c +41 -6
  32. data/vendor/liburing/examples/send-zerocopy.c +79 -32
  33. data/vendor/liburing/examples/zcrx.c +436 -0
  34. data/vendor/liburing/liburing.spec +1 -1
  35. data/vendor/liburing/src/Makefile +0 -1
  36. data/vendor/liburing/src/arch/generic/syscall.h +2 -2
  37. data/vendor/liburing/src/arch/syscall-defs.h +2 -2
  38. data/vendor/liburing/src/include/liburing/io_uring.h +101 -17
  39. data/vendor/liburing/src/include/liburing.h +179 -59
  40. data/vendor/liburing/src/int_flags.h +4 -1
  41. data/vendor/liburing/src/liburing-ffi.map +14 -2
  42. data/vendor/liburing/src/liburing.map +9 -2
  43. data/vendor/liburing/src/queue.c +35 -30
  44. data/vendor/liburing/src/register.c +46 -15
  45. data/vendor/liburing/src/sanitize.c +6 -9
  46. data/vendor/liburing/src/setup.c +37 -71
  47. data/vendor/liburing/src/syscall.c +2 -2
  48. data/vendor/liburing/test/232c93d07b74.c +1 -0
  49. data/vendor/liburing/test/Makefile +9 -0
  50. data/vendor/liburing/test/accept-test.c +1 -0
  51. data/vendor/liburing/test/cmd-discard.c +16 -8
  52. data/vendor/liburing/test/connect.c +11 -7
  53. data/vendor/liburing/test/epwait.c +420 -0
  54. data/vendor/liburing/test/eventfd-ring.c +30 -5
  55. data/vendor/liburing/test/fallocate.c +1 -1
  56. data/vendor/liburing/test/fixed-hugepage.c +10 -7
  57. data/vendor/liburing/test/fixed-seg.c +187 -0
  58. data/vendor/liburing/test/helpers.c +121 -0
  59. data/vendor/liburing/test/helpers.h +13 -0
  60. data/vendor/liburing/test/init-mem.c +2 -0
  61. data/vendor/liburing/test/io_uring_passthrough.c +78 -62
  62. data/vendor/liburing/test/iopoll-overflow.c +5 -4
  63. data/vendor/liburing/test/iopoll.c +20 -10
  64. data/vendor/liburing/test/iowait.c +141 -0
  65. data/vendor/liburing/test/nvme.h +2 -0
  66. data/vendor/liburing/test/pipe-bug.c +11 -5
  67. data/vendor/liburing/test/pipe-eof.c +11 -1
  68. data/vendor/liburing/test/read-inc-file.c +150 -0
  69. data/vendor/liburing/test/read-write.c +21 -14
  70. data/vendor/liburing/test/recv-bundle-short-ooo.c +435 -0
  71. data/vendor/liburing/test/recv-multishot.c +2 -2
  72. data/vendor/liburing/test/reg-wait.c +449 -120
  73. data/vendor/liburing/test/regbuf-clone.c +53 -0
  74. data/vendor/liburing/test/resize-rings.c +25 -2
  75. data/vendor/liburing/test/rsrc_tags.c +67 -14
  76. data/vendor/liburing/test/send-zerocopy.c +52 -130
  77. data/vendor/liburing/test/sendmsg_iov_clean.c +216 -0
  78. data/vendor/liburing/test/socket-nb.c +158 -0
  79. data/vendor/liburing/test/sqwait.c +9 -11
  80. data/vendor/liburing/test/timeout.c +198 -0
  81. data/vendor/liburing/test/vec-regbuf.c +609 -0
  82. data/vendor/liburing/test/wait-timeout.c +1 -1
  83. data/vendor/liburing/test/wq-aff.c +5 -1
  84. data/vendor/liburing/test/zcrx.c +928 -0
  85. metadata +16 -32
  86. data/vendor/liburing/.github/workflows/codespell.yml +0 -25
  87. data/vendor/liburing/.github/workflows/shellcheck.yml +0 -20
@@ -0,0 +1,141 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test toggling of iowait on kernels that support it
4
+ *
5
+ */
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+ #include <unistd.h>
9
+ #include <string.h>
10
+
11
+ #include "liburing.h"
12
+ #include "helpers.h"
13
+
14
+ static int get_iowait(int cpu)
15
+ {
16
+ char cpu_buf[32], this_cpu[32];
17
+ int user, nice, system, idle, iowait, ret;
18
+ FILE *file;
19
+
20
+ file = fopen("/proc/stat", "r");
21
+ if (!file) {
22
+ perror("fopen stat");
23
+ return 0;
24
+ }
25
+
26
+ sprintf(this_cpu, "cpu%d", cpu);
27
+ ret = 0;
28
+ do {
29
+ int r;
30
+ r = fscanf(file, "%s %d %d %d %d %d", cpu_buf, &user, &nice,
31
+ &system, &idle, &iowait);
32
+ if (r != 6)
33
+ continue;
34
+ if (strncmp(cpu_buf, this_cpu, strlen(this_cpu)))
35
+ continue;
36
+ ret = iowait;
37
+ break;
38
+ } while (1);
39
+
40
+ fclose(file);
41
+ return ret;
42
+ }
43
+
44
+ static int test(struct io_uring *ring, int with_iowait, int cpu)
45
+ {
46
+ struct io_uring_sqe *sqe;
47
+ struct io_uring_cqe *cqe;
48
+ int iowait_pre, iowait_post;
49
+ struct __kernel_timespec ts;
50
+ int ret, fds[2], diff;
51
+ char buf[32];
52
+
53
+ if (!(ring->features & IORING_FEAT_NO_IOWAIT))
54
+ return T_EXIT_SKIP;
55
+
56
+ if (pipe(fds) < 0) {
57
+ perror("pipe");
58
+ return T_EXIT_FAIL;
59
+ }
60
+
61
+ ret = io_uring_set_iowait(ring, with_iowait);
62
+ if (ret) {
63
+ fprintf(stderr, "set_iowait=%d\n", ret);
64
+ return T_EXIT_FAIL;
65
+ }
66
+
67
+ sqe = io_uring_get_sqe(ring);
68
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0);
69
+ io_uring_submit(ring);
70
+
71
+ ts.tv_sec = 1;
72
+ ts.tv_nsec = 0;
73
+ iowait_pre = get_iowait(cpu);
74
+ ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts);
75
+ if (ret != -ETIME) {
76
+ fprintf(stderr, "Unexpected wait ret: %d\n", ret);
77
+ return T_EXIT_FAIL;
78
+ }
79
+ iowait_post = get_iowait(cpu);
80
+ diff = iowait_post - iowait_pre;
81
+
82
+ close(fds[0]);
83
+ close(fds[1]);
84
+
85
+ ret = io_uring_wait_cqe(ring, &cqe);
86
+ if (ret) {
87
+ fprintf(stderr, "Unexpected wait ret: %d\n", ret);
88
+ return T_EXIT_FAIL;
89
+ }
90
+ io_uring_cqe_seen(ring, cqe);
91
+
92
+ if (with_iowait) {
93
+ if (diff < 90) {
94
+ fprintf(stderr, "iowait diff too small: %d\n", diff);
95
+ return T_EXIT_FAIL;
96
+ }
97
+ } else {
98
+ if (diff > 10) {
99
+ fprintf(stderr, "iowait diff too large: %d\n", diff);
100
+ return T_EXIT_FAIL;
101
+ }
102
+ }
103
+ return T_EXIT_PASS;
104
+ }
105
+
106
+ int main(int argc, char *argv[])
107
+ {
108
+ struct io_uring ring;
109
+ cpu_set_t cpuset;
110
+ int ret;
111
+
112
+ CPU_ZERO(&cpuset);
113
+ CPU_SET(0, &cpuset);
114
+ if (sched_setaffinity(0, sizeof(cpuset), &cpuset))
115
+ return T_EXIT_SKIP;
116
+
117
+ ret = t_create_ring(64, &ring, 0);
118
+ if (ret == T_SETUP_SKIP)
119
+ return T_EXIT_SKIP;
120
+ else if (ret != T_SETUP_OK)
121
+ return T_EXIT_FAIL;
122
+
123
+ ret = test(&ring, 0, 0);
124
+ if (ret == T_EXIT_SKIP) {
125
+ return T_EXIT_SKIP;
126
+ } else if (ret == T_EXIT_FAIL) {
127
+ fprintf(stderr, "test 0 failed\n");
128
+ return T_EXIT_FAIL;
129
+ }
130
+
131
+ ret = test(&ring, 1, 0);
132
+ if (ret == T_EXIT_SKIP) {
133
+ return T_EXIT_SKIP;
134
+ } else if (ret == T_EXIT_FAIL) {
135
+ fprintf(stderr, "test 1 failed\n");
136
+ return T_EXIT_FAIL;
137
+ }
138
+
139
+ io_uring_queue_exit(&ring);
140
+ return 0;
141
+ }
@@ -59,6 +59,7 @@ enum nvme_io_opcode {
59
59
 
60
60
  static int nsid;
61
61
  static __u32 lba_shift;
62
+ static __u32 meta_size;
62
63
 
63
64
  struct nvme_lbaf {
64
65
  __le16 ms;
@@ -157,6 +158,7 @@ static int nvme_get_info(const char *file)
157
158
 
158
159
  lba_size = 1 << ns.lbaf[(ns.flbas & 0x0f)].ds;
159
160
  lba_shift = ilog2(lba_size);
161
+ meta_size = ns.lbaf[(ns.flbas & 0x0f)].ms;
160
162
 
161
163
  close(fd);
162
164
  return 0;
@@ -24,20 +24,26 @@ do { \
24
24
 
25
25
  static int pipe_bug(void)
26
26
  {
27
- struct io_uring_params p;
28
27
  struct io_uring ring;
29
28
  struct io_uring_sqe *sqe;
30
29
  struct io_uring_cqe *cqe;
31
30
  char buf[1024];
32
- int fds[2];
31
+ int ret, fds[2];
33
32
  struct __kernel_timespec to = {
34
33
  .tv_sec = 1
35
34
  };
36
35
 
37
- CHECK(pipe(fds) == 0);
36
+ ret = io_uring_queue_init(8, &ring, 0);
37
+ /* can hit -ENOMEM due to repeated ring creation and teardowns */
38
+ if (ret == -ENOMEM) {
39
+ usleep(1000);
40
+ return 0;
41
+ } else if (ret) {
42
+ fprintf(stderr, "ring_init: %d\n", ret);
43
+ return 1;
44
+ }
38
45
 
39
- memset(&p, 0, sizeof(p));
40
- CHECK(t_create_ring_params(8, &ring, &p) == 0);
46
+ CHECK(pipe(fds) == 0);
41
47
 
42
48
  /* WRITE */
43
49
  sqe = io_uring_get_sqe(&ring);
@@ -11,6 +11,7 @@
11
11
  #include <pthread.h>
12
12
  #include <string.h>
13
13
  #include "liburing.h"
14
+ #include "helpers.h"
14
15
 
15
16
  #define BUFSIZE 512
16
17
 
@@ -41,13 +42,22 @@ int main(int argc, char *argv[])
41
42
  struct data d;
42
43
  int ret;
43
44
 
45
+ if (argc > 1)
46
+ return T_EXIT_SKIP;
47
+
44
48
  if (pipe(d.fds) < 0) {
45
49
  perror("pipe");
46
50
  return 1;
47
51
  }
48
52
  d.str = buf;
49
53
 
50
- io_uring_queue_init(8, &ring, 0);
54
+ ret = io_uring_queue_init(8, &ring, 0);
55
+ if (ret == -ENOMEM) {
56
+ return T_EXIT_SKIP;
57
+ } else if (ret) {
58
+ fprintf(stderr, "queue_init: %d\n", ret);
59
+ return T_EXIT_FAIL;
60
+ }
51
61
 
52
62
  pthread_create(&thread, NULL, t, &d);
53
63
 
@@ -0,0 +1,150 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test reading a normal file with incremental buffer
4
+ * consumption. Some kernels had a bug where the initial part
5
+ * of the buffer got skipped, test for that.
6
+ *
7
+ */
8
+ #include <stdio.h>
9
+ #include <unistd.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+ #include "liburing.h"
13
+ #include "helpers.h"
14
+
15
+ #define BUF_BGID 4
16
+ #define BUF_BID 8
17
+
18
+ static void arm_read(struct io_uring *ring, int fd, int offset)
19
+ {
20
+ struct io_uring_sqe *sqe;
21
+
22
+ sqe = io_uring_get_sqe(ring);
23
+ io_uring_prep_read(sqe, fd, NULL, 80, offset);
24
+ sqe->flags = IOSQE_BUFFER_SELECT;
25
+ sqe->buf_group = BUF_BGID;
26
+ io_uring_submit(ring);
27
+ }
28
+
29
+ static int create_test_file(const char *fname)
30
+ {
31
+ char buf[80], c;
32
+ int fd, i, ret;
33
+
34
+ fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
35
+ if (fd < 0) {
36
+ perror("open");
37
+ return T_EXIT_FAIL;
38
+ }
39
+
40
+ c = 'a';
41
+ for (i = 0; i < 8; i++) {
42
+ memset(buf, c, sizeof(buf));
43
+ ret = write(fd, buf, sizeof(buf));
44
+ if (ret < 0) {
45
+ perror("write");
46
+ unlink(fname);
47
+ return T_EXIT_FAIL;
48
+ } else if (ret != sizeof(buf)) {
49
+ fprintf(stderr, "Short write: %d\n", ret);
50
+ unlink(fname);
51
+ return T_EXIT_FAIL;
52
+ }
53
+ c++;
54
+ }
55
+
56
+ close(fd);
57
+ return 0;
58
+ }
59
+
60
+ int main(int argc, char *argv[])
61
+ {
62
+ struct io_uring_buf_ring *br;
63
+ struct io_uring_params p = { };
64
+ struct io_uring_cqe *cqe;
65
+ struct io_uring ring;
66
+ int tret, ret, fd, i;
67
+ char fname[64];
68
+ char c = 'a';
69
+ char *buf;
70
+ void *ptr;
71
+
72
+ if (argc > 1)
73
+ return T_EXIT_SKIP;
74
+
75
+ sprintf(fname, ".buf-inc-file.%d", getpid());
76
+ if (create_test_file(fname))
77
+ return T_EXIT_FAIL;
78
+
79
+ fd = open(fname, O_RDONLY);
80
+ if (fd < 0) {
81
+ perror("open");
82
+ goto err;
83
+ }
84
+
85
+ ret = io_uring_queue_init_params(64, &ring, &p);
86
+ if (ret) {
87
+ fprintf(stderr, "ring setup failed: %d\n", ret);
88
+ goto err;
89
+ }
90
+
91
+ if (posix_memalign((void **) &buf, 4096, 65536))
92
+ goto err;
93
+
94
+ tret = T_EXIT_SKIP;
95
+ br = io_uring_setup_buf_ring(&ring, 32, BUF_BGID, IOU_PBUF_RING_INC, &ret);
96
+ if (!br) {
97
+ if (ret == -EINVAL)
98
+ goto out;
99
+ fprintf(stderr, "Buffer ring register failed %d\n", ret);
100
+ goto err;
101
+ }
102
+
103
+ tret = T_EXIT_PASS;
104
+ io_uring_buf_ring_add(br, buf, 65536, BUF_BID, 31, 0);
105
+ io_uring_buf_ring_advance(br, 1);
106
+
107
+ memset(buf, 0, 65536);
108
+
109
+ ptr = buf;
110
+ for (i = 0; i < 4; i++) {
111
+ int bid;
112
+
113
+ arm_read(&ring, fd, i * 80);
114
+ ret = io_uring_wait_cqe(&ring, &cqe);
115
+ if (ret) {
116
+ fprintf(stderr, "wait %d\n", ret);
117
+ goto err;
118
+ }
119
+ if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
120
+ fprintf(stderr, "buffer not assigned\n");
121
+ goto err;
122
+ }
123
+ bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
124
+ if (bid != BUF_BID) {
125
+ fprintf(stderr, "got wrong buffer bid %d\n", bid);
126
+ goto err;
127
+ }
128
+ if (cqe->res != 80) {
129
+ fprintf(stderr, "bad read size %d\n", ret);
130
+ goto err;
131
+ }
132
+ io_uring_cqe_seen(&ring, cqe);
133
+ if (!memchr(ptr, c, cqe->res)) {
134
+ fprintf(stderr, "fail buffer check loop %d\n", i);
135
+ goto err;
136
+ }
137
+ c++;
138
+ ptr += cqe->res;
139
+ }
140
+
141
+ io_uring_free_buf_ring(&ring, br, 32, BUF_BGID);
142
+ io_uring_queue_exit(&ring);
143
+ out:
144
+ free(buf);
145
+ unlink(fname);
146
+ return tret;
147
+ err:
148
+ unlink(fname);
149
+ return T_EXIT_FAIL;
150
+ }
@@ -46,7 +46,7 @@ static int create_nonaligned_buffers(void)
46
46
 
47
47
  static int _test_io(const char *file, struct io_uring *ring, int write,
48
48
  int buffered, int sqthread, int fixed, int nonvec,
49
- int buf_select, int seq, int exp_len)
49
+ int buf_select, int seq, int exp_len, bool worker_offload)
50
50
  {
51
51
  struct io_uring_sqe *sqe;
52
52
  struct io_uring_cqe *cqe;
@@ -144,6 +144,10 @@ static int _test_io(const char *file, struct io_uring *ring, int write,
144
144
  sqe->user_data = i;
145
145
  if (sqthread)
146
146
  sqe->flags |= IOSQE_FIXED_FILE;
147
+
148
+ if (worker_offload)
149
+ sqe->flags |= IOSQE_ASYNC;
150
+
147
151
  if (buf_select) {
148
152
  if (nonvec)
149
153
  sqe->addr = 0;
@@ -227,12 +231,12 @@ err:
227
231
 
228
232
  static int __test_io(const char *file, struct io_uring *ring, int write,
229
233
  int buffered, int sqthread, int fixed, int nonvec,
230
- int buf_select, int seq, int exp_len)
234
+ int buf_select, int seq, int exp_len, bool worker_offload)
231
235
  {
232
236
  int ret;
233
237
 
234
238
  ret = _test_io(file, ring, write, buffered, sqthread, fixed, nonvec,
235
- buf_select, seq, exp_len);
239
+ buf_select, seq, exp_len, worker_offload);
236
240
  if (ret)
237
241
  return ret;
238
242
 
@@ -263,7 +267,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
263
267
  return ret;
264
268
  }
265
269
  ret = _test_io(file, &ring2, write, buffered, sqthread, 2,
266
- nonvec, buf_select, seq, exp_len);
270
+ nonvec, buf_select, seq, exp_len, worker_offload);
267
271
  if (ret)
268
272
  return ret;
269
273
 
@@ -284,7 +288,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
284
288
  }
285
289
 
286
290
  static int test_io(const char *file, int write, int buffered, int sqthread,
287
- int fixed, int nonvec, int exp_len)
291
+ int fixed, int nonvec, int exp_len, bool worker_offload)
288
292
  {
289
293
  struct io_uring ring;
290
294
  int ret, ring_flags = 0;
@@ -301,7 +305,7 @@ static int test_io(const char *file, int write, int buffered, int sqthread,
301
305
  }
302
306
 
303
307
  ret = __test_io(file, &ring, write, buffered, sqthread, fixed, nonvec,
304
- 0, 0, exp_len);
308
+ 0, 0, exp_len, worker_offload);
305
309
  io_uring_queue_exit(&ring);
306
310
  return ret;
307
311
  }
@@ -481,7 +485,8 @@ static int test_buf_select_short(const char *filename, int nonvec)
481
485
  io_uring_cqe_seen(&ring, cqe);
482
486
  }
483
487
 
484
- ret = __test_io(filename, &ring, 0, 0, 0, 0, nonvec, 1, 1, exp_len);
488
+ ret = __test_io(filename, &ring, 0, 0, 0, 0, nonvec, 1, 1, exp_len,
489
+ false);
485
490
 
486
491
  io_uring_queue_exit(&ring);
487
492
  return ret;
@@ -620,7 +625,7 @@ static int test_buf_select(const char *filename, int nonvec)
620
625
  for (i = 0; i < BUFFERS; i++)
621
626
  memset(vecs[i].iov_base, i, vecs[i].iov_len);
622
627
 
623
- ret = __test_io(filename, &ring, 1, 0, 0, 0, 0, 0, 1, BS);
628
+ ret = __test_io(filename, &ring, 1, 0, 0, 0, 0, 0, 1, BS, false);
624
629
  if (ret) {
625
630
  fprintf(stderr, "failed writing data\n");
626
631
  return 1;
@@ -633,7 +638,7 @@ static int test_buf_select(const char *filename, int nonvec)
633
638
  if (ret)
634
639
  return ret;
635
640
 
636
- ret = __test_io(filename, &ring, 0, 0, 0, 0, nonvec, 1, 1, BS);
641
+ ret = __test_io(filename, &ring, 0, 0, 0, 0, nonvec, 1, 1, BS, false);
637
642
  io_uring_queue_exit(&ring);
638
643
  return ret;
639
644
  }
@@ -933,17 +938,18 @@ int main(int argc, char *argv[])
933
938
  vecs = t_create_buffers(BUFFERS, BS);
934
939
 
935
940
  /* if we don't have nonvec read, skip testing that */
936
- nr = has_nonvec_read() ? 32 : 16;
941
+ nr = has_nonvec_read() ? 64 : 32;
937
942
 
938
943
  for (i = 0; i < nr; i++) {
939
944
  int write = (i & 1) != 0;
940
945
  int buffered = (i & 2) != 0;
941
946
  int sqthread = (i & 4) != 0;
942
947
  int fixed = (i & 8) != 0;
943
- int nonvec = (i & 16) != 0;
948
+ int offload = (i & 16) != 0;
949
+ int nonvec = (i & 32) != 0;
944
950
 
945
951
  ret = test_io(fname, write, buffered, sqthread, fixed, nonvec,
946
- BS);
952
+ BS, offload);
947
953
  if (ret) {
948
954
  fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n",
949
955
  write, buffered, sqthread, fixed, nonvec);
@@ -1047,14 +1053,15 @@ int main(int argc, char *argv[])
1047
1053
  int buffered = (i & 2) != 0;
1048
1054
  int sqthread = (i & 4) != 0;
1049
1055
  int fixed = (i & 8) != 0;
1050
- int nonvec = (i & 16) != 0;
1056
+ int offload = (i & 16) != 0;
1057
+ int nonvec = (i & 32) != 0;
1051
1058
 
1052
1059
  /* direct IO requires alignment, skip it */
1053
1060
  if (!buffered || !fixed || nonvec)
1054
1061
  continue;
1055
1062
 
1056
1063
  ret = test_io(fname, write, buffered, sqthread, fixed, nonvec,
1057
- -1);
1064
+ -1, offload);
1058
1065
  if (ret) {
1059
1066
  fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n",
1060
1067
  write, buffered, sqthread, fixed, nonvec);