polyphony 1.5 → 1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +14 -0
  4. data/TODO.md +0 -4
  5. data/ext/polyphony/backend_io_uring.c +34 -1
  6. data/ext/polyphony/backend_io_uring_context.c +24 -18
  7. data/ext/polyphony/backend_io_uring_context.h +4 -2
  8. data/ext/polyphony/backend_libev.c +4 -7
  9. data/ext/polyphony/event.c +21 -0
  10. data/ext/polyphony/extconf.rb +20 -18
  11. data/ext/polyphony/fiber.c +0 -2
  12. data/ext/polyphony/polyphony.c +2 -0
  13. data/ext/polyphony/polyphony.h +5 -0
  14. data/ext/polyphony/ring_buffer.c +1 -0
  15. data/ext/polyphony/runqueue_ring_buffer.c +1 -0
  16. data/ext/polyphony/thread.c +63 -0
  17. data/lib/polyphony/adapters/open3.rb +190 -0
  18. data/lib/polyphony/core/sync.rb +83 -13
  19. data/lib/polyphony/core/timer.rb +7 -25
  20. data/lib/polyphony/extensions/exception.rb +15 -0
  21. data/lib/polyphony/extensions/fiber.rb +14 -13
  22. data/lib/polyphony/extensions/io.rb +56 -14
  23. data/lib/polyphony/extensions/kernel.rb +1 -1
  24. data/lib/polyphony/extensions/object.rb +1 -13
  25. data/lib/polyphony/extensions/process.rb +76 -1
  26. data/lib/polyphony/extensions/thread.rb +19 -27
  27. data/lib/polyphony/version.rb +1 -1
  28. data/lib/polyphony.rb +11 -5
  29. data/test/helper.rb +46 -4
  30. data/test/open3/envutil.rb +380 -0
  31. data/test/open3/find_executable.rb +24 -0
  32. data/test/stress.rb +11 -7
  33. data/test/test_backend.rb +7 -2
  34. data/test/test_event.rb +10 -3
  35. data/test/test_ext.rb +2 -1
  36. data/test/test_fiber.rb +16 -4
  37. data/test/test_global_api.rb +13 -12
  38. data/test/test_io.rb +39 -0
  39. data/test/test_kernel.rb +2 -2
  40. data/test/test_monitor.rb +356 -0
  41. data/test/test_open3.rb +338 -0
  42. data/test/test_signal.rb +5 -1
  43. data/test/test_socket.rb +6 -3
  44. data/test/test_sync.rb +46 -0
  45. data/test/test_thread.rb +10 -1
  46. data/test/test_thread_pool.rb +5 -0
  47. data/test/test_throttler.rb +1 -1
  48. data/test/test_timer.rb +8 -2
  49. data/test/test_trace.rb +2 -0
  50. data/vendor/liburing/.github/workflows/build.yml +8 -0
  51. data/vendor/liburing/.gitignore +1 -0
  52. data/vendor/liburing/CHANGELOG +8 -0
  53. data/vendor/liburing/configure +17 -25
  54. data/vendor/liburing/debian/liburing-dev.manpages +2 -0
  55. data/vendor/liburing/debian/rules +2 -1
  56. data/vendor/liburing/examples/Makefile +2 -1
  57. data/vendor/liburing/examples/io_uring-udp.c +11 -3
  58. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  59. data/vendor/liburing/liburing.spec +1 -1
  60. data/vendor/liburing/make-debs.sh +4 -2
  61. data/vendor/liburing/src/Makefile +5 -5
  62. data/vendor/liburing/src/arch/aarch64/lib.h +1 -1
  63. data/vendor/liburing/src/include/liburing/io_uring.h +41 -16
  64. data/vendor/liburing/src/include/liburing.h +86 -11
  65. data/vendor/liburing/src/int_flags.h +1 -0
  66. data/vendor/liburing/src/liburing-ffi.map +12 -0
  67. data/vendor/liburing/src/liburing.map +8 -0
  68. data/vendor/liburing/src/register.c +7 -2
  69. data/vendor/liburing/src/setup.c +373 -81
  70. data/vendor/liburing/test/232c93d07b74.c +3 -3
  71. data/vendor/liburing/test/Makefile +10 -3
  72. data/vendor/liburing/test/accept.c +2 -1
  73. data/vendor/liburing/test/buf-ring.c +35 -75
  74. data/vendor/liburing/test/connect-rep.c +204 -0
  75. data/vendor/liburing/test/coredump.c +59 -0
  76. data/vendor/liburing/test/fallocate.c +9 -0
  77. data/vendor/liburing/test/fd-pass.c +34 -3
  78. data/vendor/liburing/test/file-verify.c +27 -6
  79. data/vendor/liburing/test/helpers.c +3 -1
  80. data/vendor/liburing/test/io_uring_register.c +25 -28
  81. data/vendor/liburing/test/io_uring_setup.c +1 -1
  82. data/vendor/liburing/test/poll-cancel-all.c +29 -5
  83. data/vendor/liburing/test/poll-race-mshot.c +6 -22
  84. data/vendor/liburing/test/read-write.c +53 -0
  85. data/vendor/liburing/test/recv-msgall.c +21 -23
  86. data/vendor/liburing/test/reg-fd-only.c +55 -0
  87. data/vendor/liburing/test/reg-hint.c +56 -0
  88. data/vendor/liburing/test/regbuf-merge.c +91 -0
  89. data/vendor/liburing/test/ringbuf-read.c +2 -10
  90. data/vendor/liburing/test/send_recvmsg.c +5 -16
  91. data/vendor/liburing/test/shutdown.c +2 -1
  92. data/vendor/liburing/test/socket-io-cmd.c +215 -0
  93. data/vendor/liburing/test/socket-rw-eagain.c +2 -1
  94. data/vendor/liburing/test/socket-rw-offset.c +2 -1
  95. data/vendor/liburing/test/socket-rw.c +2 -1
  96. data/vendor/liburing/test/timeout.c +276 -0
  97. data/vendor/liburing/test/xattr.c +38 -25
  98. metadata +14 -3
  99. data/vendor/liburing/test/timeout-overflow.c +0 -204
@@ -20,7 +20,8 @@ example_srcs := \
20
20
  io_uring-udp.c \
21
21
  link-cp.c \
22
22
  poll-bench.c \
23
- send-zerocopy.c
23
+ send-zerocopy.c \
24
+ rsrc-update-bench.c
24
25
 
25
26
  all_targets :=
26
27
 
@@ -271,14 +271,22 @@ static int process_cqe_recv(struct ctx *ctx, struct io_uring_cqe *cqe,
271
271
  }
272
272
 
273
273
  if (ctx->verbose) {
274
+ struct sockaddr_in *addr = io_uring_recvmsg_name(o);
275
+ struct sockaddr_in6 *addr6 = (void *)addr;
274
276
  char buff[INET6_ADDRSTRLEN + 1];
275
277
  const char *name;
276
- struct sockaddr_in *addr = io_uring_recvmsg_name(o);
278
+ void *paddr;
277
279
 
278
- name = inet_ntop(ctx->af, &addr->sin_addr, buff, sizeof(buff));
280
+ if (ctx->af == AF_INET6)
281
+ paddr = &addr6->sin6_addr;
282
+ else
283
+ paddr = &addr->sin_addr;
284
+
285
+ name = inet_ntop(ctx->af, paddr, buff, sizeof(buff));
279
286
  if (!name)
280
287
  name = "<INVALID>";
281
- fprintf(stderr, "received %u bytes %d from %s:%d\n",
288
+
289
+ fprintf(stderr, "received %u bytes %d from [%s]:%d\n",
282
290
  io_uring_recvmsg_payload_length(o, cqe->res, &ctx->msg),
283
291
  o->namelen, name, (int)ntohs(addr->sin_port));
284
292
  }
@@ -0,0 +1,100 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ #include <errno.h>
3
+ #include <stdio.h>
4
+ #include <unistd.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <signal.h>
8
+ #include <poll.h>
9
+ #include <sys/time.h>
10
+ #include <sys/wait.h>
11
+
12
+ #include "liburing.h"
13
+
14
+ static unsigned long runtime_ms = 10000;
15
+
16
+ static unsigned long gettimeofday_ms(void)
17
+ {
18
+ struct timeval tv;
19
+
20
+ gettimeofday(&tv, NULL);
21
+ return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
22
+ }
23
+
24
+ int main(void)
25
+ {
26
+ unsigned long tstop;
27
+ unsigned long nr_reqs = 0;
28
+ struct io_uring_cqe *cqe;
29
+ struct io_uring_sqe *sqe;
30
+ struct io_uring ring;
31
+ int pipe1[2];
32
+ int ret, i, qd = 32;
33
+ int table_size = 128;
34
+
35
+ if (pipe(pipe1) != 0) {
36
+ perror("pipe");
37
+ return 1;
38
+ }
39
+
40
+ ret = io_uring_queue_init(1024, &ring, IORING_SETUP_SINGLE_ISSUER |
41
+ IORING_SETUP_DEFER_TASKRUN);
42
+ if (ret) {
43
+ fprintf(stderr, "io_uring_queue_init failed: %d\n", ret);
44
+ return 1;
45
+ }
46
+ ret = io_uring_register_ring_fd(&ring);
47
+ if (ret < 0) {
48
+ fprintf(stderr, "io_uring_register_ring_fd failed\n");
49
+ return 1;
50
+ }
51
+ ret = io_uring_register_files_sparse(&ring, table_size);
52
+ if (ret < 0) {
53
+ fprintf(stderr, "io_uring_register_files_sparse failed\n");
54
+ return 1;
55
+ }
56
+
57
+ for (i = 0; i < table_size; i++) {
58
+ ret = io_uring_register_files_update(&ring, i, pipe1, 1);
59
+ if (ret < 0) {
60
+ fprintf(stderr, "io_uring_register_files_update failed\n");
61
+ return 1;
62
+ }
63
+ }
64
+
65
+ srand(time(NULL));
66
+
67
+ tstop = gettimeofday_ms() + runtime_ms;
68
+ do {
69
+ int off = rand();
70
+
71
+ for (i = 0; i < qd; i++) {
72
+ sqe = io_uring_get_sqe(&ring);
73
+ int roff = (off + i) % table_size;
74
+ io_uring_prep_files_update(sqe, pipe1, 1, roff);
75
+ }
76
+
77
+ ret = io_uring_submit(&ring);
78
+ if (ret != qd) {
79
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
80
+ return 1;
81
+ }
82
+
83
+ for (i = 0; i < qd; i++) {
84
+ ret = io_uring_wait_cqe(&ring, &cqe);
85
+ if (ret < 0) {
86
+ fprintf(stderr, "child: wait completion %d\n", ret);
87
+ break;
88
+ }
89
+ io_uring_cqe_seen(&ring, cqe);
90
+ nr_reqs++;
91
+ }
92
+ } while (gettimeofday_ms() < tstop);
93
+
94
+ fprintf(stderr, "max updates/s: %lu\n", nr_reqs * 1000UL / runtime_ms);
95
+
96
+ io_uring_queue_exit(&ring);
97
+ close(pipe1[0]);
98
+ close(pipe1[1]);
99
+ return 0;
100
+ }
@@ -1,5 +1,5 @@
1
1
  Name: liburing
2
- Version: 2.4
2
+ Version: 2.5
3
3
  Release: 1%{?dist}
4
4
  Summary: Linux-native io_uring I/O access library
5
5
  License: (GPLv2 with exceptions and LGPLv2+) or MIT
@@ -23,6 +23,8 @@ distro=unstable
23
23
  releasedir=$base/$(lsb_release -si)/liburing
24
24
  rm -rf $releasedir
25
25
  mkdir -p $releasedir
26
+ HEAD=$(which head)
27
+ DCH=$(which dch)
26
28
 
27
29
  src_dir=$(readlink -e `basename $0`)
28
30
  liburing_dir=$(dirname $src_dir)
@@ -38,9 +40,9 @@ cd ${releasedir}/${outfile}
38
40
  git clean -dxf
39
41
 
40
42
  # Change changelog if it's needed
41
- cur_ver=`head -l debian/changelog | sed -n -e 's/.* (\(.*\)) .*/\1/p'`
43
+ cur_ver=`$HEAD < debian/changelog | sed -n -e 's/.* (\(.*\)) .*/\1/p'`
42
44
  if [ "$cur_ver" != "$version-1" ]; then
43
- dch -D $distro --force-distribution -b -v "$version-1" "new version"
45
+ $DCH -D $distro --force-distribution -b -v "$version-1" "new version"
44
46
  fi
45
47
 
46
48
  # Create tar archieve
@@ -11,12 +11,12 @@ override CPPFLAGS += -D_GNU_SOURCE \
11
11
  -Iinclude/ -include ../config-host.h \
12
12
  -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
13
13
  CFLAGS ?= -g -O3 -Wall -Wextra -fno-stack-protector
14
- override CFLAGS += -Wno-unused-parameter -Wno-sign-compare \
14
+ override CFLAGS += -Wno-unused-parameter \
15
15
  -DLIBURING_INTERNAL \
16
16
  $(LIBURING_CFLAGS)
17
17
  SO_CFLAGS=-fPIC $(CFLAGS)
18
18
  L_CFLAGS=$(CFLAGS)
19
- LINK_FLAGS=
19
+ LINK_FLAGS=-Wl,-z,defs
20
20
  LINK_FLAGS+=$(LDFLAGS)
21
21
  ENABLE_SHARED ?= 1
22
22
 
@@ -45,8 +45,8 @@ liburing_srcs := setup.c queue.c register.c syscall.c version.c
45
45
 
46
46
  ifeq ($(CONFIG_NOLIBC),y)
47
47
  liburing_srcs += nolibc.c
48
- override CFLAGS += -nostdlib -nodefaultlibs -ffreestanding
49
- override CPPFLAGS += -nostdlib -nodefaultlibs -ffreestanding
48
+ override CFLAGS += -nostdlib -nodefaultlibs -ffreestanding -fno-builtin -fno-stack-protector
49
+ override CPPFLAGS += -nostdlib -nodefaultlibs -ffreestanding -fno-builtin -fno-stack-protector
50
50
  override LINK_FLAGS += -nostdlib -nodefaultlibs
51
51
  endif
52
52
 
@@ -81,7 +81,7 @@ liburing-ffi.a: $(liburing_objs) $(liburing_ffi_objs)
81
81
  $(libname): $(liburing_sobjs) liburing.map
82
82
  $(QUIET_CC)$(CC) $(SO_CFLAGS) -shared -Wl,--version-script=liburing.map -Wl,-soname=$(soname) -o $@ $(liburing_sobjs) $(LINK_FLAGS)
83
83
 
84
- $(ffi_libname): $(liburing_ffi_objs) $(liburing_ffi_sobjs) liburing-ffi.map
84
+ $(ffi_libname): $(liburing_ffi_objs) $(liburing_ffi_sobjs) $(liburing_sobjs) liburing-ffi.map
85
85
  $(QUIET_CC)$(CC) $(SO_CFLAGS) -shared -Wl,--version-script=liburing-ffi.map -Wl,-soname=$(ffi_soname) -o $@ $(liburing_sobjs) $(liburing_ffi_sobjs) $(LINK_FLAGS)
86
86
 
87
87
  install: $(all_targets)
@@ -21,7 +21,7 @@ static inline long __get_page_size(void)
21
21
  ssize_t x;
22
22
 
23
23
  x = __sys_read(fd, buf, sizeof(buf));
24
- if (x < sizeof(buf))
24
+ if (x < (long) sizeof(buf))
25
25
  break;
26
26
 
27
27
  if (buf[0] == AT_PAGESZ) {
@@ -173,6 +173,18 @@ enum {
173
173
  */
174
174
  #define IORING_SETUP_DEFER_TASKRUN (1U << 13)
175
175
 
176
+ /*
177
+ * Application provides ring memory
178
+ */
179
+ #define IORING_SETUP_NO_MMAP (1U << 14)
180
+
181
+ /*
182
+ * Register the ring fd in itself for use with
183
+ * IORING_REGISTER_USE_REGISTERED_RING; return a registered fd index rather
184
+ * than an fd.
185
+ */
186
+ #define IORING_SETUP_REGISTERED_FD_ONLY (1U << 15)
187
+
176
188
  enum io_uring_op {
177
189
  IORING_OP_NOP,
178
190
  IORING_OP_READV,
@@ -250,6 +262,7 @@ enum io_uring_op {
250
262
  #define IORING_TIMEOUT_REALTIME (1U << 3)
251
263
  #define IORING_LINK_TIMEOUT_UPDATE (1U << 4)
252
264
  #define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5)
265
+ #define IORING_TIMEOUT_MULTISHOT (1U << 6)
253
266
  #define IORING_TIMEOUT_CLOCK_MASK (IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME)
254
267
  #define IORING_TIMEOUT_UPDATE_MASK (IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE)
255
268
  /*
@@ -389,6 +402,9 @@ enum {
389
402
  #define IORING_OFF_SQ_RING 0ULL
390
403
  #define IORING_OFF_CQ_RING 0x8000000ULL
391
404
  #define IORING_OFF_SQES 0x10000000ULL
405
+ #define IORING_OFF_PBUF_RING 0x80000000ULL
406
+ #define IORING_OFF_PBUF_SHIFT 16
407
+ #define IORING_OFF_MMAP_MASK 0xf8000000ULL
392
408
 
393
409
  /*
394
410
  * Filled with the offset for mmap(2)
@@ -402,7 +418,7 @@ struct io_sqring_offsets {
402
418
  __u32 dropped;
403
419
  __u32 array;
404
420
  __u32 resv1;
405
- __u64 resv2;
421
+ __u64 user_addr;
406
422
  };
407
423
 
408
424
  /*
@@ -421,7 +437,7 @@ struct io_cqring_offsets {
421
437
  __u32 cqes;
422
438
  __u32 flags;
423
439
  __u32 resv1;
424
- __u64 resv2;
440
+ __u64 user_addr;
425
441
  };
426
442
 
427
443
  /*
@@ -568,19 +584,6 @@ struct io_uring_rsrc_update2 {
568
584
  __u32 resv2;
569
585
  };
570
586
 
571
- struct io_uring_notification_slot {
572
- __u64 tag;
573
- __u64 resv[3];
574
- };
575
-
576
- struct io_uring_notification_register {
577
- __u32 nr_slots;
578
- __u32 resv;
579
- __u64 resv2;
580
- __u64 data;
581
- __u64 resv3;
582
- };
583
-
584
587
  /* Skip updating fd indexes set to this value in the fd table */
585
588
  #define IORING_REGISTER_FILES_SKIP (-2)
586
589
 
@@ -635,12 +638,26 @@ struct io_uring_buf_ring {
635
638
  };
636
639
  };
637
640
 
641
+ /*
642
+ * Flags for IORING_REGISTER_PBUF_RING.
643
+ *
644
+ * IOU_PBUF_RING_MMAP: If set, kernel will allocate the memory for the ring.
645
+ * The application must not set a ring_addr in struct
646
+ * io_uring_buf_reg, instead it must subsequently call
647
+ * mmap(2) with the offset set as:
648
+ * IORING_OFF_PBUF_RING | (bgid << IORING_OFF_PBUF_SHIFT)
649
+ * to get a virtual mapping for the ring.
650
+ */
651
+ enum {
652
+ IOU_PBUF_RING_MMAP = 1,
653
+ };
654
+
638
655
  /* argument for IORING_(UN)REGISTER_PBUF_RING */
639
656
  struct io_uring_buf_reg {
640
657
  __u64 ring_addr;
641
658
  __u32 ring_entries;
642
659
  __u16 bgid;
643
- __u16 pad;
660
+ __u16 flags;
644
661
  __u64 resv[3];
645
662
  };
646
663
 
@@ -698,6 +715,14 @@ struct io_uring_recvmsg_out {
698
715
  __u32 flags;
699
716
  };
700
717
 
718
+ /*
719
+ * Argument for IORING_OP_URING_CMD when file is a socket
720
+ */
721
+ enum {
722
+ SOCKET_URING_OP_SIOCINQ = 0,
723
+ SOCKET_URING_OP_SIOCOUTQ,
724
+ };
725
+
701
726
  #ifdef __cplusplus
702
727
  }
703
728
  #endif
@@ -164,6 +164,9 @@ IOURINGINLINE int io_uring_opcode_supported(const struct io_uring_probe *p,
164
164
  return (p->ops[op].flags & IO_URING_OP_SUPPORTED) != 0;
165
165
  }
166
166
 
167
+ int io_uring_queue_init_mem(unsigned entries, struct io_uring *ring,
168
+ struct io_uring_params *p,
169
+ void *buf, size_t buf_size);
167
170
  int io_uring_queue_init_params(unsigned entries, struct io_uring *ring,
168
171
  struct io_uring_params *p);
169
172
  int io_uring_queue_init(unsigned entries, struct io_uring *ring,
@@ -256,6 +259,16 @@ int io_uring_setup(unsigned int entries, struct io_uring_params *p);
256
259
  int io_uring_register(unsigned int fd, unsigned int opcode, const void *arg,
257
260
  unsigned int nr_args);
258
261
 
262
+ /*
263
+ * Mapped buffer ring alloc/register + unregister/free helpers
264
+ */
265
+ struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *ring,
266
+ unsigned int nentries,
267
+ int bgid, unsigned int flags,
268
+ int *ret);
269
+ int io_uring_free_buf_ring(struct io_uring *ring, struct io_uring_buf_ring *br,
270
+ unsigned int nentries, int bgid);
271
+
259
272
  /*
260
273
  * Helper for the peek/wait single cqe functions. Exported because of that,
261
274
  * but probably shouldn't be used directly in an application.
@@ -594,6 +607,9 @@ IOURINGINLINE void io_uring_prep_accept_direct(struct io_uring_sqe *sqe, int fd,
594
607
  unsigned int file_index)
595
608
  {
596
609
  io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
610
+ /* offset by 1 for allocation */
611
+ if (file_index == IORING_FILE_INDEX_ALLOC)
612
+ file_index--;
597
613
  __io_uring_set_target_fixed_file(sqe, file_index);
598
614
  }
599
615
 
@@ -661,7 +677,7 @@ IOURINGINLINE void io_uring_prep_files_update(struct io_uring_sqe *sqe,
661
677
  }
662
678
 
663
679
  IOURINGINLINE void io_uring_prep_fallocate(struct io_uring_sqe *sqe, int fd,
664
- int mode, off_t offset, off_t len)
680
+ int mode, __u64 offset, __u64 len)
665
681
  {
666
682
  io_uring_prep_rw(IORING_OP_FALLOCATE, sqe, fd,
667
683
  0, (unsigned int) mode, (__u64) offset);
@@ -683,6 +699,9 @@ IOURINGINLINE void io_uring_prep_openat_direct(struct io_uring_sqe *sqe,
683
699
  unsigned file_index)
684
700
  {
685
701
  io_uring_prep_openat(sqe, dfd, path, flags, mode);
702
+ /* offset by 1 for allocation */
703
+ if (file_index == IORING_FILE_INDEX_ALLOC)
704
+ file_index--;
686
705
  __io_uring_set_target_fixed_file(sqe, file_index);
687
706
  }
688
707
 
@@ -742,6 +761,23 @@ IOURINGINLINE void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd,
742
761
  sqe->msg_flags = (__u32) flags;
743
762
  }
744
763
 
764
+ IOURINGINLINE void io_uring_prep_send_set_addr(struct io_uring_sqe *sqe,
765
+ const struct sockaddr *dest_addr,
766
+ __u16 addr_len)
767
+ {
768
+ sqe->addr2 = (unsigned long)(const void *)dest_addr;
769
+ sqe->addr_len = addr_len;
770
+ }
771
+
772
+ IOURINGINLINE void io_uring_prep_sendto(struct io_uring_sqe *sqe, int sockfd,
773
+ const void *buf, size_t len, int flags,
774
+ const struct sockaddr *addr,
775
+ socklen_t addrlen)
776
+ {
777
+ io_uring_prep_send(sqe, sockfd, buf, len, flags);
778
+ io_uring_prep_send_set_addr(sqe, addr, addrlen);
779
+ }
780
+
745
781
  IOURINGINLINE void io_uring_prep_send_zc(struct io_uring_sqe *sqe, int sockfd,
746
782
  const void *buf, size_t len, int flags,
747
783
  unsigned zc_flags)
@@ -770,14 +806,6 @@ IOURINGINLINE void io_uring_prep_sendmsg_zc(struct io_uring_sqe *sqe, int fd,
770
806
  sqe->opcode = IORING_OP_SENDMSG_ZC;
771
807
  }
772
808
 
773
- IOURINGINLINE void io_uring_prep_send_set_addr(struct io_uring_sqe *sqe,
774
- const struct sockaddr *dest_addr,
775
- __u16 addr_len)
776
- {
777
- sqe->addr2 = (unsigned long)(const void *)dest_addr;
778
- sqe->addr_len = addr_len;
779
- }
780
-
781
809
  IOURINGINLINE void io_uring_prep_recv(struct io_uring_sqe *sqe, int sockfd,
782
810
  void *buf, size_t len, int flags)
783
811
  {
@@ -872,6 +900,9 @@ IOURINGINLINE void io_uring_prep_openat2_direct(struct io_uring_sqe *sqe,
872
900
  unsigned file_index)
873
901
  {
874
902
  io_uring_prep_openat2(sqe, dfd, path, how);
903
+ /* offset by 1 for allocation */
904
+ if (file_index == IORING_FILE_INDEX_ALLOC)
905
+ file_index--;
875
906
  __io_uring_set_target_fixed_file(sqe, file_index);
876
907
  }
877
908
 
@@ -1011,10 +1042,21 @@ IOURINGINLINE void io_uring_prep_msg_ring_fd(struct io_uring_sqe *sqe, int fd,
1011
1042
  io_uring_prep_rw(IORING_OP_MSG_RING, sqe, fd,
1012
1043
  (void *) (uintptr_t) IORING_MSG_SEND_FD, 0, data);
1013
1044
  sqe->addr3 = source_fd;
1045
+ /* offset by 1 for allocation */
1046
+ if ((unsigned int) target_fd == IORING_FILE_INDEX_ALLOC)
1047
+ target_fd--;
1014
1048
  __io_uring_set_target_fixed_file(sqe, target_fd);
1015
1049
  sqe->msg_ring_flags = flags;
1016
1050
  }
1017
1051
 
1052
+ IOURINGINLINE void io_uring_prep_msg_ring_fd_alloc(struct io_uring_sqe *sqe,
1053
+ int fd, int source_fd,
1054
+ __u64 data, unsigned int flags)
1055
+ {
1056
+ io_uring_prep_msg_ring_fd(sqe, fd, source_fd, IORING_FILE_INDEX_ALLOC,
1057
+ data, flags);
1058
+ }
1059
+
1018
1060
  IOURINGINLINE void io_uring_prep_getxattr(struct io_uring_sqe *sqe,
1019
1061
  const char *name, char *value,
1020
1062
  const char *path, unsigned int len)
@@ -1070,6 +1112,9 @@ IOURINGINLINE void io_uring_prep_socket_direct(struct io_uring_sqe *sqe,
1070
1112
  {
1071
1113
  io_uring_prep_rw(IORING_OP_SOCKET, sqe, domain, NULL, protocol, type);
1072
1114
  sqe->rw_flags = flags;
1115
+ /* offset by 1 for allocation */
1116
+ if (file_index == IORING_FILE_INDEX_ALLOC)
1117
+ file_index--;
1073
1118
  __io_uring_set_target_fixed_file(sqe, file_index);
1074
1119
  }
1075
1120
 
@@ -1083,6 +1128,29 @@ IOURINGINLINE void io_uring_prep_socket_direct_alloc(struct io_uring_sqe *sqe,
1083
1128
  __io_uring_set_target_fixed_file(sqe, IORING_FILE_INDEX_ALLOC - 1);
1084
1129
  }
1085
1130
 
1131
+
1132
+ #define UNUSED(x) (void)(x)
1133
+
1134
+ /*
1135
+ * Prepare commands for sockets
1136
+ */
1137
+ IOURINGINLINE void io_uring_prep_cmd_sock(struct io_uring_sqe *sqe,
1138
+ int cmd_op,
1139
+ int fd,
1140
+ int level,
1141
+ int optname,
1142
+ void *optval,
1143
+ int optlen)
1144
+ {
1145
+ /* This will be removed once the get/setsockopt() patches land */
1146
+ UNUSED(optlen);
1147
+ UNUSED(optval);
1148
+ UNUSED(level);
1149
+ UNUSED(optname);
1150
+ io_uring_prep_rw(IORING_OP_URING_CMD, sqe, fd, NULL, 0, 0);
1151
+ sqe->cmd_op = cmd_op;
1152
+ }
1153
+
1086
1154
  /*
1087
1155
  * Returns number of unconsumed (if SQPOLL) or unsubmitted entries exist in
1088
1156
  * the SQ ring
@@ -1340,6 +1408,14 @@ IOURINGINLINE void io_uring_buf_ring_advance(struct io_uring_buf_ring *br,
1340
1408
  io_uring_smp_store_release(&br->tail, new_tail);
1341
1409
  }
1342
1410
 
1411
+ IOURINGINLINE void __io_uring_buf_ring_cq_advance(struct io_uring *ring,
1412
+ struct io_uring_buf_ring *br,
1413
+ int cq_count, int buf_count)
1414
+ {
1415
+ br->tail += buf_count;
1416
+ io_uring_cq_advance(ring, cq_count);
1417
+ }
1418
+
1343
1419
  /*
1344
1420
  * Make 'count' new buffers visible to the kernel while at the same time
1345
1421
  * advancing the CQ ring seen entries. This can be used when the application
@@ -1351,8 +1427,7 @@ IOURINGINLINE void io_uring_buf_ring_cq_advance(struct io_uring *ring,
1351
1427
  struct io_uring_buf_ring *br,
1352
1428
  int count)
1353
1429
  {
1354
- br->tail += count;
1355
- io_uring_cq_advance(ring, count);
1430
+ __io_uring_buf_ring_cq_advance(ring, br, count, count);
1356
1431
  }
1357
1432
 
1358
1433
  #ifndef LIBURING_INTERNAL
@@ -5,6 +5,7 @@
5
5
  enum {
6
6
  INT_FLAG_REG_RING = 1,
7
7
  INT_FLAG_REG_REG_RING = 2,
8
+ INT_FLAG_APP_MEM = 4,
8
9
  };
9
10
 
10
11
  #endif
@@ -47,6 +47,8 @@ LIBURING_2.4 {
47
47
  io_uring_register_buf_ring;
48
48
  io_uring_unregister_buf_ring;
49
49
  io_uring_close_ring_fd;
50
+ io_uring_setup_buf_ring;
51
+ io_uring_free_buf_ring;
50
52
 
51
53
  io_uring_register_sync_cancel;
52
54
  io_uring_register_file_alloc_range;
@@ -118,6 +120,7 @@ LIBURING_2.4 {
118
120
  io_uring_recvmsg_cmsg_firsthdr;
119
121
  io_uring_prep_socket_direct;
120
122
  io_uring_buf_ring_cq_advance;
123
+ __io_uring_buf_ring_cq_advance;
121
124
  io_uring_prep_mkdir;
122
125
  io_uring_wait_cqe_nr;
123
126
  io_uring_prep_unlink;
@@ -167,6 +170,15 @@ LIBURING_2.4 {
167
170
  io_uring_prep_recv;
168
171
  io_uring_prep_msg_ring_cqe_flags;
169
172
  io_uring_prep_msg_ring_fd;
173
+ io_uring_prep_msg_ring_fd_alloc;
174
+ io_uring_prep_sendto;
175
+ io_uring_queue_init_mem;
176
+ io_uring_prep_sock_cmd;
170
177
  local:
171
178
  *;
172
179
  };
180
+
181
+ LIBURING_2.5 {
182
+ global:
183
+ io_uring_queue_init_mem;
184
+ } LIBURING_2.4;
@@ -77,4 +77,12 @@ LIBURING_2.4 {
77
77
  io_uring_close_ring_fd;
78
78
  io_uring_enable_rings;
79
79
  io_uring_register_restrictions;
80
+ io_uring_setup_buf_ring;
81
+ io_uring_free_buf_ring;
82
+ io_uring_queue_init_mem;
80
83
  } LIBURING_2.3;
84
+
85
+ LIBURING_2.5 {
86
+ global:
87
+ io_uring_queue_init_mem;
88
+ } LIBURING_2.4;
@@ -11,11 +11,16 @@
11
11
  static inline int do_register(struct io_uring *ring, unsigned int opcode,
12
12
  const void *arg, unsigned int nr_args)
13
13
  {
14
+ int fd;
15
+
14
16
  if (ring->int_flags & INT_FLAG_REG_REG_RING) {
15
17
  opcode |= IORING_REGISTER_USE_REGISTERED_RING;
16
- return __sys_io_uring_register(ring->enter_ring_fd, opcode, arg, nr_args);
18
+ fd = ring->enter_ring_fd;
19
+ } else {
20
+ fd = ring->ring_fd;
17
21
  }
18
- return __sys_io_uring_register(ring->ring_fd, opcode, arg, nr_args);
22
+
23
+ return __sys_io_uring_register(fd, opcode, arg, nr_args);
19
24
  }
20
25
 
21
26
  int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off,