The unpac monorepo manager self-hosting as a monorepo using unpac
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

vendor liburing-2.4

+6474 -1468
+14 -16
vendor/opam/uring/vendor/liburing/.github/workflows/build.yml
··· 26 26 cxx_pkg: clang 27 27 cc: clang 28 28 cxx: clang++ 29 - extra_flags: -Wshorten-64-to-32 29 + liburing_extra_flags: -Wshorten-64-to-32 30 + extra_flags: -Wmissing-prototypes -Wstrict-prototypes -Wunreachable-code-loop-increment -Wunreachable-code -Wmissing-variable-declarations -Wextra-semi-stmt 30 31 31 32 # x86 (32-bit) gcc 32 33 - arch: i686 ··· 84 85 cc: mips-linux-gnu-gcc 85 86 cxx: mips-linux-gnu-g++ 86 87 88 + # hppa 89 + - arch: hppa 90 + cc_pkg: gcc-hppa-linux-gnu 91 + cxx_pkg: g++-hppa-linux-gnu 92 + cc: hppa-linux-gnu-gcc 93 + cxx: hppa-linux-gnu-g++ 94 + 87 95 env: 88 - FLAGS: -g -O3 -Wall -Wextra -Werror 96 + FLAGS: -g -O3 -Wall -Wextra -Werror -Wno-sign-compare ${{matrix.extra_flags}} 89 97 90 98 # Flags for building sources in src/ dir only. 91 - LIBURING_CFLAGS: ${{matrix.extra_flags}} 99 + LIBURING_CFLAGS: ${{matrix.liburing_extra_flags}} 92 100 93 101 steps: 94 102 - name: Checkout source ··· 98 106 run: | 99 107 if [[ "${{matrix.cc_pkg}}" == "clang" ]]; then \ 100 108 wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh; \ 101 - sudo bash /tmp/llvm.sh 16; \ 102 - sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-16 400; \ 103 - sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-16 400; \ 109 + sudo bash /tmp/llvm.sh 17; \ 110 + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 400; \ 111 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 400; \ 104 112 else \ 105 113 sudo apt-get update -y; \ 106 114 sudo apt-get install -y ${{matrix.cc_pkg}} ${{matrix.cxx_pkg}}; \ ··· 115 123 run: | 116 124 ./configure --cc=${{matrix.cc}} --cxx=${{matrix.cxx}}; 117 125 make -j$(nproc) V=1 CPPFLAGS="-Werror" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS"; 118 - 119 - - name: Build nolibc 120 - run: | 121 - if [[ "${{matrix.arch}}" == "x86_64" || "${{matrix.arch}}" == "i686" || "${{matrix.arch}}" == "aarch64" ]]; then \ 122 - make clean; \ 123 - ./configure --cc=${{matrix.cc}} --cxx=${{matrix.cxx}} --nolibc; \ 124 - make -j$(nproc) V=1 CPPFLAGS="-Werror" CFLAGS="$FLAGS" CXXFLAGS="$FLAGS"; \ 125 - else \ 126 - echo "Skipping nolibc build, this arch doesn't support building liburing without libc"; \ 127 - fi; 128 126 129 127 - name: Test install command 130 128 run: |
+6
vendor/opam/uring/vendor/liburing/.gitignore
··· 9 9 10 10 /src/liburing.a 11 11 /src/liburing.so* 12 + /src/liburing-ffi.a 13 + /src/liburing-ffi.so* 12 14 /src/include/liburing/compat.h 15 + /src/include/liburing/io_uring_version.h 13 16 17 + /examples/io_uring-close-test 14 18 /examples/io_uring-cp 15 19 /examples/io_uring-test 16 20 /examples/io_uring-udp ··· 18 22 /examples/ucontext-cp 19 23 /examples/poll-bench 20 24 /examples/send-zerocopy 25 + /examples/rsrc-update-bench 21 26 22 27 /test/*.t 23 28 /test/*.dmesg ··· 28 33 config.log 29 34 30 35 liburing.pc 36 + liburing-ffi.pc 31 37 32 38 cscope.out
+18
vendor/opam/uring/vendor/liburing/CHANGELOG
··· 1 + liburing-2.4 release 2 + 3 + - Add io_uring_{major,minor,check}_version() functions. 4 + - Add IO_URING_{MAJOR,MINOR,CHECK}_VERSION() macros. 5 + - FFI support (for non-C/C++ languages integration). 6 + - Add io_uring_prep_msg_ring_cqe_flags() function. 7 + - Deprecate --nolibc configure option. 8 + - CONFIG_NOLIBC is always enabled on x86-64, x86, and aarch64. 9 + - Add support for IORING_REGISTER_USE_REGISTERED_RING and use if available. 10 + - Add io_uring_close_ring_fd() function. 11 + - Add io_uring_prep_msg_ring_fd_alloc function. 12 + - Add io_uring_free_buf_ring() and io_uring_setup_buf_ring() functions. 13 + - Ensure that io_uring_prep_accept_direct(), io_uring_prep_openat_direct(), 14 + io_uring_prep_openat2_direct(), io_uring_prep_msg_ring_fd(), and 15 + io_uring_prep_socket_direct() factor in being called with 16 + IORING_FILE_INDEX_ALLOC for allocating a direct descriptor. 17 + - Add io_uring_prep_sendto() function. 18 + 1 19 liburing-2.3 release 2 20 3 21 - Support non-libc build for aarch64.
+4 -3
vendor/opam/uring/vendor/liburing/Makefile
··· 25 25 @$(MAKE) -C test runtests-parallel 26 26 27 27 config-host.mak: configure 28 - @if [ ! -e "$@" ]; then \ 28 + +@if [ ! -e "$@" ]; then \ 29 29 echo "Running configure ..."; \ 30 30 ./configure; \ 31 31 else \ ··· 45 45 -e "s%@VERSION@%$(VERSION)%g" \ 46 46 $< >$@ 47 47 48 - install: $(NAME).pc 48 + install: $(NAME).pc $(NAME)-ffi.pc 49 49 @$(MAKE) -C src install prefix=$(DESTDIR)$(prefix) \ 50 50 includedir=$(DESTDIR)$(includedir) \ 51 51 libdir=$(DESTDIR)$(libdir) \ 52 52 libdevdir=$(DESTDIR)$(libdevdir) \ 53 53 relativelibdir=$(relativelibdir) 54 54 $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdevdir)/pkgconfig/$(NAME).pc 55 + $(INSTALL) -D -m 644 $(NAME)-ffi.pc $(DESTDIR)$(libdevdir)/pkgconfig/$(NAME)-ffi.pc 55 56 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man2 56 57 $(INSTALL) -m 644 man/*.2 $(DESTDIR)$(mandir)/man2 57 58 $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man3 ··· 63 64 @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) 64 65 65 66 clean: 66 - @rm -f config-host.mak config-host.h cscope.out $(NAME).pc test/*.dmesg 67 + @rm -f config-host.mak config-host.h cscope.out $(NAME).pc $(NAME)-ffi.pc test/*.dmesg 67 68 @$(MAKE) -C src clean 68 69 @$(MAKE) -C test clean 69 70 @$(MAKE) -C examples clean
+1
vendor/opam/uring/vendor/liburing/Makefile.common
··· 3 3 SPECFILE=$(TOP)/$(NAME).spec 4 4 VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) 5 5 VERSION_MAJOR=$(shell echo $(VERSION) | cut -d. -f1) 6 + VERSION_MINOR=$(shell echo $(VERSION) | cut -d. -f2) 6 7 TAG = $(NAME)-$(VERSION)
+48
vendor/opam/uring/vendor/liburing/README
··· 47 47 pass on older kernels, and may even crash or hang older kernels! 48 48 49 49 50 + Building liburing 51 + ----------------- 52 + 53 + # 54 + # Prepare build config (optional). 55 + # 56 + # --cc specifies the C compiler. 57 + # --cxx speficies the C++ compiler. 58 + # 59 + ./configure --cc=gcc --cxx=g++; 60 + 61 + # 62 + # Build liburing. 63 + # 64 + make -j$(nproc); 65 + 66 + # 67 + # Install liburing (headers, shared/static libs, and manpage). 68 + # 69 + sudo make install; 70 + 71 + See './configure --help' for more information about build config options. 72 + 73 + 74 + FFI support 75 + ----------- 76 + 77 + By default, the build results in 4 lib files: 78 + 79 + 2 shared libs: 80 + 81 + liburing.so 82 + liburing-ffi.so 83 + 84 + 2 static libs: 85 + 86 + liburing.a 87 + liburing-ffi.a 88 + 89 + Languages and applications that can't use 'static inline' functions in 90 + liburing.h should use the FFI variants. 91 + 92 + liburing's main public interface lives in liburing.h as 'static inline' 93 + functions. Users wishing to consume liburing purely as a binary dependency 94 + should link against liburing-ffi. It contains definitions for every 'static 95 + inline' function. 96 + 97 + 50 98 License 51 99 ------- 52 100
+76 -6
vendor/opam/uring/vendor/liburing/configure
··· 5 5 cc=${CC:-gcc} 6 6 cxx=${CXX:-g++} 7 7 8 + # 9 + # TODO(ammarfaizi2): Remove this notice and `--nolibc` option. 10 + # 11 + nolibc_deprecated() { 12 + echo ""; 13 + echo "================================================================="; 14 + echo ""; 15 + echo " --nolibc option is deprecated and has no effect."; 16 + echo " It will be removed in a future liburing release."; 17 + echo ""; 18 + echo " liburing on x86-64, x86 (32-bit) and aarch64 always use CONFIG_NOLIBC."; 19 + echo ""; 20 + echo "================================================================="; 21 + echo ""; 22 + } 23 + 8 24 for opt do 9 25 optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)' || true) 10 26 case "$opt" in ··· 26 42 ;; 27 43 --cxx=*) cxx="$optarg" 28 44 ;; 29 - --nolibc) liburing_nolibc="yes" 45 + --nolibc) nolibc_deprecated 30 46 ;; 31 47 *) 32 48 echo "ERROR: unknown option $opt" ··· 115 131 } 116 132 117 133 # Default CFLAGS 118 - CFLAGS="-D_GNU_SOURCE -include config-host.h" 134 + CFLAGS="-D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -include config-host.h" 119 135 BUILD_CFLAGS="" 120 136 121 137 # Print configure header at the top of $config_host_h ··· 385 401 print_config "NVMe uring command support" "$nvme_uring_cmd" 386 402 387 403 ############################################################################# 404 + # 405 + # Currently, CONFIG_NOLIBC is only enabled on x86-64, x86 (32-bit) and aarch64. 406 + # 407 + cat > $TMPC << EOF 408 + int main(void){ 409 + #if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) 410 + return 0; 411 + #else 412 + #error libc is needed 413 + #endif 414 + } 415 + EOF 416 + if compile_prog "" "" "nolibc support"; then 417 + liburing_nolibc="yes" 418 + fi 419 + print_config "nolibc support" "$liburing_nolibc"; 420 + ############################################################################# 421 + 422 + #################################################### 423 + # Most Android devices don't have sys/fanotify.h 424 + has_fanotify="no" 425 + cat > $TMPC << EOF 426 + #include <sys/fanotify.h> 427 + int main(void) 428 + { 429 + return 0; 430 + } 431 + EOF 432 + if compile_prog "" "" "fanotify"; then 433 + has_fanotify="yes" 434 + fi 435 + print_config "has_fanotify" "$has_fanotify" 436 + #################################################### 437 + 388 438 if test "$liburing_nolibc" = "yes"; then 389 439 output_sym "CONFIG_NOLIBC" 390 - else 391 - liburing_nolibc="no" 392 440 fi 393 - print_config "liburing_nolibc" "$liburing_nolibc" 394 - 395 441 if test "$__kernel_rwf_t" = "yes"; then 396 442 output_sym "CONFIG_HAVE_KERNEL_RWF_T" 397 443 fi ··· 422 468 if test "$nvme_uring_cmd" = "yes"; then 423 469 output_sym "CONFIG_HAVE_NVME_URING" 424 470 fi 471 + if test "$has_fanotify" = "yes"; then 472 + output_sym "CONFIG_HAVE_FANOTIFY" 473 + fi 425 474 426 475 echo "CC=$cc" >> $config_host_mak 427 476 print_config "CC" "$cc" 428 477 echo "CXX=$cxx" >> $config_host_mak 429 478 print_config "CXX" "$cxx" 430 479 480 + # generate io_uring_version.h 481 + MAKE_PRINT_VARS="include Makefile.common\nprint-%: ; @echo \$(\$*)\n" 482 + VERSION_MAJOR=$(env echo -e "$MAKE_PRINT_VARS" | make -s --no-print-directory -f - print-VERSION_MAJOR) 483 + VERSION_MINOR=$(env echo -e "$MAKE_PRINT_VARS" | make -s --no-print-directory -f - print-VERSION_MINOR) 484 + io_uring_version_h="src/include/liburing/io_uring_version.h" 485 + cat > $io_uring_version_h << EOF 486 + /* SPDX-License-Identifier: MIT */ 487 + #ifndef LIBURING_VERSION_H 488 + #define LIBURING_VERSION_H 489 + 490 + #define IO_URING_VERSION_MAJOR $VERSION_MAJOR 491 + #define IO_URING_VERSION_MINOR $VERSION_MINOR 492 + 493 + #endif 494 + EOF 495 + 431 496 # generate compat.h 432 497 compat_h="src/include/liburing/compat.h" 433 498 cat > $compat_h << EOF ··· 452 517 long long tv_nsec; 453 518 }; 454 519 520 + /* <linux/time_types.h> is not available, so it can't be included */ 521 + #define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 1 522 + 455 523 EOF 456 524 else 457 525 cat >> $compat_h << EOF 458 526 #include <linux/time_types.h> 527 + /* <linux/time_types.h> is included above and not needed again */ 528 + #define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 1 459 529 460 530 EOF 461 531 fi
+11
vendor/opam/uring/vendor/liburing/debian/changelog
··· 1 + liburing (2.2-1) stable; urgency=low 2 + 3 + * Update to 2.2 4 + * Bump up so version to 2 5 + * Drop liburing1-udeb 6 + * Package using dh instead of using dh_* helpers manually 7 + * Add linux header dependency to liburing-dev 8 + * Bump up debhelper-compact level to 13 9 + 10 + -- Kefu Chai <tchaikov@gmail.com> Sun, 16 Oct 2022 16:30:48 +0800 11 + 1 12 liburing (0.7-1) stable; urgency=low 2 13 3 14 * Update to 0.7
-1
vendor/opam/uring/vendor/liburing/debian/compat
··· 1 - 9
+7 -16
vendor/opam/uring/vendor/liburing/debian/control
··· 2 2 Section: libs 3 3 Priority: optional 4 4 Maintainer: Liu Changcheng <changcheng.liu@intel.com> 5 - Build-Depends: debhelper (>=9) 5 + Build-Depends: 6 + debhelper-compat (= 13) 6 7 Standards-Version: 4.1.4 7 8 Homepage: https://git.kernel.dk/cgit/liburing/tree/README 8 9 Vcs-Git: https://git.kernel.dk/liburing 9 10 Vcs-Browser: https://git.kernel.dk/cgit/liburing/ 10 11 11 - Package: liburing1 12 + Package: liburing2 12 13 Architecture: linux-any 13 14 Multi-Arch: same 14 15 Pre-Depends: ${misc:Pre-Depends} ··· 21 22 . 22 23 This package contains the shared library. 23 24 24 - Package: liburing1-udeb 25 - Package-Type: udeb 26 - Section: debian-installer 27 - Architecture: linux-any 28 - Depends: ${misc:Depends}, ${shlibs:Depends}, 29 - Description: userspace library for using io_uring 30 - io_uring is kernel feature to improve development 31 - The newese Linux IO interface, io_uring could improve 32 - system performance a lot. liburing is the userpace 33 - library to use io_uring feature. 34 - . 35 - This package contains the udeb shared library. 36 - 37 25 Package: liburing-dev 38 26 Section: libdevel 39 27 Architecture: linux-any 40 28 Multi-Arch: same 41 - Depends: ${misc:Depends}, liburing1 (= ${binary:Version}), 29 + Depends: 30 + ${misc:Depends}, 31 + liburing2 (= ${binary:Version}), 32 + linux-libc-dev (>= 5.1) 42 33 Description: userspace library for using io_uring 43 34 io_uring is kernel feature to improve development 44 35 The newese Linux IO interface, io_uring could improve
+3 -6
vendor/opam/uring/vendor/liburing/debian/liburing-dev.manpages
··· 1 - man/io_uring_setup.2 2 - man/io_uring_enter.2 3 - man/io_uring_register.2 4 - man/io_uring_queue_exit.3 5 - man/io_uring_queue_init.3 6 - man/io_uring_get_sqe.3 1 + usr/share/man/man2/io_uring_*.2 2 + usr/share/man/man3/io_uring_*.3 3 + usr/share/man/man7/io_uring.7
-1
vendor/opam/uring/vendor/liburing/debian/liburing1-udeb.install
··· 1 - lib/*/lib*.so.*
-1
vendor/opam/uring/vendor/liburing/debian/liburing1.install
··· 1 - lib/*/lib*.so.*
-32
vendor/opam/uring/vendor/liburing/debian/liburing1.symbols
··· 1 - liburing.so.1 liburing1 #MINVER# 2 - (symver)LIBURING_0.1 0.1-1 3 - io_uring_get_sqe@LIBURING_0.1 0.1-1 4 - io_uring_queue_exit@LIBURING_0.1 0.1-1 5 - io_uring_queue_init@LIBURING_0.1 0.1-1 6 - io_uring_queue_mmap@LIBURING_0.1 0.1-1 7 - io_uring_register_buffers@LIBURING_0.1 0.1-1 8 - io_uring_register_eventfd@LIBURING_0.1 0.1-1 9 - io_uring_register_eventfd_async@LIBURING_0.6 0.6-1 10 - io_uring_register_files@LIBURING_0.1 0.1-1 11 - io_uring_submit@LIBURING_0.1 0.1-1 12 - io_uring_submit_and_wait@LIBURING_0.1 0.1-1 13 - io_uring_unregister_buffers@LIBURING_0.1 0.1-1 14 - io_uring_unregister_files@LIBURING_0.1 0.1-1 15 - (symver)LIBURING_0.2 0.2-1 16 - __io_uring_get_cqe@LIBURING_0.2 0.2-1 17 - io_uring_queue_init_params@LIBURING_0.2 0.2-1 18 - io_uring_register_files_update@LIBURING_0.2 0.2-1 19 - io_uring_peek_batch_cqe@LIBURING_0.2 0.2-1 20 - io_uring_wait_cqe_timeout@LIBURING_0.2 0.2-1 21 - io_uring_wait_cqes@LIBURING_0.2 0.2-1 22 - (symver)LIBURING_0.3 0.3-1 23 - (symver)LIBURING_0.4 0.4-1 24 - (symver)LIBURING_0.5 0.5-1 25 - (symver)LIBURING_0.6 0.6-1 26 - (symver)LIBURING_0.7 0.7-1 27 - io_uring_get_probe@LIBURING_0.4 0.4-1 28 - io_uring_get_probe_ring@LIBURING_0.4 0.4-1 29 - io_uring_register_personality@LIBURING_0.4 0.4-1 30 - io_uring_register_probe@LIBURING_0.4 0.4-1 31 - io_uring_ring_dontfork@LIBURING_0.4 0.4-1 32 - io_uring_unregister_personality@LIBURING_0.4 0.4-1
+1
vendor/opam/uring/vendor/liburing/debian/liburing2.install
··· 1 + usr/lib/*/lib*.so.*
+56
vendor/opam/uring/vendor/liburing/debian/liburing2.symbols
··· 1 + liburing.so.2 liburing2 #MINVER# [47/1887] 2 + LIBURING_2.0@LIBURING_2.0 0.7-1 3 + LIBURING_2.1@LIBURING_2.1 0.7-1 4 + LIBURING_2.2@LIBURING_2.2 0.7-1 5 + LIBURING_2.3@LIBURING_2.3 0.7-1 6 + __io_uring_get_cqe@LIBURING_2.0 0.7-1 7 + __io_uring_sqring_wait@LIBURING_2.0 0.7-1 8 + io_uring_enter2@LIBURING_2.3 0.7-1 9 + io_uring_enter@LIBURING_2.3 0.7-1 10 + io_uring_free_probe@LIBURING_2.0 0.7-1 11 + io_uring_get_events@LIBURING_2.3 0.7-1 12 + io_uring_get_probe@LIBURING_2.0 0.7-1 13 + io_uring_get_probe_ring@LIBURING_2.0 0.7-1 14 + io_uring_get_sqe@LIBURING_2.0 0.7-1 15 + io_uring_mlock_size@LIBURING_2.1 0.7-1 16 + io_uring_mlock_size_params@LIBURING_2.1 0.7-1 17 + io_uring_peek_batch_cqe@LIBURING_2.0 0.7-1 18 + io_uring_queue_exit@LIBURING_2.0 0.7-1 19 + io_uring_queue_init@LIBURING_2.0 0.7-1 20 + io_uring_queue_init_params@LIBURING_2.0 0.7-1 21 + io_uring_queue_mmap@LIBURING_2.0 0.7-1 22 + io_uring_register@LIBURING_2.3 0.7-1 23 + io_uring_register_buf_ring@LIBURING_2.2 0.7-1 24 + io_uring_register_buffers@LIBURING_2.0 0.7-1 25 + io_uring_register_buffers_sparse@LIBURING_2.2 0.7-1 26 + io_uring_register_buffers_tags@LIBURING_2.1 0.7-1 27 + io_uring_register_buffers_update_tag@LIBURING_2.1 0.7-1 28 + io_uring_register_eventfd@LIBURING_2.0 0.7-1 29 + io_uring_register_eventfd_async@LIBURING_2.0 0.7-1 30 + io_uring_register_file_alloc_range@LIBURING_2.3 0.7-1 31 + io_uring_register_files@LIBURING_2.0 0.7-1 32 + io_uring_register_files_sparse@LIBURING_2.2 0.7-1 33 + io_uring_register_files_tags@LIBURING_2.1 0.7-1 34 + io_uring_register_files_update@LIBURING_2.0 0.7-1 35 + io_uring_register_files_update_tag@LIBURING_2.1 0.7-1 36 + io_uring_register_iowq_aff@LIBURING_2.1 0.7-1 37 + io_uring_register_iowq_max_workers@LIBURING_2.1 0.7-1 38 + io_uring_register_personality@LIBURING_2.0 0.7-1 39 + io_uring_register_probe@LIBURING_2.0 0.7-1 40 + io_uring_register_ring_fd@LIBURING_2.2 0.7-1 41 + io_uring_register_sync_cancel@LIBURING_2.3 0.7-1 42 + io_uring_ring_dontfork@LIBURING_2.0 0.7-1 43 + io_uring_setup@LIBURING_2.3 0.7-1 44 + io_uring_submit@LIBURING_2.0 0.7-1 45 + io_uring_submit_and_get_events@LIBURING_2.3 0.7-1 46 + io_uring_submit_and_wait@LIBURING_2.0 0.7-1 47 + io_uring_submit_and_wait_timeout@LIBURING_2.2 0.7-1 48 + io_uring_unregister_buf_ring@LIBURING_2.2 0.7-1 49 + io_uring_unregister_buffers@LIBURING_2.0 0.7-1 50 + io_uring_unregister_eventfd@LIBURING_2.0 0.7-1 51 + io_uring_unregister_files@LIBURING_2.0 0.7-1 52 + io_uring_unregister_iowq_aff@LIBURING_2.1 0.7-1 53 + io_uring_unregister_personality@LIBURING_2.0 0.7-1 54 + io_uring_unregister_ring_fd@LIBURING_2.2 0.7-1 55 + io_uring_wait_cqe_timeout@LIBURING_2.0 0.7-1 56 + io_uring_wait_cqes@LIBURING_2.0 0.7-1
+13 -66
vendor/opam/uring/vendor/liburing/debian/rules
··· 9 9 include /usr/share/dpkg/default.mk 10 10 include /usr/share/dpkg/buildtools.mk 11 11 12 - export CC 13 - 14 - lib := liburing1 15 - libdbg := $(lib)-dbg 16 - libudeb := $(lib)-udeb 17 - libdev := liburing-dev 18 - 19 - build-indep: 20 - 21 - build-arch: 22 - dh_testdir 23 - 24 - $(MAKE) CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" 25 - 26 - build: build-indep build-arch 27 - 28 - clean: 29 - dh_testdir 30 - dh_testroot 31 - 32 - $(MAKE) clean 33 - 34 - dh_clean 12 + %: 13 + dh $@ 35 14 36 - check-arch: build-arch 37 - dh_testdir 15 + override_dh_auto_configure: 16 + ./configure \ 17 + --prefix=/usr \ 18 + --includedir=/usr/include \ 19 + --datadir=/usr/share \ 20 + --mandir=/usr/share/man \ 21 + --libdir=/usr/lib/$(DEB_HOST_MULTIARCH) \ 22 + --libdevdir=/usr/lib/$(DEB_HOST_MULTIARCH) \ 23 + --cc=$(CC) 38 24 25 + override_dh_auto_test: 39 26 ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) 40 - $(MAKE) CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \ 41 - partcheck 27 + $(MAKE) runtests 42 28 endif 43 - 44 - install-arch: check-arch 45 - dh_testdir 46 - dh_testroot 47 - dh_clean 48 - dh_installdirs 49 - 50 - $(MAKE) install \ 51 - DESTDIR=$(CURDIR)/debian/tmp \ 52 - libdir=/lib/$(DEB_HOST_MULTIARCH) \ 53 - libdevdir=/usr/lib/$(DEB_HOST_MULTIARCH) \ 54 - relativelibdir=/lib/$(DEB_HOST_MULTIARCH)/ 55 - 56 - binary: binary-indep binary-arch 57 - 58 - binary-indep: 59 - # Nothing to do. 60 - 61 - binary-arch: install-arch 62 - dh_testdir 63 - dh_testroot 64 - dh_install -a 65 - dh_installdocs -a 66 - dh_installexamples -a 67 - dh_installman -a 68 - dh_lintian -a 69 - dh_link -a 70 - dh_strip -a --ddeb-migration='$(libdbg) (<< 0.3)' 71 - dh_compress -a 72 - dh_fixperms -a 73 - dh_makeshlibs -a --add-udeb '$(libudeb)' 74 - dh_shlibdeps -a 75 - dh_installdeb -a 76 - dh_gencontrol -a 77 - dh_md5sums -a 78 - dh_builddeb -a 79 - 80 - .PHONY: clean build-indep build-arch build 81 - .PHONY: install-arch binary-indep binary-arch binary
+6 -1
vendor/opam/uring/vendor/liburing/examples/Makefile
··· 10 10 include ../config-host.mak 11 11 endif 12 12 13 + LDFLAGS ?= 14 + override LDFLAGS += -L../src/ -luring -lpthread 15 + 13 16 example_srcs := \ 17 + io_uring-close-test.c \ 14 18 io_uring-cp.c \ 15 19 io_uring-test.c \ 16 20 io_uring-udp.c \ 17 21 link-cp.c \ 18 22 poll-bench.c \ 19 - send-zerocopy.c 23 + send-zerocopy.c \ 24 + rsrc-update-bench.c 20 25 21 26 all_targets := 22 27
+123
vendor/opam/uring/vendor/liburing/examples/io_uring-close-test.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Simple app that demonstrates how to setup an io_uring interface, and use it 4 + * via a registered ring fd, without leaving the original fd open. 5 + * 6 + * gcc -Wall -O2 -D_GNU_SOURCE -o io_uring-close-test io_uring-close-test.c -luring 7 + */ 8 + #include <stdio.h> 9 + #include <fcntl.h> 10 + #include <string.h> 11 + #include <stdlib.h> 12 + #include <sys/types.h> 13 + #include <sys/stat.h> 14 + #include <unistd.h> 15 + #include "liburing.h" 16 + 17 + #define QD 4 18 + 19 + int main(int argc, char *argv[]) 20 + { 21 + struct io_uring ring; 22 + int i, fd, ret, pending, done; 23 + struct io_uring_sqe *sqe; 24 + struct io_uring_cqe *cqe; 25 + struct iovec *iovecs; 26 + struct stat sb; 27 + ssize_t fsize; 28 + off_t offset; 29 + void *buf; 30 + 31 + if (argc < 2) { 32 + printf("%s: file\n", argv[0]); 33 + return 1; 34 + } 35 + 36 + ret = io_uring_queue_init(QD, &ring, 0); 37 + if (ret < 0) { 38 + fprintf(stderr, "queue_init: %s\n", strerror(-ret)); 39 + return 1; 40 + } 41 + 42 + ret = io_uring_register_ring_fd(&ring); 43 + if (ret < 0) { 44 + fprintf(stderr, "register_ring_fd: %s\n", strerror(-ret)); 45 + return 1; 46 + } 47 + ret = io_uring_close_ring_fd(&ring); 48 + if (ret < 0) { 49 + fprintf(stderr, "close_ring_fd: %s\n", strerror(-ret)); 50 + return 1; 51 + } 52 + 53 + fd = open(argv[1], O_RDONLY); 54 + if (fd < 0) { 55 + perror("open"); 56 + return 1; 57 + } 58 + 59 + if (fstat(fd, &sb) < 0) { 60 + perror("fstat"); 61 + return 1; 62 + } 63 + 64 + fsize = 0; 65 + iovecs = calloc(QD, sizeof(struct iovec)); 66 + for (i = 0; i < QD; i++) { 67 + if (posix_memalign(&buf, 4096, 4096)) 68 + return 1; 69 + iovecs[i].iov_base = buf; 70 + iovecs[i].iov_len = 4096; 71 + fsize += 4096; 72 + } 73 + 74 + offset = 0; 75 + i = 0; 76 + do { 77 + sqe = io_uring_get_sqe(&ring); 78 + if (!sqe) 79 + break; 80 + io_uring_prep_readv(sqe, fd, &iovecs[i], 1, offset); 81 + offset += iovecs[i].iov_len; 82 + i++; 83 + if (offset > sb.st_size) 84 + break; 85 + } while (1); 86 + 87 + ret = io_uring_submit(&ring); 88 + if (ret < 0) { 89 + fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret)); 90 + return 1; 91 + } else if (ret != i) { 92 + fprintf(stderr, "io_uring_submit submitted less %d\n", ret); 93 + return 1; 94 + } 95 + 96 + done = 0; 97 + pending = ret; 98 + fsize = 0; 99 + for (i = 0; i < pending; i++) { 100 + ret = io_uring_wait_cqe(&ring, &cqe); 101 + if (ret < 0) { 102 + fprintf(stderr, "io_uring_wait_cqe: %s\n", strerror(-ret)); 103 + return 1; 104 + } 105 + 106 + done++; 107 + ret = 0; 108 + if (cqe->res != 4096 && cqe->res + fsize != sb.st_size) { 109 + fprintf(stderr, "ret=%d, wanted 4096\n", cqe->res); 110 + ret = 1; 111 + } 112 + fsize += cqe->res; 113 + io_uring_cqe_seen(&ring, cqe); 114 + if (ret) 115 + break; 116 + } 117 + 118 + printf("Submitted=%d, completed=%d, bytes=%lu\n", pending, done, 119 + (unsigned long) fsize); 120 + close(fd); 121 + io_uring_queue_exit(&ring); 122 + return 0; 123 + }
+11 -3
vendor/opam/uring/vendor/liburing/examples/io_uring-udp.c
··· 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, 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 }
+100
vendor/opam/uring/vendor/liburing/examples/rsrc-update-bench.c
··· 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 + }
+315 -56
vendor/opam/uring/vendor/liburing/examples/send-zerocopy.c
··· 5 5 #include <stdint.h> 6 6 #include <assert.h> 7 7 #include <errno.h> 8 - #include <error.h> 9 8 #include <limits.h> 10 9 #include <fcntl.h> 11 10 #include <unistd.h> 12 11 #include <stdbool.h> 12 + #include <stdarg.h> 13 13 #include <string.h> 14 + #include <pthread.h> 14 15 16 + #include <poll.h> 17 + #include <sched.h> 15 18 #include <arpa/inet.h> 16 - #include <linux/errqueue.h> 17 19 #include <linux/if_packet.h> 18 20 #include <linux/ipv6.h> 19 21 #include <linux/socket.h> ··· 35 37 #include <sys/time.h> 36 38 #include <sys/types.h> 37 39 #include <sys/wait.h> 40 + #include <sys/mman.h> 41 + #include <linux/mman.h> 38 42 39 43 #include "liburing.h" 40 44 41 45 #define ZC_TAG 0xfffffffULL 42 46 #define MAX_SUBMIT_NR 512 47 + #define MAX_THREADS 100 48 + 49 + struct thread_data { 50 + pthread_t thread; 51 + void *ret; 52 + int idx; 53 + unsigned long long packets; 54 + unsigned long long bytes; 55 + struct sockaddr_storage dst_addr; 56 + int fd; 57 + }; 43 58 44 59 static bool cfg_reg_ringfd = true; 45 60 static bool cfg_fixed_files = 1; 46 61 static bool cfg_zc = 1; 47 62 static int cfg_nr_reqs = 8; 48 63 static bool cfg_fixed_buf = 1; 64 + static bool cfg_hugetlb = 0; 65 + static bool cfg_defer_taskrun = 0; 66 + static int cfg_cpu = -1; 67 + static bool cfg_rx = 0; 68 + static unsigned cfg_nr_threads = 1; 49 69 50 70 static int cfg_family = PF_UNSPEC; 71 + static int cfg_type = 0; 51 72 static int cfg_payload_len; 52 73 static int cfg_port = 8000; 53 74 static int cfg_runtime_ms = 4200; 54 75 55 76 static socklen_t cfg_alen; 56 - static struct sockaddr_storage cfg_dst_addr; 77 + static char *str_addr = NULL; 78 + 79 + static char payload_buf[IP_MAXPACKET] __attribute__((aligned(4096))); 80 + static char *payload; 81 + static struct thread_data threads[MAX_THREADS]; 82 + static pthread_barrier_t barrier; 83 + 84 + /* 85 + * Implementation of error(3), prints an error message and exits. 86 + */ 87 + static void t_error(int status, int errnum, const char *format, ...) 88 + { 89 + va_list args; 90 + va_start(args, format); 91 + 92 + vfprintf(stderr, format, args); 93 + if (errnum) 94 + fprintf(stderr, ": %s", strerror(errnum)); 95 + 96 + fprintf(stderr, "\n"); 97 + va_end(args); 98 + exit(status); 99 + } 100 + 101 + static void set_cpu_affinity(void) 102 + { 103 + cpu_set_t mask; 104 + 105 + if (cfg_cpu == -1) 106 + return; 107 + 108 + CPU_ZERO(&mask); 109 + CPU_SET(cfg_cpu, &mask); 110 + if (sched_setaffinity(0, sizeof(mask), &mask)) 111 + t_error(1, errno, "unable to pin cpu\n"); 112 + } 113 + 114 + static void set_iowq_affinity(struct io_uring *ring) 115 + { 116 + cpu_set_t mask; 117 + int ret; 57 118 58 - static char payload[IP_MAXPACKET] __attribute__((aligned(4096))); 119 + if (cfg_cpu == -1) 120 + return; 121 + 122 + ret = io_uring_register_iowq_aff(ring, 1, &mask); 123 + if (ret) 124 + t_error(1, ret, "unabled to set io-wq affinity\n"); 125 + } 59 126 60 127 static unsigned long gettimeofday_ms(void) 61 128 { ··· 68 135 static void do_setsockopt(int fd, int level, int optname, int val) 69 136 { 70 137 if (setsockopt(fd, level, optname, &val, sizeof(val))) 71 - error(1, errno, "setsockopt %d.%d: %d", level, optname, val); 138 + t_error(1, errno, "setsockopt %d.%d: %d", level, optname, val); 72 139 } 73 140 74 141 static void setup_sockaddr(int domain, const char *str_addr, ··· 76 143 { 77 144 struct sockaddr_in6 *addr6 = (void *) sockaddr; 78 145 struct sockaddr_in *addr4 = (void *) sockaddr; 146 + int port = cfg_port; 79 147 80 148 switch (domain) { 81 149 case PF_INET: 82 150 memset(addr4, 0, sizeof(*addr4)); 83 151 addr4->sin_family = AF_INET; 84 - addr4->sin_port = htons(cfg_port); 152 + addr4->sin_port = htons(port); 85 153 if (str_addr && 86 154 inet_pton(AF_INET, str_addr, &(addr4->sin_addr)) != 1) 87 - error(1, 0, "ipv4 parse error: %s", str_addr); 155 + t_error(1, 0, "ipv4 parse error: %s", str_addr); 88 156 break; 89 157 case PF_INET6: 90 158 memset(addr6, 0, sizeof(*addr6)); 91 159 addr6->sin6_family = AF_INET6; 92 - addr6->sin6_port = htons(cfg_port); 160 + addr6->sin6_port = htons(port); 93 161 if (str_addr && 94 162 inet_pton(AF_INET6, str_addr, &(addr6->sin6_addr)) != 1) 95 - error(1, 0, "ipv6 parse error: %s", str_addr); 163 + t_error(1, 0, "ipv6 parse error: %s", str_addr); 96 164 break; 97 165 default: 98 - error(1, 0, "illegal domain"); 166 + t_error(1, 0, "illegal domain"); 99 167 } 100 168 } 101 169 102 - static int do_setup_tx(int domain, int type, int protocol) 170 + static int do_poll(int fd, int events) 103 171 { 104 - int fd; 172 + struct pollfd pfd; 173 + int ret; 174 + 175 + pfd.events = events; 176 + pfd.revents = 0; 177 + pfd.fd = fd; 178 + 179 + ret = poll(&pfd, 1, -1); 180 + if (ret == -1) 181 + t_error(1, errno, "poll"); 182 + 183 + return ret && (pfd.revents & events); 184 + } 185 + 186 + /* Flush all outstanding bytes for the tcp receive queue */ 187 + static int do_flush_tcp(struct thread_data *td, int fd) 188 + { 189 + int ret; 190 + 191 + /* MSG_TRUNC flushes up to len bytes */ 192 + ret = recv(fd, NULL, 1 << 21, MSG_TRUNC | MSG_DONTWAIT); 193 + if (ret == -1 && errno == EAGAIN) 194 + return 0; 195 + if (ret == -1) 196 + t_error(1, errno, "flush"); 197 + if (!ret) 198 + return 1; 199 + 200 + td->packets++; 201 + td->bytes += ret; 202 + return 0; 203 + } 204 + 205 + /* Flush all outstanding datagrams. Verify first few bytes of each. */ 206 + static int do_flush_datagram(struct thread_data *td, int fd) 207 + { 208 + long ret, off = 0; 209 + char buf[64]; 210 + 211 + /* MSG_TRUNC will return full datagram length */ 212 + ret = recv(fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_TRUNC); 213 + if (ret == -1 && errno == EAGAIN) 214 + return 0; 215 + 216 + if (ret == -1) 217 + t_error(1, errno, "recv"); 218 + if (ret != cfg_payload_len) 219 + t_error(1, 0, "recv: ret=%u != %u", ret, cfg_payload_len); 220 + if ((unsigned long) ret > sizeof(buf) - off) 221 + ret = sizeof(buf) - off; 222 + if (memcmp(buf + off, payload, ret)) 223 + t_error(1, 0, "recv: data mismatch"); 224 + 225 + td->packets++; 226 + td->bytes += cfg_payload_len; 227 + return 0; 228 + } 229 + 230 + static void do_setup_rx(int domain, int type, int protocol) 231 + { 232 + struct sockaddr_storage addr = {}; 233 + struct thread_data *td; 234 + int listen_fd, fd; 235 + unsigned int i; 105 236 106 237 fd = socket(domain, type, protocol); 107 238 if (fd == -1) 108 - error(1, errno, "socket t"); 239 + t_error(1, errno, "socket r"); 240 + 241 + do_setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, 1); 242 + 243 + setup_sockaddr(cfg_family, str_addr, &addr); 244 + 245 + if (bind(fd, (void *)&addr, cfg_alen)) 246 + t_error(1, errno, "bind"); 247 + 248 + if (type != SOCK_STREAM) { 249 + if (cfg_nr_threads != 1) 250 + t_error(1, 0, "udp rx cant multithread"); 251 + threads[0].fd = fd; 252 + return; 253 + } 254 + 255 + listen_fd = fd; 256 + if (listen(listen_fd, cfg_nr_threads)) 257 + t_error(1, errno, "listen"); 258 + 259 + for (i = 0; i < cfg_nr_threads; i++) { 260 + td = &threads[i]; 261 + 262 + fd = accept(listen_fd, NULL, NULL); 263 + if (fd == -1) 264 + t_error(1, errno, "accept"); 265 + td->fd = fd; 266 + } 267 + 268 + if (close(listen_fd)) 269 + t_error(1, errno, "close listen sock"); 270 + } 109 271 110 - do_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, 1 << 21); 272 + static void *do_rx(void *arg) 273 + { 274 + struct thread_data *td = arg; 275 + const int cfg_receiver_wait_ms = 400; 276 + uint64_t tstop; 277 + int ret, fd = td->fd; 111 278 112 - if (connect(fd, (void *) &cfg_dst_addr, cfg_alen)) 113 - error(1, errno, "connect"); 114 - return fd; 279 + tstop = gettimeofday_ms() + cfg_runtime_ms + cfg_receiver_wait_ms; 280 + do { 281 + if (cfg_type == SOCK_STREAM) 282 + ret = do_flush_tcp(td, fd); 283 + else 284 + ret = do_flush_datagram(td, fd); 285 + 286 + if (ret) 287 + break; 288 + 289 + do_poll(fd, POLLIN); 290 + } while (gettimeofday_ms() < tstop); 291 + 292 + if (close(fd)) 293 + t_error(1, errno, "close"); 294 + pthread_exit(&td->ret); 295 + return NULL; 115 296 } 116 297 117 298 static inline struct io_uring_cqe *wait_cqe_fast(struct io_uring *ring) ··· 125 306 126 307 ret = io_uring_wait_cqe(ring, &cqe); 127 308 if (ret) 128 - error(1, ret, "wait cqe"); 309 + t_error(1, ret, "wait cqe"); 129 310 return cqe; 130 311 } 131 312 132 - static void do_tx(int domain, int type, int protocol) 313 + static void do_tx(struct thread_data *td, int domain, int type, int protocol) 133 314 { 134 - unsigned long packets = 0; 135 - unsigned long bytes = 0; 315 + const int notif_slack = 128; 136 316 struct io_uring ring; 137 317 struct iovec iov; 138 318 uint64_t tstop; 139 319 int i, fd, ret; 140 320 int compl_cqes = 0; 321 + int ring_flags = IORING_SETUP_COOP_TASKRUN | IORING_SETUP_SINGLE_ISSUER; 141 322 142 - fd = do_setup_tx(domain, type, protocol); 323 + if (cfg_defer_taskrun) 324 + ring_flags |= IORING_SETUP_DEFER_TASKRUN; 325 + 326 + fd = socket(domain, type, protocol); 327 + if (fd == -1) 328 + t_error(1, errno, "socket t"); 329 + 330 + if (connect(fd, (void *)&td->dst_addr, cfg_alen)) 331 + t_error(1, errno, "connect, idx %i", td->idx); 143 332 144 - ret = io_uring_queue_init(512, &ring, IORING_SETUP_COOP_TASKRUN); 333 + ret = io_uring_queue_init(512, &ring, ring_flags); 145 334 if (ret) 146 - error(1, ret, "io_uring: queue init"); 335 + t_error(1, ret, "io_uring: queue init"); 336 + 337 + set_cpu_affinity(); 338 + set_iowq_affinity(&ring); 147 339 148 340 if (cfg_fixed_files) { 149 341 ret = io_uring_register_files(&ring, &fd, 1); 150 342 if (ret < 0) 151 - error(1, ret, "io_uring: files registration"); 343 + t_error(1, ret, "io_uring: files registration"); 152 344 } 153 345 if (cfg_reg_ringfd) { 154 346 ret = io_uring_register_ring_fd(&ring); 155 347 if (ret < 0) 156 - error(1, ret, "io_uring: io_uring_register_ring_fd"); 348 + t_error(1, ret, "io_uring: io_uring_register_ring_fd"); 157 349 } 158 350 159 351 iov.iov_base = payload; ··· 161 353 162 354 ret = io_uring_register_buffers(&ring, &iov, 1); 163 355 if (ret) 164 - error(1, ret, "io_uring: buffer registration"); 356 + t_error(1, ret, "io_uring: buffer registration"); 357 + 358 + pthread_barrier_wait(&barrier); 165 359 166 360 tstop = gettimeofday_ms() + cfg_runtime_ms; 167 361 do { ··· 191 385 } 192 386 } 193 387 194 - ret = io_uring_submit(&ring); 388 + if (cfg_defer_taskrun && compl_cqes >= notif_slack) 389 + ret = io_uring_submit_and_get_events(&ring); 390 + else 391 + ret = io_uring_submit(&ring); 392 + 195 393 if (ret != cfg_nr_reqs) 196 - error(1, ret, "submit"); 394 + t_error(1, ret, "submit"); 197 395 198 396 for (i = 0; i < cfg_nr_reqs; i++) { 199 397 cqe = wait_cqe_fast(&ring); 200 398 201 399 if (cqe->flags & IORING_CQE_F_NOTIF) { 202 400 if (cqe->flags & IORING_CQE_F_MORE) 203 - error(1, -EINVAL, "F_MORE notif"); 401 + t_error(1, -EINVAL, "F_MORE notif"); 204 402 compl_cqes--; 205 403 i--; 206 404 io_uring_cqe_seen(&ring, cqe); ··· 210 408 compl_cqes++; 211 409 212 410 if (cqe->res >= 0) { 213 - packets++; 214 - bytes += cqe->res; 411 + td->packets++; 412 + td->bytes += cqe->res; 215 413 } else if (cqe->res == -ECONNREFUSED || cqe->res == -EPIPE || 216 414 cqe->res == -ECONNRESET) { 217 - fprintf(stderr, "Connection failure"); 415 + fprintf(stderr, "Connection failure\n"); 218 416 goto out_fail; 219 417 } else if (cqe->res != -EAGAIN) { 220 - error(1, cqe->res, "send failed"); 418 + t_error(1, cqe->res, "send failed"); 221 419 } 222 420 io_uring_cqe_seen(&ring, cqe); 223 421 } ··· 226 424 out_fail: 227 425 shutdown(fd, SHUT_RDWR); 228 426 if (close(fd)) 229 - error(1, errno, "close"); 230 - 231 - fprintf(stderr, "tx=%lu (MB=%lu), tx/s=%lu (MB/s=%lu)\n", 232 - packets, bytes >> 20, 233 - packets / (cfg_runtime_ms / 1000), 234 - (bytes >> 20) / (cfg_runtime_ms / 1000)); 427 + t_error(1, errno, "close"); 235 428 236 429 while (compl_cqes) { 237 430 struct io_uring_cqe *cqe = wait_cqe_fast(&ring); ··· 242 435 io_uring_queue_exit(&ring); 243 436 } 244 437 245 - static void do_test(int domain, int type, int protocol) 438 + 439 + static void *do_test(void *arg) 246 440 { 247 - int i; 441 + struct thread_data *td = arg; 442 + int protocol = 0; 248 443 249 - for (i = 0; i < IP_MAXPACKET; i++) 250 - payload[i] = 'a' + (i % 26); 444 + setup_sockaddr(cfg_family, str_addr, &td->dst_addr); 251 445 252 - do_tx(domain, type, protocol); 446 + do_tx(td, cfg_family, cfg_type, protocol); 447 + pthread_exit(&td->ret); 448 + return NULL; 253 449 } 254 450 255 451 static void usage(const char *filepath) 256 452 { 257 - error(1, 0, "Usage: %s [-n<N>] [-z<val>] [-s<payload size>] " 453 + t_error(1, 0, "Usage: %s [-n<N>] [-z<val>] [-s<payload size>] " 258 454 "(-4|-6) [-t<time s>] -D<dst_ip> udp", filepath); 259 455 } 260 456 261 457 static void parse_opts(int argc, char **argv) 262 458 { 263 - const int max_payload_len = sizeof(payload) - 459 + const int max_payload_len = IP_MAXPACKET - 264 460 sizeof(struct ipv6hdr) - 265 461 sizeof(struct tcphdr) - 266 462 40 /* max tcp options */; ··· 272 468 273 469 cfg_payload_len = max_payload_len; 274 470 275 - while ((c = getopt(argc, argv, "46D:p:s:t:n:z:b:k")) != -1) { 471 + while ((c = getopt(argc, argv, "46D:p:s:t:n:z:b:l:dC:T:R")) != -1) { 276 472 switch (c) { 277 473 case '4': 278 474 if (cfg_family != PF_UNSPEC) 279 - error(1, 0, "Pass one of -4 or -6"); 475 + t_error(1, 0, "Pass one of -4 or -6"); 280 476 cfg_family = PF_INET; 281 477 cfg_alen = sizeof(struct sockaddr_in); 282 478 break; 283 479 case '6': 284 480 if (cfg_family != PF_UNSPEC) 285 - error(1, 0, "Pass one of -4 or -6"); 481 + t_error(1, 0, "Pass one of -4 or -6"); 286 482 cfg_family = PF_INET6; 287 483 cfg_alen = sizeof(struct sockaddr_in6); 288 484 break; ··· 307 503 case 'b': 308 504 cfg_fixed_buf = strtoul(optarg, NULL, 0); 309 505 break; 506 + case 'l': 507 + cfg_hugetlb = strtoul(optarg, NULL, 0); 508 + break; 509 + case 'd': 510 + cfg_defer_taskrun = 1; 511 + break; 512 + case 'C': 513 + cfg_cpu = strtol(optarg, NULL, 0); 514 + break; 515 + case 'T': 516 + cfg_nr_threads = strtol(optarg, NULL, 0); 517 + if (cfg_nr_threads > MAX_THREADS) 518 + t_error(1, 0, "too many threads\n"); 519 + break; 520 + case 'R': 521 + cfg_rx = 1; 522 + break; 310 523 } 311 524 } 312 525 313 526 if (cfg_nr_reqs > MAX_SUBMIT_NR) 314 - error(1, 0, "-n: submit batch nr exceeds max (%d)", MAX_SUBMIT_NR); 527 + t_error(1, 0, "-n: submit batch nr exceeds max (%d)", MAX_SUBMIT_NR); 315 528 if (cfg_payload_len > max_payload_len) 316 - error(1, 0, "-s: payload exceeds max (%d)", max_payload_len); 529 + t_error(1, 0, "-s: payload exceeds max (%d)", max_payload_len); 317 530 318 - setup_sockaddr(cfg_family, daddr, &cfg_dst_addr); 531 + str_addr = daddr; 319 532 320 533 if (optind != argc - 1) 321 534 usage(argv[0]); ··· 323 536 324 537 int main(int argc, char **argv) 325 538 { 539 + unsigned long long packets = 0, bytes = 0; 540 + struct thread_data *td; 326 541 const char *cfg_test; 542 + unsigned int i; 543 + void *res; 327 544 328 545 parse_opts(argc, argv); 546 + set_cpu_affinity(); 547 + 548 + payload = payload_buf; 549 + if (cfg_hugetlb) { 550 + payload = mmap(NULL, 2*1024*1024, PROT_READ | PROT_WRITE, 551 + MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_2MB | MAP_ANONYMOUS, 552 + -1, 0); 553 + if (payload == MAP_FAILED) { 554 + fprintf(stderr, "hugetlb alloc failed\n"); 555 + return 1; 556 + } 557 + } 329 558 330 559 cfg_test = argv[argc - 1]; 331 560 if (!strcmp(cfg_test, "tcp")) 332 - do_test(cfg_family, SOCK_STREAM, 0); 561 + cfg_type = SOCK_STREAM; 333 562 else if (!strcmp(cfg_test, "udp")) 334 - do_test(cfg_family, SOCK_DGRAM, 0); 563 + cfg_type = SOCK_DGRAM; 335 564 else 336 - error(1, 0, "unknown cfg_test %s", cfg_test); 565 + t_error(1, 0, "unknown cfg_test %s", cfg_test); 566 + 567 + pthread_barrier_init(&barrier, NULL, cfg_nr_threads); 568 + 569 + for (i = 0; i < IP_MAXPACKET; i++) 570 + payload[i] = 'a' + (i % 26); 337 571 572 + for (i = 0; i < cfg_nr_threads; i++) { 573 + td = &threads[i]; 574 + td->idx = i; 575 + } 576 + 577 + if (cfg_rx) 578 + do_setup_rx(cfg_family, cfg_type, 0); 579 + 580 + for (i = 0; i < cfg_nr_threads; i++) 581 + pthread_create(&threads[i].thread, NULL, 582 + !cfg_rx ? do_test : do_rx, &threads[i]); 583 + 584 + for (i = 0; i < cfg_nr_threads; i++) { 585 + td = &threads[i]; 586 + pthread_join(td->thread, &res); 587 + packets += td->packets; 588 + bytes += td->bytes; 589 + } 590 + 591 + fprintf(stderr, "packets=%llu (MB=%llu), rps=%llu (MB/s=%llu)\n", 592 + packets, bytes >> 20, 593 + packets / (cfg_runtime_ms / 1000), 594 + (bytes >> 20) / (cfg_runtime_ms / 1000)); 595 + 596 + pthread_barrier_destroy(&barrier); 338 597 return 0; 339 598 }
+2 -17
vendor/opam/uring/vendor/liburing/examples/ucontext-cp.c
··· 68 68 DEFINE_AWAIT_OP(writev) 69 69 #undef DEFINE_AWAIT_OP 70 70 71 - int await_poll(async_context *pctx, int fd, short poll_mask) { 72 - struct io_uring_sqe *sqe = io_uring_get_sqe(pctx->ring); 73 - struct io_uring_cqe *cqe; 74 - if (!sqe) 75 - return -1; 76 - 77 - io_uring_prep_poll_add(sqe, fd, poll_mask); 78 - io_uring_sqe_set_data(sqe, pctx); 79 - swapcontext(&pctx->ctx_fnew, &pctx->ctx_main); 80 - io_uring_peek_cqe(pctx->ring, &cqe); 81 - assert(cqe); 82 - io_uring_cqe_seen(pctx->ring, cqe); 83 - 84 - return cqe->res; 85 - } 86 - 87 - int await_delay(async_context *pctx, time_t seconds) { 71 + static int await_delay(async_context *pctx, time_t seconds) 72 + { 88 73 struct io_uring_sqe *sqe = io_uring_get_sqe(pctx->ring); 89 74 struct io_uring_cqe *cqe; 90 75 struct __kernel_timespec ts = {
+12
vendor/opam/uring/vendor/liburing/liburing-ffi.pc.in
··· 1 + prefix=@prefix@ 2 + exec_prefix=${prefix} 3 + libdir=@libdir@ 4 + includedir=@includedir@ 5 + 6 + Name: @NAME@ 7 + Version: @VERSION@ 8 + Description: io_uring FFI library 9 + URL: https://git.kernel.dk/cgit/liburing/ 10 + 11 + Libs: -L${libdir} -luring-ffi 12 + Cflags: -I${includedir}
+1 -1
vendor/opam/uring/vendor/liburing/liburing.pc.in
··· 6 6 Name: @NAME@ 7 7 Version: @VERSION@ 8 8 Description: io_uring library 9 - URL: http://git.kernel.dk/cgit/liburing/ 9 + URL: https://git.kernel.dk/cgit/liburing/ 10 10 11 11 Libs: -L${libdir} -luring 12 12 Cflags: -I${includedir}
+1 -1
vendor/opam/uring/vendor/liburing/liburing.spec
··· 1 1 Name: liburing 2 - Version: 2.3 2 + Version: 2.4 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
+3 -3
vendor/opam/uring/vendor/liburing/make-debs.sh
··· 13 13 # GNU General Public License for more details. 14 14 # 15 15 # You should have received a copy of the GNU General Public License 16 - # along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + # along with this program. If not, see <https://www.gnu.org/licenses/>. 17 17 # 18 18 set -xe 19 19 20 20 # Create dir for build 21 21 base=${1:-/tmp/release} 22 - codename=$(lsb_release -sc) 22 + distro=unstable 23 23 releasedir=$base/$(lsb_release -si)/liburing 24 24 rm -rf $releasedir 25 25 mkdir -p $releasedir ··· 40 40 # Change changelog if it's needed 41 41 cur_ver=`head -l debian/changelog | sed -n -e 's/.* (\(.*\)) .*/\1/p'` 42 42 if [ "$cur_ver" != "$version-1" ]; then 43 - dch -D $codename --force-distribution -b -v "$version-1" "new version" 43 + dch -D $distro --force-distribution -b -v "$version-1" "new version" 44 44 fi 45 45 46 46 # Create tar archieve
+1
vendor/opam/uring/vendor/liburing/man/IO_URING_CHECK_VERSION.3
··· 1 + io_uring_check_version.3
+1
vendor/opam/uring/vendor/liburing/man/IO_URING_VERSION_MAJOR.3
··· 1 + io_uring_check_version.3
+1
vendor/opam/uring/vendor/liburing/man/IO_URING_VERSION_MINOR.3
··· 1 + io_uring_check_version.3
+1
vendor/opam/uring/vendor/liburing/man/__io_uring_buf_ring_cq_advance.3
··· 1 + io_uring_buf_ring_cq_advance.3
+2 -2
vendor/opam/uring/vendor/liburing/man/io_uring.7
··· 299 299 /* fill the sqe index into the SQ ring array */ 300 300 sqring->array[index] = index; 301 301 tail++; 302 - atomic_store_release(sqring->tail, tail); 302 + atomic_store_explicit(sqring->tail, tail, memory_order_release); 303 303 .EE 304 304 .in 305 305 .PP ··· 453 453 /* CQE consumption complete */ 454 454 head++; 455 455 } 456 - atomic_store_release(cqring->head, head); 456 + atomic_store_explicit(cqring->head, head, memory_order_release); 457 457 .EE 458 458 .in 459 459 .PP
+6 -6
vendor/opam/uring/vendor/liburing/man/io_uring_buf_ring_add.3
··· 9 9 .nf 10 10 .B #include <liburing.h> 11 11 .PP 12 - .BI "int io_uring_buf_ring_add(struct io_uring_buf_ring *" br ", 13 - .BI " void *" addr ", 14 - .BI " unsigned int " len ", 15 - .BI " unsigned short " bid ", 16 - .BI " int " mask ", 17 - .BI " int " buf_offset ");" 12 + .BI "void io_uring_buf_ring_add(struct io_uring_buf_ring *" br ", 13 + .BI " void *" addr ", 14 + .BI " unsigned int " len ", 15 + .BI " unsigned short " bid ", 16 + .BI " int " mask ", 17 + .BI " int " buf_offset ");" 18 18 .fi 19 19 .SH DESCRIPTION 20 20 .PP
+15 -1
vendor/opam/uring/vendor/liburing/man/io_uring_buf_ring_cq_advance.3
··· 12 12 .BI "void io_uring_buf_ring_cq_advance(struct io_uring *" ring ", 13 13 .BI " struct io_uring_buf_ring *" br ", 14 14 .BI " int " count ");" 15 + .PP 16 + .BI "void __io_uring_buf_ring_cq_advance(struct io_uring *" ring ", 17 + .BI " struct io_uring_buf_ring *" br ", 18 + .BI " int " cq_count ", 19 + .BI " int " buf_count ");" 15 20 .fi 16 21 .SH DESCRIPTION 17 22 .PP ··· 29 34 amount. This effectively bundles both a 30 35 .BR io_uring_buf_ring_advance (3) 31 36 call and a 32 - .BR io_uring_cq_avance (3) 37 + .BR io_uring_cq_advance (3) 33 38 into one operation. Since updating either ring index entails a store memory 34 39 barrier, doing both at once is more efficient. 40 + 41 + The 42 + .BR __io_uring_buf_ring_cq_advance (3) 43 + function performs the same operation, except it splits the counts into two 44 + separate values. It advances the CQ ring by 45 + .I cq_count 46 + entries, and the buffer ring by 47 + .I buf_count 48 + entries rather than increment both by the same value. 35 49 36 50 .SH RETURN VALUE 37 51 None
+72
vendor/opam/uring/vendor/liburing/man/io_uring_check_version.3
··· 1 + .\" Copyright (C) 2022 Christian Hergert <chergert@redhat.com> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_check_version 3 "December 1, 2022" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_check_version \- functions and macros to check the liburing version 8 + .SH SYNOPSIS 9 + .nf 10 + .B #include <liburing.h> 11 + .PP 12 + .BI "bool io_uring_check_version(int " major ", int " minor ");" 13 + .BI "IO_URING_CHECK_VERSION(" major ", " minor ");" 14 + .PP 15 + .BI "int io_uring_major_version(void);" 16 + .BI "IO_URING_VERSION_MAJOR;" 17 + .PP 18 + .BI "int io_uring_minor_version(void);" 19 + .BI "IO_URING_VERSION_MINOR;" 20 + .fi 21 + .SH DESCRIPTION 22 + .PP 23 + The 24 + .BR io_uring_check_version (3) 25 + function returns 26 + .I true 27 + if the liburing library loaded by the dynamic linker is greater-than 28 + or equal-to the 29 + .I major 30 + and 31 + .I minor 32 + numbers provided. 33 + 34 + .PP 35 + The 36 + .BR IO_URING_CHECK_VERSION (3) 37 + macro returns 38 + .I 1 39 + if the liburing library being compiled against is greater-than or equal-to the 40 + .I major 41 + and 42 + .I minor 43 + numbers provided. 44 + 45 + .PP 46 + The 47 + .BR io_uring_major_version (3) 48 + function returns the 49 + .I major 50 + version number of the liburing library loaded by the dynamic linker. 51 + 52 + .PP 53 + The 54 + .BR IO_URING_VERSION_MAJOR (3) 55 + macro returns the 56 + .I major 57 + version number of the liburing library being compiled against. 58 + 59 + .PP 60 + The 61 + .BR io_uring_minor_version (3) 62 + function returns the 63 + .I minor 64 + version number of the liburing library loaded by the dynamic linker. 65 + 66 + .PP 67 + The 68 + .BR IO_URING_VERSION_MINOR (3) 69 + macro returns the 70 + .I minor 71 + version number of the liburing library being compiled against. 72 +
+43
vendor/opam/uring/vendor/liburing/man/io_uring_close_ring_fd.3
··· 1 + .\" Copyright (C) 2022 Jens Axboe <axboe@kernel.dk> 2 + .\" Copyright (C) 2022 Josh Triplett <josh@joshtriplett.org> 3 + .\" 4 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 5 + .\" 6 + .TH io_uring_close_ring_fd 3 "September 25, 2022" "liburing-2.4" "liburing Manual" 7 + .SH NAME 8 + io_uring_close_ring_fd \- close a ring file descriptor and use it only via registered index 9 + .SH SYNOPSIS 10 + .nf 11 + .B #include <liburing.h> 12 + .PP 13 + .BI "int io_uring_close_ring_fd(struct io_uring *" ring ");" 14 + .fi 15 + .SH DESCRIPTION 16 + .PP 17 + .BR io_uring_close_ring_fd (3) 18 + closes the ring file descriptor, which must have been previously registered. 19 + The file will remain open, but accessible only via the registered index, not 20 + via any file descriptor. Subsequent liburing calls will continue to work, using 21 + the registered ring fd. 22 + 23 + The kernel must support 24 + .BR IORING_FEAT_REG_REG_RING . 25 + 26 + Libraries that must avoid disrupting their users' uses of file descriptors, and 27 + must continue working even in the face of 28 + .BR close_range (2) 29 + and similar, can use 30 + .BR io_uring_close_ring_fd (3) 31 + to work with liburing without having any open file descriptor. 32 + 33 + .SH NOTES 34 + Each thread that wants to make use of io_uring must register the fd. A library 35 + that may get called from arbitrary theads may need to detect when it gets 36 + called on a previously unseen thread and create and register a ring for that 37 + thread. 38 + .SH RETURN VALUE 39 + Returns 1 on success, or 40 + .BR -errno 41 + on error. 42 + .SH SEE ALSO 43 + .BR io_uring_register_ring_fd (3)
+1 -1
vendor/opam/uring/vendor/liburing/man/io_uring_cqe_get_data.3
··· 46 46 If the 47 47 .I user_data 48 48 value has been set before submitting the request, it will be returned. 49 - Otherwise the functions returns NULL. 49 + Otherwise, the return value is undefined. 50 50 .SH SEE ALSO 51 51 .BR io_uring_get_sqe (3), 52 52 .BR io_uring_sqe_set_data (3),
+2 -3
vendor/opam/uring/vendor/liburing/man/io_uring_cqe_seen.3
··· 35 35 None 36 36 .SH SEE ALSO 37 37 .BR io_uring_submit (3), 38 - .BR io_uring_wait_cqe (3), 39 38 .BR io_uring_peek_cqe (3), 39 + .BR io_uring_wait_cqe (3), 40 40 .BR io_uring_wait_cqes (3), 41 - .BR io_uring_wait_cqe_timeout (3), 42 - .BR io_uring_cqe_seen (3) 41 + .BR io_uring_wait_cqe_timeout (3)
+1 -1
vendor/opam/uring/vendor/liburing/man/io_uring_enter.2
··· 81 81 must be set to the size of this structure. The definition is as follows: 82 82 83 83 .nf 84 - .BI "struct io_uring_getevents_args { 84 + .BI "struct io_uring_getevents_arg { 85 85 .BI " __u64 sigmask; 86 86 .BI " __u32 sigmask_sz; 87 87 .BI " __u32 pad;
+63
vendor/opam/uring/vendor/liburing/man/io_uring_for_each_cqe.3
··· 1 + .\" Copyright (C) 2023 Jens Axboe <axboe@kernel.dk> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_for_each_cqe 3 "June 04, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_for_each_cqe \- iterate pending completion events 8 + .SH SYNOPSIS 9 + .nf 10 + .B #include <liburing.h> 11 + .PP 12 + .BI "io_uring_for_each_cqe(struct io_uring *" ring "," 13 + .BI " unsigned " head "," 14 + .BI " struct io_uring_cqe *" cqe ") { } 15 + .fi 16 + .SH DESCRIPTION 17 + .PP 18 + The 19 + .BR io_uring_for_each_cqe (3) 20 + is a macro helper that iterates completion events belonging to the 21 + .I ring 22 + using 23 + .I head 24 + as a temporary iterator, and points 25 + .I cqe 26 + to each pending event when iterating. 27 + 28 + This helper provides an efficient way to iterate all pending events in 29 + the ring, and then advancing the CQ ring by calling 30 + .BR io_uring_cq_advance (3) 31 + with the number of CQEs consumed when done. As updating the kernel visible 32 + CQ ring state involves an ordered write, doing it once for a number of 33 + events is more efficient than handling each completion separately and 34 + calling 35 + .BR io_uring_cqe_seen (3) 36 + for each of them. 37 + 38 + .SH EXAMPLE 39 + .EX 40 + void handle_cqes(struct io_uring *ring) 41 + { 42 + struct io_uring_cqe *cqe; 43 + unsigned head; 44 + unsigned i = 0; 45 + 46 + io_uring_for_each_cqe(ring, head, cqe) { 47 + /* handle completion */ 48 + printf("cqe: %d\\n", cqe->res); 49 + i++; 50 + } 51 + 52 + io_uring_cq_advance(ring, i); 53 + } 54 + .EE 55 + 56 + .SH RETURN VALUE 57 + None 58 + .SH SEE ALSO 59 + .BR io_uring_wait_cqe_timeout (3), 60 + .BR io_uring_wait_cqe (3), 61 + .BR io_uring_wait_cqes (3), 62 + .BR io_uring_cqe_seen (3), 63 + .BR io_uring_buf_ring_cq_advance (3)
+53
vendor/opam/uring/vendor/liburing/man/io_uring_free_buf_ring.3
··· 1 + .\" Copyright (C) 2022 Jens Axboe <axboe@kernel.dk> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_free_buf_ring 3 "Mar 07, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_free_buf_ring \- register and free a buffer ring for provided buffers 8 + .SH SYNOPSIS 9 + .nf 10 + .B #include <liburing.h> 11 + .PP 12 + .BI "int io_uring_free_buf_ring(struct io_uring *" ring ", 13 + .BI " struct io_uring_buf_ring *" br ", 14 + .BI " unsigned int " nentries ", 15 + .BI " int " bgid ");" 16 + .BI " 17 + .fi 18 + .SH DESCRIPTION 19 + .PP 20 + The 21 + .BR io_uring_free_buf_ring (3) 22 + function unregisters a previously registered shared buffer ring. The ring must 23 + have heen previously returned from 24 + .BR io_uring_setup_buf_ring (3) . 25 + 26 + The 27 + .I ring 28 + argument must pointer to the ring for which the provided buffer ring is being 29 + registered, 30 + .I br 31 + must point to a buffer ring previously returned by 32 + .BR io_uring_setup_buf_ring (3) , 33 + .I nentries 34 + is the number of entries requested in the buffer ring, and 35 + .I bgid 36 + is the buffer group ID that 37 + .I br 38 + was setup with. 39 + 40 + Under the covers, this function uses 41 + .BR io_uring_unregister_buf_ring (3) 42 + to unregister the ring, and handles the freeing of the ring rather than 43 + letting the application open code it. 44 + 45 + Available since 5.19. 46 + 47 + .SH RETURN VALUE 48 + On success 49 + .BR io_uring_register_free_ring (3) 50 + returns a pointer to the buffe ring. On failure it returns 51 + .BR -errno . 52 + .SH SEE ALSO 53 + .BR io_uring_setup_buf_ring (3)
+1
vendor/opam/uring/vendor/liburing/man/io_uring_major_version.3
··· 1 + io_uring_check_version.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_minor_version.3
··· 1 + io_uring_check_version.3
+1 -1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_accept.3
··· 92 92 If both forms of direct selection will be employed, specific and dynamic, see 93 93 .BR io_uring_register_file_alloc_range (3) 94 94 for setting up the table so dynamically chosen entries are made against 95 - a different range than that targetted by specific requests. 95 + a different range than that targeted by specific requests. 96 96 97 97 Note that old kernels don't check the SQE 98 98 .I file_index
+2 -2
vendor/opam/uring/vendor/liburing/man/io_uring_prep_fallocate.3
··· 13 13 .BI "void io_uring_prep_fallocate(struct io_uring_sqe *" sqe "," 14 14 .BI " int " fd "," 15 15 .BI " int " mode "," 16 - .BI " off_t " offset "," 17 - .BI " off_t " len ");" 16 + .BI " __u64 " offset "," 17 + .BI " __u64 " len ");" 18 18 .fi 19 19 .SH DESCRIPTION 20 20 .PP
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_fgetxattr.3
··· 1 + io_uring_prep_getxattr.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_fsetxattr.3
··· 1 + io_uring_prep_setxattr.3
+61
vendor/opam/uring/vendor/liburing/man/io_uring_prep_getxattr.3
··· 1 + .\" Copyright (C) 2023 Rutvik Patel <heyrutvik@gmail.com> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_prep_getxattr 3 "January 23, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_prep_getxattr, io_uring_prep_fgetxattr \- prepare a request to get an 8 + extended attribute value 9 + .SH SYNOPSIS 10 + .nf 11 + .B #include <liburing.h> 12 + .PP 13 + .BI "void io_uring_prep_getxattr(struct io_uring_sqe *" sqe "," 14 + .BI " const char *" name "," 15 + .BI " char *" value "," 16 + .BI " const char *" path "," 17 + .BI " unsigned int " len ");" 18 + .PP 19 + .BI "void io_uring_prep_fgetxattr(struct io_uring_sqe *" sqe "," 20 + .BI " int " fd "," 21 + .BI " const char *" name "," 22 + .BI " char *" value "," 23 + .BI " unsigned int " len ");" 24 + .fi 25 + .SH DESCRIPTION 26 + .PP 27 + The 28 + .BR io_uring_prep_getxattr (3) 29 + function prepares a request to get an extended attribute value. The submission 30 + queue entry 31 + .I sqe 32 + is setup to get the 33 + .I value 34 + of the extended attribute identified by 35 + .I name 36 + and associated with the given 37 + .I path 38 + in the filesystem. 39 + The 40 + .I len 41 + argument specifies the size (in bytes) of 42 + .IR value . 43 + 44 + .BR io_uring_prep_fgetxattr (3) 45 + is identical to 46 + .BR io_uring_prep_getxattr (3), 47 + only the open file referred to by 48 + .I fd 49 + is interrogated in place of 50 + .IR path . 51 + 52 + This function prepares an async 53 + .BR getxattr (2) 54 + request. See that man page for details. 55 + 56 + .SH RETURN VALUE 57 + None 58 + 59 + .SH SEE ALSO 60 + .BR io_uring_get_sqe (3), 61 + .BR getxattr (2)
+22 -2
vendor/opam/uring/vendor/liburing/man/io_uring_prep_msg_ring.3
··· 14 14 .BI " unsigned int " len "," 15 15 .BI " __u64 " data "," 16 16 .BI " unsigned int " flags ");" 17 + .PP 18 + .BI "void io_uring_prep_msg_ring_cqe_flags(struct io_uring_sqe *" sqe "," 19 + .BI " int " fd "," 20 + .BI " unsigned int " len "," 21 + .BI " __u64 " data "," 22 + .BI " unsigned int " flags "," 23 + .BI " unsigned int " cqe_flags ");" 17 24 .fi 18 25 .SH DESCRIPTION 19 26 .PP 20 27 .BR io_uring_prep_msg_ring (3) 21 - prepares a to send a CQE to an io_uring file descriptor. The submission queue 28 + prepares to send a CQE to an io_uring file descriptor. The submission queue 22 29 entry 23 30 .I sqe 24 31 is setup to use the file descriptor ··· 47 54 on the targeted ring, or it can be used to pass messages between the two 48 55 rings. 49 56 57 + .BR io_uring_prep_msg_ring_cqe_flags (3) 58 + is similar to 59 + .BR io_uring_prep_msg_ring (3) . 60 + But has an addition 61 + .I cqe_flags 62 + parameter, which is used to set 63 + .I flags 64 + field on CQE side. That way, you can set the CQE flags field 65 + .I cqe->flags 66 + when sending a message. Be aware that io_uring could potentially set additional 67 + bits into this field. 68 + 50 69 .SH RETURN VALUE 51 70 None 52 71 ··· 64 83 .B -EBADFD 65 84 The descriptor passed in 66 85 .I fd 67 - does not refer to an io_uring file descriptor. 86 + does not refer to an io_uring file descriptor, or the ring is in a disabled 87 + state. 68 88 .TP 69 89 .B -EOVERFLOW 70 90 The kernel was unable to fill a CQE on the target ring. This can happen if
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3
··· 1 + io_uring_prep_msg_ring.3
+83
vendor/opam/uring/vendor/liburing/man/io_uring_prep_msg_ring_fd.3
··· 1 + .\" Copyright (C) 2022 Jens Axboe <axboe@kernel.dk> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_prep_msg_ring 3 "Mar 16, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_prep_msg_ring_fd \- send a direct descriptor to another ring 8 + .SH SYNOPSIS 9 + .nf 10 + .B #include <liburing.h> 11 + .PP 12 + .BI "void io_uring_prep_msg_ring_fd(struct io_uring_sqe *" sqe "," 13 + .BI " int " fd "," 14 + .BI " int " source_fd "," 15 + .BI " int " target_fd "," 16 + .BI " __u64 " data "," 17 + .BI " unsigned int " flags ");" 18 + .PP 19 + .BI "void io_uring_prep_msg_ring_fd_alloc(struct io_uring_sqe *" sqe "," 20 + .BI " int " fd "," 21 + .BI " int " source_fd "," 22 + .BI " __u64 " data "," 23 + .BI " unsigned int " flags ");" 24 + .fi 25 + .SH DESCRIPTION 26 + .PP 27 + .BR io_uring_prep_msg_ring_fd (3) 28 + prepares an SQE to send a direct file descriptor to another ring. The submission 29 + queue entry 30 + .I sqe 31 + is setup to use the file descriptor 32 + .IR fd , 33 + which must identify a target io_uring context, to send the locally registered 34 + file descriptor with value 35 + .I source_fd 36 + to the destination ring into index 37 + .I target_fd 38 + and passing 39 + .I data 40 + as the user data in the target CQE with the request modifier flags set by 41 + .IR flags . 42 + Currently there are no valid flag modifiers, this field must contain 43 + .BR 0 . 44 + 45 + .BR io_uring_prep_msg_ring_fd_alloc (3) 46 + is similar to 47 + .BR io_uring_prep_msg_ring_fd (3) , 48 + but doesn't specify a target index for the direct descriptor. Instead, this 49 + index is allocated in the target ring and returned in the CQE 50 + .IR res 51 + field. 52 + 53 + .SH RETURN VALUE 54 + None 55 + 56 + .SH ERRORS 57 + These are the errors that are reported in the CQE 58 + .I res 59 + field. 60 + .TP 61 + .B -ENOMEM 62 + The kernel was unable to allocate memory for the request. 63 + .TP 64 + .B -EINVAL 65 + One of the fields set in the SQE was invalid. 66 + .TP 67 + .B -EINVAL 68 + Target ring is identical to the source ring. 69 + .TP 70 + .B -EBADFD 71 + The descriptor passed in 72 + .I fd 73 + does not refer to an io_uring file descriptor, or the ring is in a disabled 74 + state. 75 + .TP 76 + .B -EOVERFLOW 77 + The kernel was unable to fill a CQE on the target ring. This can happen if 78 + the target CQ ring is in an overflow state and the kernel wasn't able to 79 + allocate memory for a new CQE entry. 80 + .TP 81 + .B -ENFILE 82 + The direct descriptor table in the target ring was full, no new descriptors 83 + could be successfully allocated.
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_msg_ring_fd_alloc.3
··· 1 + io_uring_prep_msg_ring_fd.3
+1 -1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_poll_add.3
··· 33 33 The default behavior is a single-shot poll request. When the specified event 34 34 has triggered, a completion CQE is posted and no more events will be generated 35 35 by the poll request. 36 - .BR io_uring_prep_multishot (3) 36 + .BR io_uring_prep_poll_multishot (3) 37 37 behaves identically in terms of events, but it persist across notifications 38 38 and will repeatedly post notifications for the same registration. A CQE 39 39 posted from a multishot poll request will have
+18 -9
vendor/opam/uring/vendor/liburing/man/io_uring_prep_provide_buffers.3
··· 24 24 submission queue entry 25 25 .I sqe 26 26 is setup to consume 27 + .I nr 28 + number of 27 29 .I len 28 - number of buffers starting at 30 + sized buffers starting at 29 31 .I addr 30 32 and identified by the buffer group ID of 31 33 .I bgid ··· 68 70 The application must be aware of this to make sense of the buffer ID passed 69 71 back in the CQE. 70 72 73 + Buffer IDs always range from 74 + .B 0 75 + to 76 + .B 65535 , 77 + as there are only 16-bits available in the CQE to pass them back. This range 78 + is independent of how the buffer group initially got created. Attempting to 79 + add buffer IDs larger than that, or buffer IDs that will wrap when cast to 80 + a 16-bit value, will cause the request to fail with 81 + .B -E2BIG 82 + or 83 + .B -EINVAL . 84 + 71 85 Not all requests support buffer selection, as it only really makes sense for 72 86 requests that receive data from the kernel rather than write or provide data. 73 87 Currently, this mode of operation is supported for any file read or socket ··· 88 102 .I res 89 103 field. On success, 90 104 .I res 91 - will contain the number of successfully provided buffers. On error, 92 - the following errors can occur. 105 + will contain 106 + .B 0 107 + or the number of successfully provided buffers. 93 108 .TP 94 109 .B -ENOMEM 95 110 The kernel was unable to allocate memory for the request. ··· 106 121 .TP 107 122 .B -EFAULT 108 123 Some of the user memory given was invalid for the application. 109 - .TP 110 - .B -EBADF 111 - On of the descriptors located in 112 - .I fds 113 - didn't refer to a valid file descriptor, or one of the file descriptors in 114 - the array referred to an io_uring instance. 115 124 .TP 116 125 .B -EOVERFLOW 117 126 The product of
+3 -3
vendor/opam/uring/vendor/liburing/man/io_uring_prep_readv.3
··· 43 43 44 44 On files that are not capable of seeking, the offset must be 0 or -1. 45 45 46 - After the write has been prepared it can be submitted with one of the submit 46 + After the read has been prepared it can be submitted with one of the submit 47 47 functions. 48 48 49 49 .SH RETURN VALUE ··· 64 64 .I res 65 65 field. 66 66 .SH NOTES 67 - Unless an application explicitly needs to pass in more than iovec, it is more 68 - efficient to use 67 + Unless an application explicitly needs to pass in more than one iovec, it 68 + is more efficient to use 69 69 .BR io_uring_prep_read (3) 70 70 rather than this function, as no state has to be maintained for a 71 71 non-vectored IO request.
+3 -3
vendor/opam/uring/vendor/liburing/man/io_uring_prep_readv2.3
··· 69 69 70 70 On files that are not capable of seeking, the offset must be 0 or -1. 71 71 72 - After the write has been prepared, it can be submitted with one of the submit 72 + After the read has been prepared, it can be submitted with one of the submit 73 73 functions. 74 74 75 75 .SH RETURN VALUE ··· 90 90 .I res 91 91 field. 92 92 .SH NOTES 93 - Unless an application explicitly needs to pass in more than iovec, it is more 94 - efficient to use 93 + Unless an application explicitly needs to pass in more than one iovec, it 94 + is more efficient to use 95 95 .BR io_uring_prep_read (3) 96 96 rather than this function, as no state has to be maintained for a 97 97 non-vectored IO request.
+5 -5
vendor/opam/uring/vendor/liburing/man/io_uring_prep_recv.3
··· 30 30 .I sqe 31 31 is setup to use the file descriptor 32 32 .I sockfd 33 - to start receiving the data into the buffer destination 33 + to start receiving the data into the destination buffer 34 34 .I buf 35 35 of size 36 - .I size 36 + .I len 37 37 and with modifier flags 38 38 .IR flags . 39 39 ··· 43 43 prep helper. 44 44 45 45 The multishot version allows the application to issue a single receive request, 46 - which repeatedly posts a CQE when data is available. It requires length to be 0 47 - , the 46 + which repeatedly posts a CQE when data is available. It requires length to 47 + be 0, the 48 48 .B IOSQE_BUFFER_SELECT 49 49 flag to be set and no 50 50 .B MSG_WAITALL 51 51 flag to be set. 52 52 Therefore each CQE will take a buffer out of a provided buffer pool for receiving. 53 - The application should check the flags of each CQE, regardless of it's result. 53 + The application should check the flags of each CQE, regardless of its result. 54 54 If a posted CQE does not have the 55 55 .B IORING_CQE_F_MORE 56 56 flag set then the multishot receive will be done and the application should issue a
+4 -4
vendor/opam/uring/vendor/liburing/man/io_uring_prep_recvmsg.3
··· 49 49 .B MSG_WAITALL 50 50 flag to be set. 51 51 Therefore each CQE will take a buffer out of a provided buffer pool for receiving. 52 - The application should check the flags of each CQE, regardless of it's result. 52 + The application should check the flags of each CQE, regardless of its result. 53 53 If a posted CQE does not have the 54 54 .B IORING_CQE_F_MORE 55 55 flag set then the multishot receive will be done and the application should issue a 56 56 new request. 57 57 58 58 Unlike 59 - .BR recvmsg (2) 60 - , multishot recvmsg will prepend a 59 + .BR recvmsg (2), 60 + multishot recvmsg will prepend a 61 61 .I struct io_uring_recvmsg_out 62 62 which describes the layout of the rest of the buffer in combination with the initial 63 63 .I struct msghdr 64 64 submitted with the request. See 65 - .B io_uring_recvmsg_out (3) 65 + .BR io_uring_recvmsg_out (3) 66 66 for more information on accessing the data. 67 67 68 68 Multishot variants are available since kernel 6.0.
+40
vendor/opam/uring/vendor/liburing/man/io_uring_prep_send.3
··· 14 14 .BI " const void *" buf "," 15 15 .BI " size_t " len "," 16 16 .BI " int " flags ");" 17 + .PP 18 + .BI "void io_uring_prep_sendto(struct io_uring_sqe *" sqe "," 19 + .BI " int " sockfd "," 20 + .BI " const void *" buf "," 21 + .BI " size_t " len "," 22 + .BI " int " flags "," 23 + .BI " const struct sockaddr *" addr "," 24 + .BI " socklen_t " addrlen ");" 17 25 .fi 18 26 .SH DESCRIPTION 19 27 .PP ··· 30 38 bytes and with modifier flags 31 39 .IR flags . 32 40 41 + Note that using 42 + .B IOSQE_IO_LINK 43 + with this request type requires the setting of 44 + .B MSG_WAITALL 45 + in the 46 + .IR flags 47 + argument, as a short send isn't a considered an error condition without 48 + that being set. 49 + 33 50 This function prepares an async 34 51 .BR send (2) 35 52 request. See that man page for details. 36 53 54 + The 55 + .BR io_uring_prep_sendto (3) 56 + function prepares a sendto request. The submission queue entry 57 + .I sqe 58 + is setup to use the file descriptor 59 + .I sockfd 60 + to start sending the data from 61 + .I buf 62 + of size 63 + .I len 64 + bytes and with modifier flags 65 + .IR flags . 66 + The destination address is specified by 67 + .I addr 68 + and 69 + .I addrlen 70 + and must be a valid address for the socket type. 71 + 72 + This function prepares an async 73 + .BR sendto (2) 74 + request. See that man page for details. 75 + 37 76 .SH RETURN VALUE 38 77 None 39 78 .SH ERRORS ··· 55 94 .BR io_uring_get_sqe (3), 56 95 .BR io_uring_submit (3), 57 96 .BR send (2) 97 + .BR sendto (2)
+38
vendor/opam/uring/vendor/liburing/man/io_uring_prep_send_set_addr.3
··· 1 + .\" Copyright (C) 2023 Rutvik Patel <heyrutvik@gmail.com> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_prep_send_set_addr 3 "January 23, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_prep_send_set_addr \- set address details for send requests 8 + .SH SYNOPSIS 9 + .nf 10 + .B #include <liburing.h> 11 + .PP 12 + .BI "void io_uring_prep_send_set_addr(struct io_uring_sqe *" sqe "," 13 + .BI " const struct sockaddr *" dest_addr "," 14 + .BI " __u16 " addr_len ");" 15 + .fi 16 + .SH DESCRIPTION 17 + .PP 18 + The 19 + .BR io_uring_prep_send_set_addr (3) 20 + function sets a socket destination address specified by 21 + .I dest_addr 22 + and its length using 23 + .I addr_len 24 + parameters. It can be used once 25 + .I sqe 26 + is prepared using any of the 27 + .BR send (2) 28 + io_uring helpers. See man pages of 29 + .BR io_uring_prep_send (3) 30 + or 31 + .BR io_uring_prep_send_zc (3). 32 + .SH RETURN VALUE 33 + None 34 + .SH SEE ALSO 35 + .BR io_uring_get_sqe (3), 36 + .BR io_uring_prep_send (3), 37 + .BR io_uring_prep_send_zc (3), 38 + .BR send (2)
+39 -7
vendor/opam/uring/vendor/liburing/man/io_uring_prep_send_zc.3
··· 10 10 .B #include <liburing.h> 11 11 .PP 12 12 .BI "void io_uring_prep_send_zc(struct io_uring_sqe *" sqe "," 13 - .BI " int " sockfd "," 14 - .BI " const void *" buf "," 15 - .BI " size_t " len "," 16 - .BI " int " flags "," 17 - .BI " int " zc_flags ");" 13 + .BI " int " sockfd "," 14 + .BI " const void *" buf "," 15 + .BI " size_t " len "," 16 + .BI " int " flags "," 17 + .BI " unsigned " zc_flags ");" 18 + .PP 19 + .BI "void io_uring_prep_send_zc_fixed(struct io_uring_sqe *" sqe "," 20 + .BI " int " sockfd "," 21 + .BI " const void *" buf "," 22 + .BI " size_t " len "," 23 + .BI " int " flags "," 24 + .BI " unsigned " zc_flags ");" 25 + .BI " unsigned " buf_index ");" 18 26 .fi 19 27 .SH DESCRIPTION 20 28 .PP ··· 29 37 of size 30 38 .I len 31 39 bytes with send modifier flags 32 - .IR flags 40 + .I flags 33 41 and zerocopy modifier flags 34 42 .IR zc_flags . 35 43 36 - This function prepares an async zerocopy 44 + The 45 + .BR io_uring_prep_send_zc_fixed (3) 46 + works just like 47 + .BR io_uring_prep_send_zc (3) 48 + except it requires the use of buffers that have been registered with 49 + .BR io_uring_register_buffers (3). 50 + The 51 + .I buf 52 + and 53 + .I len 54 + arguments must fall within a region specified by 55 + .I buf_index 56 + in the previously registered buffer. The buffer need not be aligned with the 57 + start of the registered buffer. 58 + 59 + Note that using 60 + .B IOSQE_IO_LINK 61 + with this request type requires the setting of 62 + .B MSG_WAITALL 63 + in the 64 + .I flags 65 + argument, as a short send isn't considered an error condition without 66 + that being set. 67 + 68 + These functions prepare an async zerocopy 37 69 .BR send (2) 38 70 request. See that man page for details. For details on the zerocopy nature 39 71 of it, see
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_send_zc_fixed.3
··· 1 + io_uring_prep_send_zc.3
+20
vendor/opam/uring/vendor/liburing/man/io_uring_prep_sendmsg.3
··· 15 15 .BI " int " fd "," 16 16 .BI " const struct msghdr *" msg "," 17 17 .BI " unsigned " flags ");" 18 + .PP 19 + .BI "void io_uring_prep_sendmsg_zc(struct io_uring_sqe *" sqe "," 20 + .BI " int " fd "," 21 + .BI " const struct msghdr *" msg "," 22 + .BI " unsigned " flags ");" 18 23 .fi 19 24 .SH DESCRIPTION 20 25 .PP ··· 31 36 defined flags in the 32 37 .I flags 33 38 argument. 39 + 40 + The 41 + .BR io_uring_prep_sendmsg_zc (3) 42 + accepts the same parameters as 43 + .BR io_uring_prep_sendmsg (3) 44 + but prepares a zerocopy sendmsg request. 45 + 46 + Note that using 47 + .B IOSQE_IO_LINK 48 + with this request type requires the setting of 49 + .B MSG_WAITALL 50 + in the 51 + .I flags 52 + argument, as a short send isn't considered an error condition without 53 + that being set. 34 54 35 55 This function prepares an async 36 56 .BR sendmsg (2)
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_sendmsg_zc.3
··· 1 + io_uring_prep_sendmsg.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_sendto.3
··· 1 + io_uring_prep_send.3
+64
vendor/opam/uring/vendor/liburing/man/io_uring_prep_setxattr.3
··· 1 + .\" Copyright (C) 2023 Rutvik Patel <heyrutvik@gmail.com> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_prep_setxattr 3 "January 23, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_prep_setxattr, io_uring_prep_fsetxattr \- prepare a request to set an 8 + extended attribute value 9 + .SH SYNOPSIS 10 + .nf 11 + .B #include <liburing.h> 12 + .PP 13 + .BI "void io_uring_prep_setxattr(struct io_uring_sqe *" sqe "," 14 + .BI " const char *" name "," 15 + .BI " const char *" value "," 16 + .BI " const char *" path "," 17 + .BI " int " flags "," 18 + .BI " unsigned int " len ");" 19 + .PP 20 + .BI "void io_uring_prep_fsetxattr(struct io_uring_sqe *" sqe "," 21 + .BI " int " fd "," 22 + .BI " const char *" name "," 23 + .BI " const char *" value "," 24 + .BI " int " flags "," 25 + .BI " unsigned int " len ");" 26 + .fi 27 + .SH DESCRIPTION 28 + .PP 29 + The 30 + .BR io_uring_prep_setxattr (3) 31 + function prepares a request to set an extended attribute value. The submission 32 + queue entry 33 + .I sqe 34 + is setup to set the 35 + .I value 36 + of the extended attribute identified by 37 + .I name 38 + and associated with the given 39 + .I path 40 + in the filesystem with modifier flags 41 + .IR flags . 42 + The 43 + .I len 44 + argument specifies the size (in bytes) of 45 + .IR value . 46 + 47 + .BR io_uring_prep_fsetxattr (3) 48 + is identical to 49 + .BR io_uring_prep_setxattr (3), 50 + only the extended attribute is set on the open file referred to by 51 + .I fd 52 + in place of 53 + .IR path . 54 + 55 + This function prepares an async 56 + .BR setxattr (2) 57 + request. See that man page for details. 58 + 59 + .SH RETURN VALUE 60 + None 61 + 62 + .SH SEE ALSO 63 + .BR io_uring_get_sqe (3), 64 + .BR setxattr (2)
+40
vendor/opam/uring/vendor/liburing/man/io_uring_prep_splice.3
··· 52 52 .I fd_in 53 53 given as a registered file descriptor offset. 54 54 55 + If 56 + .I fd_in 57 + refers to a pipe, 58 + .I off_in 59 + is ignored and must be set to -1. 60 + 61 + If 62 + .I fd_in 63 + does not refer to a pipe and 64 + .I off_in 65 + is -1, then 66 + .I nbytes 67 + are read from 68 + .I fd_in 69 + starting from the file offset, which is incremented by the number of bytes read. 70 + 71 + If 72 + .I fd_in 73 + does not refer to a pipe and 74 + .I off_in 75 + is not -1, then the starting offset of 76 + .I fd_in 77 + will be 78 + .IR off_in . 79 + 80 + The same rules apply to 81 + .I fd_out 82 + and 83 + .IR off_out . 84 + 55 85 This function prepares an async 56 86 .BR splice (2) 57 87 request. See that man page for details. ··· 78 108 .BR io_uring_submit (3), 79 109 .BR io_uring_register (2), 80 110 .BR splice (2) 111 + 112 + .SH NOTES 113 + Note that even if 114 + .I fd_in 115 + or 116 + .I fd_out 117 + refers to a pipe, the splice operation can still fail with 118 + .B EINVAL 119 + if one of the fd doesn't explicitly support splice operation, e.g. reading from 120 + terminal is unsupported from kernel 5.7 to 5.11.
+7
vendor/opam/uring/vendor/liburing/man/io_uring_prep_timeout.3
··· 51 51 CQE 52 52 .I res 53 53 value. 54 + .TP 55 + .B IORING_TIMEOUT_MULTISHOT 56 + The request will return multiple timeout completions. The completion flag 57 + IORING_CQE_F_MORE is set if more timeouts are expected. The value specified in 58 + .I count 59 + is the number of repeats. A value of 0 means the timeout is indefinite and can 60 + only be stopped by a removal request. 54 61 .PP 55 62 The timeout completion event will trigger if either the specified timeout 56 63 has occurred, or the specified number of events to wait for have been posted
+1
vendor/opam/uring/vendor/liburing/man/io_uring_prep_timeout_update.3
··· 54 54 .I res 55 55 value. 56 56 .PP 57 + The timeout remove command does not currently accept any flags. 57 58 58 59 .SH RETURN VALUE 59 60 None
+2 -2
vendor/opam/uring/vendor/liburing/man/io_uring_prep_writev.3
··· 64 64 .I res 65 65 field. 66 66 .SH NOTES 67 - Unless an application explicitly needs to pass in more than iovec, it is more 68 - efficient to use 67 + Unless an application explicitly needs to pass in more than one iovec, it 68 + is more efficient to use 69 69 .BR io_uring_prep_write (3) 70 70 rather than this function, as no state has to be maintained for a 71 71 non-vectored IO request.
+2 -2
vendor/opam/uring/vendor/liburing/man/io_uring_prep_writev2.3
··· 90 90 .I res 91 91 field. 92 92 .SH NOTES 93 - Unless an application explicitly needs to pass in more than iovec, it is more 94 - efficient to use 93 + Unless an application explicitly needs to pass in more than one iovec, it 94 + is more efficient to use 95 95 .BR io_uring_prep_write (3) 96 96 rather than this function, as no state has to be maintained for a 97 97 non-vectored IO request.
+6 -6
vendor/opam/uring/vendor/liburing/man/io_uring_queue_init.3
··· 33 33 By default, the CQ ring will have twice the number of entries as specified by 34 34 .I entries 35 35 for the SQ ring. This is adequate for regular file or storage workloads, but 36 - may be too small networked workloads. The SQ ring entries do not impose a limit 37 - on the number of in-flight requests that the ring can support, it merely limits 38 - the number that can be submitted to the kernel in one go (batch). if the CQ 39 - ring overflows, e.g. more entries are generated than fits in the ring before the 40 - application can reap them, then the ring enters a CQ ring overflow state. This 41 - is indicated by 36 + may be too small for networked workloads. The SQ ring entries do not impose a 37 + limit on the number of in-flight requests that the ring can support, it merely 38 + limits the number that can be submitted to the kernel in one go (batch). if the 39 + CQ ring overflows, e.g. more entries are generated than fits in the ring before 40 + the application can reap them, then the ring enters a CQ ring overflow state. 41 + This is indicated by 42 42 .B IORING_SQ_CQ_OVERFLOW 43 43 being set in the SQ ring flags. Unless the kernel runs out of available memory, 44 44 entries are not dropped, but it is a much slower completion path and will slow
+13 -9
vendor/opam/uring/vendor/liburing/man/io_uring_recvmsg_out.3
··· 2 2 .\" 3 3 .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 4 .\" 5 - .TH io_uring_recvmsg_out 3 "Julyu 26, 2022" "liburing-2.2" "liburing Manual" 5 + .TH io_uring_recvmsg_out 3 "July 26, 2022" "liburing-2.2" "liburing Manual" 6 6 .SH NAME 7 7 io_uring_recvmsg_out - access data from multishot recvmsg 8 8 .SH SYNOPSIS ··· 15 15 .PP 16 16 .BI "void *io_uring_recvmsg_name(struct io_uring_recvmsg_out *" o ");" 17 17 .PP 18 - .BI "struct cmsghdr *io_uring_recvmsg_cmsg_firsthdr(struct io_uring_recvmsg_out * " o "," 19 - .BI " struct msghdr *" msgh ");" 20 - .BI "struct cmsghdr *io_uring_recvmsg_cmsg_nexthdr(struct io_uring_recvmsg_out * " o "," 18 + .BI "struct cmsghdr *io_uring_recvmsg_cmsg_firsthdr(struct io_uring_recvmsg_out *" o "," 19 + .BI " struct msghdr *" msgh ");" 20 + .BI "struct cmsghdr *io_uring_recvmsg_cmsg_nexthdr(struct io_uring_recvmsg_out *" o "," 21 21 .BI " struct msghdr *" msgh "," 22 22 .BI " struct cmsghdr *" cmsg ");" 23 23 .PP 24 - .BI "void *io_uring_recvmsg_payload(struct io_uring_recvmsg_out * " o "," 24 + .BI "void *io_uring_recvmsg_payload(struct io_uring_recvmsg_out *" o "," 25 25 .BI " struct msghdr *" msgh ");" 26 26 .BI "unsigned int io_uring_recvmsg_payload_length(struct io_uring_recvmsg_out *" o "," 27 27 .BI " int " buf_len "," ··· 32 32 .SH DESCRIPTION 33 33 34 34 These functions are used to access data in the payload delivered by 35 - .BR io_uring_prep_recv_multishot (3) 36 - . 35 + .BR io_uring_prep_recvmsg_multishot (3). 36 + .PP 37 + .I msgh 38 + should point to the 39 + .I struct msghdr 40 + submitted with the request. 37 41 .PP 38 42 .BR io_uring_recvmsg_validate (3) 39 43 will validate a buffer delivered by 40 - .BR io_uring_prep_recv_multishot (3) 44 + .BR io_uring_prep_recvmsg_multishot (3) 41 45 and extract the 42 46 .I io_uring_recvmsg_out 43 47 if it is valid, returning a pointer to it or else NULL. ··· 75 79 76 80 77 81 .SH "SEE ALSO" 78 - .BR io_uring_prep_recv_multishot (3) 82 + .BR io_uring_prep_recvmsg_multishot (3)
+18 -9
vendor/opam/uring/vendor/liburing/man/io_uring_register.2
··· 31 31 .I fd 32 32 is the file descriptor returned by a call to 33 33 .BR io_uring_setup (2). 34 + If 35 + .I opcode 36 + has the flag 37 + .B IORING_REGISTER_USE_REGISTERED_RING 38 + ored into it, 39 + .I fd 40 + is instead the index of a registered ring fd. 41 + 34 42 .I opcode 35 43 can be one of: 36 44 ··· 93 101 wait for those to finish before proceeding. 94 102 95 103 An application need not unregister buffers explicitly before shutting 96 - down the io_uring instance. Available since 5.1. 104 + down the io_uring instance. Note, however, that shutdown processing may run 105 + asynchronously within the kernel. As a result, it is not guaranteed that 106 + pages are immediately unpinned in this case. Available since 5.1. 97 107 98 108 .TP 99 109 .B IORING_REGISTER_BUFFERS2 ··· 193 203 This operation takes no argument, and 194 204 .I arg 195 205 must be passed as NULL. All previously registered buffers associated 196 - with the io_uring instance will be released. Available since 5.1. 206 + with the io_uring instance will be released synchronously. Available since 5.1. 197 207 198 208 .TP 199 209 .B IORING_REGISTER_FILES ··· 620 630 size allowed is 2^15 (32768). 621 631 .I bgid 622 632 is the buffer group ID associated with this ring. SQEs that select a buffer 623 - has a buffer group associated with them in their 633 + have a buffer group associated with them in their 624 634 .I buf_group 625 - field, and the associated CQE will have 635 + field, and the associated CQEs will have 626 636 .B IORING_CQE_F_BUFFER 627 637 set in their 628 638 .I flags 629 639 member, which will also contain the specific ID of the buffer selected. The rest 630 640 of the fields are reserved and must be cleared to zero. 631 641 632 - The 633 - .I flags 634 - argument is currently unused and must be set to zero. 635 - 636 - .i nr_args 642 + .I nr_args 637 643 must be set to 1. 638 644 639 645 Also see ··· 828 834 .TP 829 835 .B EOPNOTSUPP 830 836 User buffers point to file-backed memory. 837 + .TP 838 + .B EFAULT 839 + User buffers point to file-backed memory (newer kernels).
+4 -4
vendor/opam/uring/vendor/liburing/man/io_uring_register_buf_ring.3
··· 59 59 size allowed is 2^15 (32768). 60 60 .I bgid 61 61 is the buffer group ID associated with this ring. SQEs that select a buffer 62 - has a buffer group associated with them in their 62 + have a buffer group associated with them in their 63 63 .I buf_group 64 - field, and the associated CQE will have 64 + field, and the associated CQEs will have 65 65 .B IORING_CQE_F_BUFFER 66 66 set in their 67 67 .I flags ··· 118 118 119 119 Reserved fields must not be touched. Applications must use 120 120 .BR io_uring_buf_ring_init (3) 121 - to initialise the buffer ring. Applications may use 121 + to initialise the buffer ring before use. Applications may use 122 122 .BR io_uring_buf_ring_add (3) 123 123 and 124 124 .BR io_uring_buf_ring_advance (3) 125 125 or 126 - .BR io_uring_buf_ring_advance (3) 126 + .BR io_uring_buf_ring_cq_advance (3) 127 127 to provide buffers, which will set these fields and update the tail. 128 128 129 129 Available since 5.19.
+49 -6
vendor/opam/uring/vendor/liburing/man/io_uring_register_buffers.3
··· 9 9 .nf 10 10 .B #include <liburing.h> 11 11 .PP 12 - .BI "int io_uring_register_buffers(struct io_uring *" ring ", 13 - .BI " const struct iovec *" iovecs ", 12 + .BI "int io_uring_register_buffers(struct io_uring *" ring "," 13 + .BI " const struct iovec *" iovecs "," 14 14 .BI " unsigned " nr_iovecs ");" 15 15 .PP 16 - .BI "int io_uring_register_buffers_sparse(struct io_uring *" ring ", 17 - .BI " unsigned " nr_iovecs ");" 16 + .BI "int io_uring_register_buffers_tags(struct io_uring *" ring "," 17 + .BI " const struct iovec *" iovecs "," 18 + .BI " const __u64 *" tags "," 19 + .BI " unsigned " nr ");" 20 + .PP 21 + .BI "int io_uring_register_buffers_sparse(struct io_uring *" ring "," 22 + .BI " unsigned " nr_iovecs ");" 23 + .PP 24 + .BI "int io_uring_register_buffers_update_tag(struct io_uring *" ring "," 25 + .BI " unsigned " off "," 26 + .BI " const struct iovec *" iovecs "," 27 + .BI " const __u64 *" tags "," 28 + .BI " unsigned " nr ");" 18 29 .fi 19 30 .SH DESCRIPTION 20 31 .PP ··· 28 39 .IR ring . 29 40 30 41 The 42 + .BR io_uring_register_buffers_tags (3) 43 + function behaves the same as 44 + .BR io_uring_register_buffers (3) 45 + function but additionally takes 46 + .I tags 47 + parameter. See 48 + .B IORING_REGISTER_BUFFERS2 49 + for the resource tagging description. 50 + 51 + The 31 52 .BR io_uring_register_buffers_sparse (3) 32 53 function registers 33 54 .I nr_iovecs ··· 46 67 every time IO is performed to that region. Additionally, it also avoids 47 68 manipulating the page reference counts for each IO. 48 69 70 + The 71 + .BR io_uring_register_buffers_update_tag (3) 72 + function updates registered buffers with new ones, either turning a sparse 73 + entry into a real one, or replacing an existing entry. The 74 + .I off 75 + is offset on which to start the update 76 + .I nr 77 + number of buffers defined by the array 78 + .I iovecs 79 + belonging to the 80 + .IR ring . 81 + The 82 + .I tags 83 + points to an array of tags. See 84 + .B IORING_REGISTER_BUFFERS2 85 + for the resource tagging description. 86 + 49 87 .SH RETURN VALUE 50 88 On success 51 - .BR io_uring_register_buffers (3) 89 + .BR io_uring_register_buffers (3), 90 + .BR io_uring_register_buffers_tags (3) 52 91 and 53 92 .BR io_uring_register_buffers_sparse (3) 54 - return 0. On failure they return 93 + return 0. 94 + .BR io_uring_register_buffers_update_tag (3) 95 + return number of buffers updated. 96 + On failure they return 55 97 .BR -errno . 56 98 .SH SEE ALSO 99 + .BR io_uring_register (2), 57 100 .BR io_uring_get_sqe (3), 58 101 .BR io_uring_unregister_buffers (3), 59 102 .BR io_uring_register_buf_ring (3),
+1
vendor/opam/uring/vendor/liburing/man/io_uring_register_buffers_sparse.3
··· 1 + io_uring_register_buffers.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_register_buffers_tags.3
··· 1 + io_uring_register_buffers.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_register_buffers_update_tag.3
··· 1 + io_uring_register_buffers.3
+60 -5
vendor/opam/uring/vendor/liburing/man/io_uring_register_files.3
··· 13 13 .BI " const int *" files "," 14 14 .BI " unsigned " nr_files ");" 15 15 .PP 16 + .BI "int io_uring_register_files_tags(struct io_uring *" ring "," 17 + .BI " const int *" files "," 18 + .BI " const __u64 *" tags "," 19 + .BI " unsigned " nr ");" 20 + .PP 16 21 .BI "int io_uring_register_files_sparse(struct io_uring *" ring "," 17 - .BI " unsigned " nr_files ");" 22 + .BI " unsigned " nr_files ");" 23 + .PP 24 + .BI "int io_uring_register_files_update(struct io_uring *" ring "," 25 + .BI " unsigned " off "," 26 + .BI " const int *" files "," 27 + .BI " unsigned " nr_files ");" 28 + .PP 29 + .BI "int io_uring_register_files_update_tag(struct io_uring *" ring "," 30 + .BI " unsigned " off "," 31 + .BI " const int *" files "," 32 + .BI " const __u64 *" tags "," 33 + .BI " unsigned " nr_files ");" 18 34 .fi 19 35 .SH DESCRIPTION 20 36 .PP ··· 29 45 for subsequent operations. 30 46 31 47 The 48 + .BR io_uring_register_files_tags (3) 49 + function behaves the same as 50 + .BR io_uring_register_files (3) 51 + function but additionally takes 52 + .I tags 53 + parameter. See 54 + .B IORING_REGISTER_BUFFERS2 55 + for the resource tagging description. 56 + 57 + The 32 58 .BR io_uring_register_files_sparse (3) 33 59 function registers an empty file table of 34 60 .I nr_files 35 - number of file descriptors. The sparse variant is available in kernels 5.19 36 - and later. 61 + number of file descriptors. These files must be updated before use, using eg 62 + .BR io_uring_register_files_update_tag (3). 63 + The sparse variant is available in kernels 5.19 and later. 37 64 38 65 Registering a file table is a prerequisite for using any request that uses 39 66 direct descriptors. ··· 45 72 cost goes up even more. Using registered files reduces the overhead of 46 73 file reference management across requests that operate on a file. 47 74 75 + The 76 + .BR io_uring_register_files_update (3) 77 + function updates existing registered files. The 78 + .I off 79 + is offset on which to start the update 80 + .I nr_files 81 + number of files defined by the array 82 + .I files 83 + belonging to the 84 + .IR ring . 85 + 86 + The 87 + .BR io_uring_register_files_update_tag (3) 88 + function behaves the same as 89 + .BR io_uring_register_files_update (3) 90 + function but additionally takes 91 + .I tags 92 + parameter. See 93 + .B IORING_REGISTER_BUFFERS2 94 + for the resource tagging description. 95 + 48 96 .SH RETURN VALUE 49 97 On success 50 - .BR io_uring_register_files (3) 98 + .BR io_uring_register_files (3), 99 + .BR io_uring_register_files_tags (3) 51 100 and 52 101 .BR io_uring_register_files_sparse (3) 53 - return 0. On failure they return 102 + return 0. 103 + .BR io_uring_register_files_update (3) 104 + and 105 + .BR io_uring_register_files_update_tag (3) 106 + return number of files updated. 107 + On failure they return 54 108 .BR -errno . 55 109 .SH SEE ALSO 110 + .BR io_uring_register (2), 56 111 .BR io_uring_get_sqe (3), 57 112 .BR io_uring_unregister_files (3)
+1
vendor/opam/uring/vendor/liburing/man/io_uring_register_files_tags.3
··· 1 + io_uring_register_files.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_register_files_update.3
··· 1 + io_uring_register_files.3
+1
vendor/opam/uring/vendor/liburing/man/io_uring_register_files_update_tag.3
··· 1 + io_uring_register_files.3
+35 -4
vendor/opam/uring/vendor/liburing/man/io_uring_setup.2
··· 13 13 .PP 14 14 .BI "int io_uring_setup(u32 " entries ", struct io_uring_params *" p ); 15 15 .fi 16 - .PPAA 16 + .PP 17 17 .SH DESCRIPTION 18 18 .PP 19 19 The ··· 71 71 It is illegal to mix and match polled and non-polled I/O on an io_uring 72 72 instance. 73 73 74 + This is only applicable for storage devices for now, and the storage device 75 + must be configured for polling. How to do that depends on the device type 76 + in question. For NVMe devices, the nvme driver must be loaded with the 77 + .I poll_queues 78 + parameter set to the desired number of polling queues. The polling queues 79 + will be shared appropriately between the CPUs in the system, if the number 80 + is less than the number of online CPU threads. 81 + 74 82 .TP 75 83 .B IORING_SETUP_SQPOLL 76 84 When this flag is specified, a kernel thread is created to perform ··· 119 127 described below. 120 128 .TP 121 129 .BR 130 + Note that, when using a ring setup with 131 + .B IORING_SETUP_SQPOLL, 132 + you never directly call the 133 + .BR io_uring_enter (2) 134 + system call. That is usually taken care of by liburing's 135 + .BR io_uring_submit (3) 136 + function. It automatically determines if you are using 137 + polling mode or not and deals with when your program needs to call 138 + .BR io_uring_enter (2) 139 + without you having to bother about it. 140 + .TP 141 + .BR 122 142 Before version 5.11 of the Linux kernel, to successfully use this feature, the 123 143 application must register a set of files to be used for IO through 124 144 .BR io_uring_register (2) ··· 132 152 In version 5.11 and later, it is no longer necessary to register files to use 133 153 this feature. 5.11 also allows using this as non-root, if the user has the 134 154 .B CAP_SYS_NICE 135 - capability. 155 + capability. In 5.13 this requirement was also relaxed, and no special privileges 156 + are needed for SQPOLL in newer kernels. Certain stable kernels older than 5.13 157 + may also support unprivileged SQPOLL. 136 158 .TP 137 159 .B IORING_SETUP_SQ_AFF 138 160 If this flag is specified, then the poll thread will be bound to the ··· 445 467 execution of that SQE. If this flag is set, then the kernel will defer 446 468 file assignment until execution of a given request is started. Available since 447 469 kernel 5.17. 470 + .TP 471 + .B IORING_FEAT_REG_REG_RING 472 + If this flag is set, then io_uring supports calling 473 + .BR io_uring_register (2) 474 + using a registered ring fd, via 475 + .BR IORING_REGISTER_USE_REGISTERED_RING . 476 + Available since kernel 6.3. 448 477 449 478 .PP 450 479 The rest of the fields in the ··· 498 527 .BR io_uring_setup (2). 499 528 The addition of 500 529 .I sq_off.array 501 - to the length of the region accounts for the fact that the ring 530 + to the length of the region accounts for the fact that the ring is 502 531 located at the end of the data structure. As an example, the ring 503 532 buffer head pointer can be accessed by adding 504 533 .I sq_off.head ··· 581 610 .PP 582 611 Closing the file descriptor returned by 583 612 .BR io_uring_setup (2) 584 - will free all resources associated with the io_uring context. 613 + will free all resources associated with the io_uring context. Note that this 614 + may happen asynchronously within the kernel, so it is not guaranteed that 615 + resources are freed immediately. 585 616 .PP 586 617 .SH RETURN VALUE 587 618 .BR io_uring_setup (2)
+76
vendor/opam/uring/vendor/liburing/man/io_uring_setup_buf_ring.3
··· 1 + .\" Copyright (C) 2022 Jens Axboe <axboe@kernel.dk> 2 + .\" 3 + .\" SPDX-License-Identifier: LGPL-2.0-or-later 4 + .\" 5 + .TH io_uring_setup_buf_ring 3 "Mar 07, 2023" "liburing-2.4" "liburing Manual" 6 + .SH NAME 7 + io_uring_setup_buf_ring \- setup and register buffer ring for provided buffers 8 + .SH SYNOPSIS 9 + .nf 10 + .B #include <liburing.h> 11 + .PP 12 + .BI "struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *" ring ", 13 + .BI " unsigned int " nentries ", 14 + .BI " int " bgid ", 15 + .BI " unsigned int " flags ", 16 + .BI " int *" ret ");" 17 + .BI " 18 + .fi 19 + .SH DESCRIPTION 20 + .PP 21 + The 22 + .BR io_uring_setup_buf_ring (3) 23 + function registers a shared buffer ring to be used with provided buffers. For 24 + the request types that support it, provided buffers are given to the ring and 25 + one is selected by a request if it has 26 + .B IOSQE_BUFFER_SELECT 27 + set in the SQE 28 + .IR flags , 29 + when the request is ready to receive data. This allows both clear ownership 30 + of the buffer lifetime, and a way to have more read/receive type of operations 31 + in flight than buffers available. 32 + 33 + The 34 + .I ring 35 + argument must pointer to the ring for which the provided buffer ring is being 36 + registered, 37 + .I nentries 38 + is the number of entries requested in the buffer ring. This argument must be 39 + a power-of 2 in size. 40 + .I bgid 41 + is the chosen buffer group ID, 42 + .I flags 43 + are modifier flags for the operation, and 44 + .I *ret 45 + is is a pointer to an integer for the error value if any part of the ring 46 + allocation and registration fails. 47 + 48 + The 49 + .I flags 50 + argument is currently unused and must be set to zero. 51 + 52 + Under the covers, this function uses 53 + .BR io_uring_register_buf_ring (3) 54 + to register the ring, and handles the allocation of the ring rather than 55 + letting the application open code it. 56 + 57 + To unregister and free a buffer group ID setup with this function, the 58 + application must call 59 + .BR io_uring_free_buf_ring (3) . 60 + 61 + Available since 5.19. 62 + 63 + .SH RETURN VALUE 64 + On success 65 + .BR io_uring_register_setup_ring (3) 66 + returns a pointer to the buffe ring. On failure it returns 67 + .BR NULL 68 + and sets 69 + .I *ret 70 + to -errno. 71 + .SH SEE ALSO 72 + .BR io_uring_register_buf_ring (3), 73 + .BR io_uring_buf_ring_init (3), 74 + .BR io_uring_buf_ring_add (3), 75 + .BR io_uring_buf_ring_advance (3), 76 + .BR io_uring_buf_ring_cq_advance (3)
+1
vendor/opam/uring/vendor/liburing/man/io_uring_wait_cqe.3
··· 37 37 relation to the CQE result itself. 38 38 .SH SEE ALSO 39 39 .BR io_uring_submit (3), 40 + .BR io_uring_wait_cqe_timeout (3), 40 41 .BR io_uring_wait_cqes (3)
+2 -2
vendor/opam/uring/vendor/liburing/man/io_uring_wait_cqe_timeout.3
··· 42 42 43 43 .SH RETURN VALUE 44 44 On success 45 - .BR io_uring_wait_cqes (3) 45 + .BR io_uring_wait_cqe_timeout (3) 46 46 returns 0 and the cqe_ptr param is filled in. On failure it returns 47 47 .BR -errno . 48 48 The return value indicates the result of waiting for a CQE, and it has no 49 49 relation to the CQE result itself. 50 50 .SH SEE ALSO 51 51 .BR io_uring_submit (3), 52 - .BR io_uring_wait_cqe_timeout (3), 52 + .BR io_uring_wait_cqes (3), 53 53 .BR io_uring_wait_cqe (3)
+5 -1
vendor/opam/uring/vendor/liburing/man/io_uring_wait_cqes.3
··· 32 32 33 33 The 34 34 .I cqe_ptr 35 - param is filled in on success. 35 + param is filled in on success with the first CQE. Callers of this function 36 + should use 37 + .BR io_uring_for_each_cqe (3) 38 + to iterate all available CQEs. 36 39 37 40 If 38 41 .I ts ··· 52 55 .BR -errno . 53 56 .SH SEE ALSO 54 57 .BR io_uring_submit (3), 58 + .BR io_uring_for_each_cqe (3), 55 59 .BR io_uring_wait_cqe_timeout (3), 56 60 .BR io_uring_wait_cqe (3)
+28 -6
vendor/opam/uring/vendor/liburing/src/Makefile
··· 8 8 LIBURING_CFLAGS ?= 9 9 CPPFLAGS ?= 10 10 override CPPFLAGS += -D_GNU_SOURCE \ 11 - -Iinclude/ -include ../config-host.h 11 + -Iinclude/ -include ../config-host.h \ 12 + -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 12 13 CFLAGS ?= -g -O3 -Wall -Wextra -fno-stack-protector 13 - override CFLAGS += -Wno-unused-parameter -Wno-sign-compare \ 14 + override CFLAGS += -Wno-unused-parameter \ 14 15 -DLIBURING_INTERNAL \ 15 16 $(LIBURING_CFLAGS) 16 17 SO_CFLAGS=-fPIC $(CFLAGS) ··· 21 22 22 23 soname=liburing.so.$(VERSION_MAJOR) 23 24 libname=liburing.so.$(VERSION) 25 + ffi_soname=liburing-ffi.so.$(VERSION_MAJOR) 26 + ffi_libname=liburing-ffi.so.$(VERSION) 27 + 24 28 all_targets += liburing.a 29 + all_targets += liburing-ffi.a 25 30 26 31 ifeq ($(ENABLE_SHARED),1) 27 32 all_targets += $(libname) 33 + all_targets += $(ffi_libname) 28 34 endif 29 35 30 36 include ../Makefile.quiet ··· 35 41 36 42 all: $(all_targets) 37 43 38 - liburing_srcs := setup.c queue.c register.c syscall.c 44 + liburing_srcs := setup.c queue.c register.c syscall.c version.c 39 45 40 46 ifeq ($(CONFIG_NOLIBC),y) 41 47 liburing_srcs += nolibc.c 42 - override CFLAGS += -nostdlib -nodefaultlibs -ffreestanding 43 - override CPPFLAGS += -nostdlib -nodefaultlibs -ffreestanding 48 + override CFLAGS += -nostdlib -nodefaultlibs -ffreestanding -fno-builtin 49 + override CPPFLAGS += -nostdlib -nodefaultlibs -ffreestanding -fno-builtin 44 50 override LINK_FLAGS += -nostdlib -nodefaultlibs 45 51 endif 46 52 47 53 override CPPFLAGS += -MT "$@" -MMD -MP -MF "$@.d" 48 54 liburing_objs := $(patsubst %.c,%.ol,$(liburing_srcs)) 49 55 liburing_sobjs := $(patsubst %.c,%.os,$(liburing_srcs)) 56 + liburing_ffi_objs := ffi.ol 57 + liburing_ffi_sobjs := ffi.os 50 58 51 59 %.os: %.c 52 60 $(QUIET_CC)$(CC) $(CPPFLAGS) $(SO_CFLAGS) -c -o $@ $< ··· 65 73 $(QUIET_AR)$(AR) r liburing.a $^ 66 74 $(QUIET_RANLIB)$(RANLIB) liburing.a 67 75 76 + liburing-ffi.a: $(liburing_objs) $(liburing_ffi_objs) 77 + @rm -f liburing-ffi.a 78 + $(QUIET_AR)$(AR) r liburing-ffi.a $^ 79 + $(QUIET_RANLIB)$(RANLIB) liburing-ffi.a 80 + 68 81 $(libname): $(liburing_sobjs) liburing.map 69 82 $(QUIET_CC)$(CC) $(SO_CFLAGS) -shared -Wl,--version-script=liburing.map -Wl,-soname=$(soname) -o $@ $(liburing_sobjs) $(LINK_FLAGS) 83 + 84 + $(ffi_libname): $(liburing_ffi_objs) $(liburing_ffi_sobjs) liburing-ffi.map 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) 70 86 71 87 install: $(all_targets) 72 88 install -D -m 644 include/liburing/io_uring.h $(includedir)/liburing/io_uring.h 73 89 install -D -m 644 include/liburing.h $(includedir)/liburing.h 74 90 install -D -m 644 include/liburing/compat.h $(includedir)/liburing/compat.h 75 91 install -D -m 644 include/liburing/barrier.h $(includedir)/liburing/barrier.h 92 + install -D -m 644 include/liburing/io_uring_version.h $(includedir)/liburing/io_uring_version.h 76 93 install -D -m 644 liburing.a $(libdevdir)/liburing.a 94 + install -D -m 644 liburing-ffi.a $(libdevdir)/liburing-ffi.a 77 95 ifeq ($(ENABLE_SHARED),1) 78 96 install -D -m 755 $(libname) $(libdir)/$(libname) 97 + install -D -m 755 $(ffi_libname) $(libdir)/$(ffi_libname) 79 98 ln -sf $(libname) $(libdir)/$(soname) 80 99 ln -sf $(relativelibdir)$(libname) $(libdevdir)/liburing.so 100 + ln -sf $(ffi_libname) $(libdir)/$(ffi_soname) 101 + ln -sf $(relativelibdir)$(ffi_libname) $(libdevdir)/liburing-ffi.so 81 102 endif 82 103 83 104 clean: 84 - @rm -f $(all_targets) $(liburing_objs) $(liburing_sobjs) $(soname).new 105 + @rm -f $(all_targets) $(liburing_objs) $(liburing_sobjs) $(liburing_ffi_objs) $(liburing_ffi_sobjs) $(soname).new 85 106 @rm -f *.so* *.a *.o *.d 86 107 @rm -f include/liburing/compat.h 108 + @rm -f include/liburing/io_uring_version.h 87 109 88 110 @# When cleaning, we don't include ../config-host.mak, 89 111 @# so the nolibc objects are always skipped, clean them up!
+1 -1
vendor/opam/uring/vendor/liburing/src/arch/aarch64/lib.h
··· 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) {
+15
vendor/opam/uring/vendor/liburing/src/ffi.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + #define IOURINGINLINE 3 + 4 + #ifdef __clang__ 5 + // clang doesn't seem to particularly like that we're including a header that 6 + // deliberately contains function definitions so we explicitly silence it 7 + #pragma clang diagnostic push 8 + #pragma clang diagnostic ignored "-Wmissing-prototypes" 9 + #endif 10 + 11 + #include "liburing.h" 12 + 13 + #ifdef __clang__ 14 + #pragma clang diagnostic pop 15 + #endif
+249 -158
vendor/opam/uring/vendor/liburing/src/include/liburing.h
··· 23 23 #include <linux/swab.h> 24 24 #include "liburing/compat.h" 25 25 #include "liburing/io_uring.h" 26 + #include "liburing/io_uring_version.h" 26 27 #include "liburing/barrier.h" 27 28 28 29 #ifndef uring_unlikely ··· 31 32 32 33 #ifndef uring_likely 33 34 #define uring_likely(cond) __builtin_expect(!!(cond), 1) 35 + #endif 36 + 37 + #ifndef IOURINGINLINE 38 + #define IOURINGINLINE static inline 34 39 #endif 35 40 36 41 #ifdef __alpha__ ··· 151 156 */ 152 157 void io_uring_free_probe(struct io_uring_probe *probe); 153 158 154 - static inline int io_uring_opcode_supported(const struct io_uring_probe *p, 159 + IOURINGINLINE int io_uring_opcode_supported(const struct io_uring_probe *p, 155 160 int op) 156 161 { 157 162 if (op > p->last_op) ··· 226 231 unsigned int *values); 227 232 int io_uring_register_ring_fd(struct io_uring *ring); 228 233 int io_uring_unregister_ring_fd(struct io_uring *ring); 234 + int io_uring_close_ring_fd(struct io_uring *ring); 229 235 int io_uring_register_buf_ring(struct io_uring *ring, 230 236 struct io_uring_buf_reg *reg, unsigned int flags); 231 237 int io_uring_unregister_buf_ring(struct io_uring *ring, int bgid); ··· 251 257 unsigned int nr_args); 252 258 253 259 /* 260 + * Mapped buffer ring alloc/register + unregister/free helpers 261 + */ 262 + struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *ring, 263 + unsigned int nentries, 264 + int bgid, unsigned int flags, 265 + int *ret); 266 + int io_uring_free_buf_ring(struct io_uring *ring, struct io_uring_buf_ring *br, 267 + unsigned int nentries, int bgid); 268 + 269 + /* 254 270 * Helper for the peek/wait single cqe functions. Exported because of that, 255 271 * but probably shouldn't be used directly in an application. 256 272 */ ··· 283 299 /* 284 300 * Must be called after io_uring_for_each_cqe() 285 301 */ 286 - static inline void io_uring_cq_advance(struct io_uring *ring, 287 - unsigned nr) 302 + IOURINGINLINE void io_uring_cq_advance(struct io_uring *ring, unsigned nr) 288 303 { 289 304 if (nr) { 290 305 struct io_uring_cq *cq = &ring->cq; ··· 301 316 * Must be called after io_uring_{peek,wait}_cqe() after the cqe has 302 317 * been processed by the application. 303 318 */ 304 - static inline void io_uring_cqe_seen(struct io_uring *ring, 319 + IOURINGINLINE void io_uring_cqe_seen(struct io_uring *ring, 305 320 struct io_uring_cqe *cqe) 306 321 { 307 322 if (cqe) ··· 316 331 * Associate pointer @data with the sqe, for later retrieval from the cqe 317 332 * at command completion time with io_uring_cqe_get_data(). 318 333 */ 319 - static inline void io_uring_sqe_set_data(struct io_uring_sqe *sqe, void *data) 334 + IOURINGINLINE void io_uring_sqe_set_data(struct io_uring_sqe *sqe, void *data) 320 335 { 321 336 sqe->user_data = (unsigned long) data; 322 337 } 323 338 324 - static inline void *io_uring_cqe_get_data(const struct io_uring_cqe *cqe) 339 + IOURINGINLINE void *io_uring_cqe_get_data(const struct io_uring_cqe *cqe) 325 340 { 326 341 return (void *) (uintptr_t) cqe->user_data; 327 342 } ··· 331 346 * time with io_uring_cqe_get_data64. Just like the non-64 variants, except 332 347 * these store a 64-bit type rather than a data pointer. 333 348 */ 334 - static inline void io_uring_sqe_set_data64(struct io_uring_sqe *sqe, 349 + IOURINGINLINE void io_uring_sqe_set_data64(struct io_uring_sqe *sqe, 335 350 __u64 data) 336 351 { 337 352 sqe->user_data = data; 338 353 } 339 354 340 - static inline __u64 io_uring_cqe_get_data64(const struct io_uring_cqe *cqe) 355 + IOURINGINLINE __u64 io_uring_cqe_get_data64(const struct io_uring_cqe *cqe) 341 356 { 342 357 return cqe->user_data; 343 358 } ··· 347 362 */ 348 363 #define LIBURING_HAVE_DATA64 349 364 350 - static inline void io_uring_sqe_set_flags(struct io_uring_sqe *sqe, 365 + IOURINGINLINE void io_uring_sqe_set_flags(struct io_uring_sqe *sqe, 351 366 unsigned flags) 352 367 { 353 368 sqe->flags = (__u8) flags; 354 369 } 355 370 356 - static inline void __io_uring_set_target_fixed_file(struct io_uring_sqe *sqe, 371 + IOURINGINLINE void __io_uring_set_target_fixed_file(struct io_uring_sqe *sqe, 357 372 unsigned int file_index) 358 373 { 359 374 /* 0 means no fixed files, indexes should be encoded as "index + 1" */ 360 375 sqe->file_index = file_index + 1; 361 376 } 362 377 363 - static inline void io_uring_prep_rw(int op, struct io_uring_sqe *sqe, int fd, 378 + IOURINGINLINE void io_uring_prep_rw(int op, struct io_uring_sqe *sqe, int fd, 364 379 const void *addr, unsigned len, 365 380 __u64 offset) 366 381 { ··· 379 394 sqe->__pad2[0] = 0; 380 395 } 381 396 382 - /** 383 - * @pre Either fd_in or fd_out must be a pipe. 384 - * @param off_in If fd_in refers to a pipe, off_in must be (int64_t) -1; 385 - * If fd_in does not refer to a pipe and off_in is (int64_t) -1, 386 - * then bytes are read from fd_in starting from the file offset 387 - * and it is adjust appropriately; 388 - * If fd_in does not refer to a pipe and off_in is not 389 - * (int64_t) -1, then the starting offset of fd_in will be 390 - * off_in. 391 - * @param off_out The description of off_in also applied to off_out. 392 - * @param splice_flags see man splice(2) for description of flags. 397 + /* 398 + * io_uring_prep_splice() - Either @fd_in or @fd_out must be a pipe. 399 + * 400 + * - If @fd_in refers to a pipe, @off_in is ignored and must be set to -1. 401 + * 402 + * - If @fd_in does not refer to a pipe and @off_in is -1, then @nbytes are read 403 + * from @fd_in starting from the file offset, which is incremented by the 404 + * number of bytes read. 405 + * 406 + * - If @fd_in does not refer to a pipe and @off_in is not -1, then the starting 407 + * offset of @fd_in will be @off_in. 393 408 * 394 409 * This splice operation can be used to implement sendfile by splicing to an 395 410 * intermediate pipe first, then splice to the final destination. 396 411 * In fact, the implementation of sendfile in kernel uses splice internally. 397 412 * 398 413 * NOTE that even if fd_in or fd_out refers to a pipe, the splice operation 399 - * can still failed with EINVAL if one of the fd doesn't explicitly support 400 - * splice operation, e.g. reading from terminal is unsupported from kernel 5.7 401 - * to 5.11. 414 + * can still fail with EINVAL if one of the fd doesn't explicitly support splice 415 + * operation, e.g. reading from terminal is unsupported from kernel 5.7 to 5.11. 402 416 * Check issue #291 for more information. 403 417 */ 404 - static inline void io_uring_prep_splice(struct io_uring_sqe *sqe, 418 + IOURINGINLINE void io_uring_prep_splice(struct io_uring_sqe *sqe, 405 419 int fd_in, int64_t off_in, 406 420 int fd_out, int64_t off_out, 407 421 unsigned int nbytes, ··· 414 428 sqe->splice_flags = splice_flags; 415 429 } 416 430 417 - static inline void io_uring_prep_tee(struct io_uring_sqe *sqe, 431 + IOURINGINLINE void io_uring_prep_tee(struct io_uring_sqe *sqe, 418 432 int fd_in, int fd_out, 419 433 unsigned int nbytes, 420 434 unsigned int splice_flags) ··· 425 439 sqe->splice_flags = splice_flags; 426 440 } 427 441 428 - static inline void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd, 442 + IOURINGINLINE void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd, 429 443 const struct iovec *iovecs, 430 444 unsigned nr_vecs, __u64 offset) 431 445 { 432 446 io_uring_prep_rw(IORING_OP_READV, sqe, fd, iovecs, nr_vecs, offset); 433 447 } 434 448 435 - static inline void io_uring_prep_readv2(struct io_uring_sqe *sqe, int fd, 449 + IOURINGINLINE void io_uring_prep_readv2(struct io_uring_sqe *sqe, int fd, 436 450 const struct iovec *iovecs, 437 451 unsigned nr_vecs, __u64 offset, 438 452 int flags) ··· 441 455 sqe->rw_flags = flags; 442 456 } 443 457 444 - static inline void io_uring_prep_read_fixed(struct io_uring_sqe *sqe, int fd, 458 + IOURINGINLINE void io_uring_prep_read_fixed(struct io_uring_sqe *sqe, int fd, 445 459 void *buf, unsigned nbytes, 446 460 __u64 offset, int buf_index) 447 461 { ··· 449 463 sqe->buf_index = (__u16) buf_index; 450 464 } 451 465 452 - static inline void io_uring_prep_writev(struct io_uring_sqe *sqe, int fd, 466 + IOURINGINLINE void io_uring_prep_writev(struct io_uring_sqe *sqe, int fd, 453 467 const struct iovec *iovecs, 454 468 unsigned nr_vecs, __u64 offset) 455 469 { 456 470 io_uring_prep_rw(IORING_OP_WRITEV, sqe, fd, iovecs, nr_vecs, offset); 457 471 } 458 472 459 - static inline void io_uring_prep_writev2(struct io_uring_sqe *sqe, int fd, 473 + IOURINGINLINE void io_uring_prep_writev2(struct io_uring_sqe *sqe, int fd, 460 474 const struct iovec *iovecs, 461 475 unsigned nr_vecs, __u64 offset, 462 476 int flags) ··· 465 479 sqe->rw_flags = flags; 466 480 } 467 481 468 - static inline void io_uring_prep_write_fixed(struct io_uring_sqe *sqe, int fd, 482 + IOURINGINLINE void io_uring_prep_write_fixed(struct io_uring_sqe *sqe, int fd, 469 483 const void *buf, unsigned nbytes, 470 484 __u64 offset, int buf_index) 471 485 { ··· 473 487 sqe->buf_index = (__u16) buf_index; 474 488 } 475 489 476 - static inline void io_uring_prep_recvmsg(struct io_uring_sqe *sqe, int fd, 490 + IOURINGINLINE void io_uring_prep_recvmsg(struct io_uring_sqe *sqe, int fd, 477 491 struct msghdr *msg, unsigned flags) 478 492 { 479 493 io_uring_prep_rw(IORING_OP_RECVMSG, sqe, fd, msg, 1, 0); 480 494 sqe->msg_flags = flags; 481 495 } 482 496 483 - static inline void io_uring_prep_recvmsg_multishot(struct io_uring_sqe *sqe, int fd, 484 - struct msghdr *msg, unsigned flags) 497 + IOURINGINLINE void io_uring_prep_recvmsg_multishot(struct io_uring_sqe *sqe, 498 + int fd, struct msghdr *msg, 499 + unsigned flags) 485 500 { 486 501 io_uring_prep_recvmsg(sqe, fd, msg, flags); 487 502 sqe->ioprio |= IORING_RECV_MULTISHOT; 488 503 } 489 504 490 - static inline void io_uring_prep_sendmsg(struct io_uring_sqe *sqe, int fd, 505 + IOURINGINLINE void io_uring_prep_sendmsg(struct io_uring_sqe *sqe, int fd, 491 506 const struct msghdr *msg, 492 507 unsigned flags) 493 508 { ··· 495 510 sqe->msg_flags = flags; 496 511 } 497 512 498 - static inline unsigned __io_uring_prep_poll_mask(unsigned poll_mask) 513 + IOURINGINLINE unsigned __io_uring_prep_poll_mask(unsigned poll_mask) 499 514 { 500 515 #if __BYTE_ORDER == __BIG_ENDIAN 501 516 poll_mask = __swahw32(poll_mask); ··· 503 518 return poll_mask; 504 519 } 505 520 506 - static inline void io_uring_prep_poll_add(struct io_uring_sqe *sqe, int fd, 521 + IOURINGINLINE void io_uring_prep_poll_add(struct io_uring_sqe *sqe, int fd, 507 522 unsigned poll_mask) 508 523 { 509 524 io_uring_prep_rw(IORING_OP_POLL_ADD, sqe, fd, NULL, 0, 0); 510 525 sqe->poll32_events = __io_uring_prep_poll_mask(poll_mask); 511 526 } 512 527 513 - static inline void io_uring_prep_poll_multishot(struct io_uring_sqe *sqe, 528 + IOURINGINLINE void io_uring_prep_poll_multishot(struct io_uring_sqe *sqe, 514 529 int fd, unsigned poll_mask) 515 530 { 516 531 io_uring_prep_poll_add(sqe, fd, poll_mask); 517 532 sqe->len = IORING_POLL_ADD_MULTI; 518 533 } 519 534 520 - static inline void io_uring_prep_poll_remove(struct io_uring_sqe *sqe, 535 + IOURINGINLINE void io_uring_prep_poll_remove(struct io_uring_sqe *sqe, 521 536 __u64 user_data) 522 537 { 523 538 io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, NULL, 0, 0); 524 539 sqe->addr = user_data; 525 540 } 526 541 527 - static inline void io_uring_prep_poll_update(struct io_uring_sqe *sqe, 542 + IOURINGINLINE void io_uring_prep_poll_update(struct io_uring_sqe *sqe, 528 543 __u64 old_user_data, 529 544 __u64 new_user_data, 530 545 unsigned poll_mask, unsigned flags) ··· 535 550 sqe->poll32_events = __io_uring_prep_poll_mask(poll_mask); 536 551 } 537 552 538 - static inline void io_uring_prep_fsync(struct io_uring_sqe *sqe, int fd, 553 + IOURINGINLINE void io_uring_prep_fsync(struct io_uring_sqe *sqe, int fd, 539 554 unsigned fsync_flags) 540 555 { 541 556 io_uring_prep_rw(IORING_OP_FSYNC, sqe, fd, NULL, 0, 0); 542 557 sqe->fsync_flags = fsync_flags; 543 558 } 544 559 545 - static inline void io_uring_prep_nop(struct io_uring_sqe *sqe) 560 + IOURINGINLINE void io_uring_prep_nop(struct io_uring_sqe *sqe) 546 561 { 547 562 io_uring_prep_rw(IORING_OP_NOP, sqe, -1, NULL, 0, 0); 548 563 } 549 564 550 - static inline void io_uring_prep_timeout(struct io_uring_sqe *sqe, 565 + IOURINGINLINE void io_uring_prep_timeout(struct io_uring_sqe *sqe, 551 566 struct __kernel_timespec *ts, 552 567 unsigned count, unsigned flags) 553 568 { ··· 555 570 sqe->timeout_flags = flags; 556 571 } 557 572 558 - static inline void io_uring_prep_timeout_remove(struct io_uring_sqe *sqe, 573 + IOURINGINLINE void io_uring_prep_timeout_remove(struct io_uring_sqe *sqe, 559 574 __u64 user_data, unsigned flags) 560 575 { 561 576 io_uring_prep_rw(IORING_OP_TIMEOUT_REMOVE, sqe, -1, NULL, 0, 0); ··· 563 578 sqe->timeout_flags = flags; 564 579 } 565 580 566 - static inline void io_uring_prep_timeout_update(struct io_uring_sqe *sqe, 581 + IOURINGINLINE void io_uring_prep_timeout_update(struct io_uring_sqe *sqe, 567 582 struct __kernel_timespec *ts, 568 583 __u64 user_data, unsigned flags) 569 584 { ··· 573 588 sqe->timeout_flags = flags | IORING_TIMEOUT_UPDATE; 574 589 } 575 590 576 - static inline void io_uring_prep_accept(struct io_uring_sqe *sqe, int fd, 591 + IOURINGINLINE void io_uring_prep_accept(struct io_uring_sqe *sqe, int fd, 577 592 struct sockaddr *addr, 578 593 socklen_t *addrlen, int flags) 579 594 { ··· 583 598 } 584 599 585 600 /* accept directly into the fixed file table */ 586 - static inline void io_uring_prep_accept_direct(struct io_uring_sqe *sqe, int fd, 601 + IOURINGINLINE void io_uring_prep_accept_direct(struct io_uring_sqe *sqe, int fd, 587 602 struct sockaddr *addr, 588 603 socklen_t *addrlen, int flags, 589 604 unsigned int file_index) 590 605 { 591 606 io_uring_prep_accept(sqe, fd, addr, addrlen, flags); 607 + /* offset by 1 for allocation */ 608 + if (file_index == IORING_FILE_INDEX_ALLOC) 609 + file_index--; 592 610 __io_uring_set_target_fixed_file(sqe, file_index); 593 611 } 594 612 595 - static inline void io_uring_prep_multishot_accept(struct io_uring_sqe *sqe, 613 + IOURINGINLINE void io_uring_prep_multishot_accept(struct io_uring_sqe *sqe, 596 614 int fd, struct sockaddr *addr, 597 615 socklen_t *addrlen, int flags) 598 616 { ··· 601 619 } 602 620 603 621 /* multishot accept directly into the fixed file table */ 604 - static inline void io_uring_prep_multishot_accept_direct(struct io_uring_sqe *sqe, 622 + IOURINGINLINE void io_uring_prep_multishot_accept_direct(struct io_uring_sqe *sqe, 605 623 int fd, 606 624 struct sockaddr *addr, 607 625 socklen_t *addrlen, ··· 611 629 __io_uring_set_target_fixed_file(sqe, IORING_FILE_INDEX_ALLOC - 1); 612 630 } 613 631 614 - static inline void io_uring_prep_cancel64(struct io_uring_sqe *sqe, 632 + IOURINGINLINE void io_uring_prep_cancel64(struct io_uring_sqe *sqe, 615 633 __u64 user_data, int flags) 616 634 { 617 635 io_uring_prep_rw(IORING_OP_ASYNC_CANCEL, sqe, -1, NULL, 0, 0); ··· 619 637 sqe->cancel_flags = (__u32) flags; 620 638 } 621 639 622 - static inline void io_uring_prep_cancel(struct io_uring_sqe *sqe, 640 + IOURINGINLINE void io_uring_prep_cancel(struct io_uring_sqe *sqe, 623 641 void *user_data, int flags) 624 642 { 625 643 io_uring_prep_cancel64(sqe, (__u64) (uintptr_t) user_data, flags); 626 644 } 627 645 628 - static inline void io_uring_prep_cancel_fd(struct io_uring_sqe *sqe, int fd, 646 + IOURINGINLINE void io_uring_prep_cancel_fd(struct io_uring_sqe *sqe, int fd, 629 647 unsigned int flags) 630 648 { 631 649 io_uring_prep_rw(IORING_OP_ASYNC_CANCEL, sqe, fd, NULL, 0, 0); 632 650 sqe->cancel_flags = (__u32) flags | IORING_ASYNC_CANCEL_FD; 633 651 } 634 652 635 - static inline void io_uring_prep_link_timeout(struct io_uring_sqe *sqe, 653 + IOURINGINLINE void io_uring_prep_link_timeout(struct io_uring_sqe *sqe, 636 654 struct __kernel_timespec *ts, 637 655 unsigned flags) 638 656 { ··· 640 658 sqe->timeout_flags = flags; 641 659 } 642 660 643 - static inline void io_uring_prep_connect(struct io_uring_sqe *sqe, int fd, 661 + IOURINGINLINE void io_uring_prep_connect(struct io_uring_sqe *sqe, int fd, 644 662 const struct sockaddr *addr, 645 663 socklen_t addrlen) 646 664 { 647 665 io_uring_prep_rw(IORING_OP_CONNECT, sqe, fd, addr, 0, addrlen); 648 666 } 649 667 650 - static inline void io_uring_prep_files_update(struct io_uring_sqe *sqe, 668 + IOURINGINLINE void io_uring_prep_files_update(struct io_uring_sqe *sqe, 651 669 int *fds, unsigned nr_fds, 652 670 int offset) 653 671 { ··· 655 673 (__u64) offset); 656 674 } 657 675 658 - static inline void io_uring_prep_fallocate(struct io_uring_sqe *sqe, int fd, 659 - int mode, off_t offset, off_t len) 676 + IOURINGINLINE void io_uring_prep_fallocate(struct io_uring_sqe *sqe, int fd, 677 + int mode, __u64 offset, __u64 len) 660 678 { 661 679 io_uring_prep_rw(IORING_OP_FALLOCATE, sqe, fd, 662 680 0, (unsigned int) mode, (__u64) offset); 663 681 sqe->addr = (__u64) len; 664 682 } 665 683 666 - static inline void io_uring_prep_openat(struct io_uring_sqe *sqe, int dfd, 684 + IOURINGINLINE void io_uring_prep_openat(struct io_uring_sqe *sqe, int dfd, 667 685 const char *path, int flags, 668 686 mode_t mode) 669 687 { ··· 672 690 } 673 691 674 692 /* open directly into the fixed file table */ 675 - static inline void io_uring_prep_openat_direct(struct io_uring_sqe *sqe, 693 + IOURINGINLINE void io_uring_prep_openat_direct(struct io_uring_sqe *sqe, 676 694 int dfd, const char *path, 677 695 int flags, mode_t mode, 678 696 unsigned file_index) 679 697 { 680 698 io_uring_prep_openat(sqe, dfd, path, flags, mode); 699 + /* offset by 1 for allocation */ 700 + if (file_index == IORING_FILE_INDEX_ALLOC) 701 + file_index--; 681 702 __io_uring_set_target_fixed_file(sqe, file_index); 682 703 } 683 704 684 - static inline void io_uring_prep_close(struct io_uring_sqe *sqe, int fd) 705 + IOURINGINLINE void io_uring_prep_close(struct io_uring_sqe *sqe, int fd) 685 706 { 686 707 io_uring_prep_rw(IORING_OP_CLOSE, sqe, fd, NULL, 0, 0); 687 708 } 688 709 689 - static inline void io_uring_prep_close_direct(struct io_uring_sqe *sqe, 710 + IOURINGINLINE void io_uring_prep_close_direct(struct io_uring_sqe *sqe, 690 711 unsigned file_index) 691 712 { 692 713 io_uring_prep_close(sqe, 0); 693 714 __io_uring_set_target_fixed_file(sqe, file_index); 694 715 } 695 716 696 - static inline void io_uring_prep_read(struct io_uring_sqe *sqe, int fd, 717 + IOURINGINLINE void io_uring_prep_read(struct io_uring_sqe *sqe, int fd, 697 718 void *buf, unsigned nbytes, __u64 offset) 698 719 { 699 720 io_uring_prep_rw(IORING_OP_READ, sqe, fd, buf, nbytes, offset); 700 721 } 701 722 702 - static inline void io_uring_prep_write(struct io_uring_sqe *sqe, int fd, 723 + IOURINGINLINE void io_uring_prep_write(struct io_uring_sqe *sqe, int fd, 703 724 const void *buf, unsigned nbytes, 704 725 __u64 offset) 705 726 { ··· 707 728 } 708 729 709 730 struct statx; 710 - static inline void io_uring_prep_statx(struct io_uring_sqe *sqe, int dfd, 711 - const char *path, int flags, unsigned mask, 712 - struct statx *statxbuf) 731 + IOURINGINLINE void io_uring_prep_statx(struct io_uring_sqe *sqe, int dfd, 732 + const char *path, int flags, 733 + unsigned mask, struct statx *statxbuf) 713 734 { 714 735 io_uring_prep_rw(IORING_OP_STATX, sqe, dfd, path, mask, 715 736 (__u64) (unsigned long) statxbuf); 716 737 sqe->statx_flags = (__u32) flags; 717 738 } 718 739 719 - static inline void io_uring_prep_fadvise(struct io_uring_sqe *sqe, int fd, 740 + IOURINGINLINE void io_uring_prep_fadvise(struct io_uring_sqe *sqe, int fd, 720 741 __u64 offset, off_t len, int advice) 721 742 { 722 743 io_uring_prep_rw(IORING_OP_FADVISE, sqe, fd, NULL, (__u32) len, offset); 723 744 sqe->fadvise_advice = (__u32) advice; 724 745 } 725 746 726 - static inline void io_uring_prep_madvise(struct io_uring_sqe *sqe, void *addr, 747 + IOURINGINLINE void io_uring_prep_madvise(struct io_uring_sqe *sqe, void *addr, 727 748 off_t length, int advice) 728 749 { 729 750 io_uring_prep_rw(IORING_OP_MADVISE, sqe, -1, addr, (__u32) length, 0); 730 751 sqe->fadvise_advice = (__u32) advice; 731 752 } 732 753 733 - static inline void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd, 754 + IOURINGINLINE void io_uring_prep_send(struct io_uring_sqe *sqe, int sockfd, 734 755 const void *buf, size_t len, int flags) 735 756 { 736 757 io_uring_prep_rw(IORING_OP_SEND, sqe, sockfd, buf, (__u32) len, 0); 737 758 sqe->msg_flags = (__u32) flags; 738 759 } 739 760 740 - static inline void io_uring_prep_send_zc(struct io_uring_sqe *sqe, int sockfd, 761 + IOURINGINLINE void io_uring_prep_send_set_addr(struct io_uring_sqe *sqe, 762 + const struct sockaddr *dest_addr, 763 + __u16 addr_len) 764 + { 765 + sqe->addr2 = (unsigned long)(const void *)dest_addr; 766 + sqe->addr_len = addr_len; 767 + } 768 + 769 + IOURINGINLINE void io_uring_prep_sendto(struct io_uring_sqe *sqe, int sockfd, 770 + const void *buf, size_t len, int flags, 771 + const struct sockaddr *addr, 772 + socklen_t addrlen) 773 + { 774 + io_uring_prep_send(sqe, sockfd, buf, len, flags); 775 + io_uring_prep_send_set_addr(sqe, addr, addrlen); 776 + } 777 + 778 + IOURINGINLINE void io_uring_prep_send_zc(struct io_uring_sqe *sqe, int sockfd, 741 779 const void *buf, size_t len, int flags, 742 780 unsigned zc_flags) 743 781 { ··· 746 784 sqe->ioprio = zc_flags; 747 785 } 748 786 749 - static inline void io_uring_prep_send_zc_fixed(struct io_uring_sqe *sqe, 787 + IOURINGINLINE void io_uring_prep_send_zc_fixed(struct io_uring_sqe *sqe, 750 788 int sockfd, const void *buf, 751 789 size_t len, int flags, 752 790 unsigned zc_flags, ··· 757 795 sqe->buf_index = buf_index; 758 796 } 759 797 760 - static inline void io_uring_prep_sendmsg_zc(struct io_uring_sqe *sqe, int fd, 798 + IOURINGINLINE void io_uring_prep_sendmsg_zc(struct io_uring_sqe *sqe, int fd, 761 799 const struct msghdr *msg, 762 800 unsigned flags) 763 801 { ··· 765 803 sqe->opcode = IORING_OP_SENDMSG_ZC; 766 804 } 767 805 768 - static inline void io_uring_prep_send_set_addr(struct io_uring_sqe *sqe, 769 - const struct sockaddr *dest_addr, 770 - __u16 addr_len) 771 - { 772 - sqe->addr2 = (unsigned long)(const void *)dest_addr; 773 - sqe->addr_len = addr_len; 774 - } 775 - 776 - static inline void io_uring_prep_recv(struct io_uring_sqe *sqe, int sockfd, 806 + IOURINGINLINE void io_uring_prep_recv(struct io_uring_sqe *sqe, int sockfd, 777 807 void *buf, size_t len, int flags) 778 808 { 779 809 io_uring_prep_rw(IORING_OP_RECV, sqe, sockfd, buf, (__u32) len, 0); 780 810 sqe->msg_flags = (__u32) flags; 781 811 } 782 812 783 - static inline void io_uring_prep_recv_multishot(struct io_uring_sqe *sqe, 813 + IOURINGINLINE void io_uring_prep_recv_multishot(struct io_uring_sqe *sqe, 784 814 int sockfd, void *buf, 785 815 size_t len, int flags) 786 816 { ··· 788 818 sqe->ioprio |= IORING_RECV_MULTISHOT; 789 819 } 790 820 791 - static inline struct io_uring_recvmsg_out * 821 + IOURINGINLINE struct io_uring_recvmsg_out * 792 822 io_uring_recvmsg_validate(void *buf, int buf_len, struct msghdr *msgh) 793 823 { 794 824 unsigned long header = msgh->msg_controllen + msgh->msg_namelen + ··· 798 828 return (struct io_uring_recvmsg_out *)buf; 799 829 } 800 830 801 - static inline void *io_uring_recvmsg_name(struct io_uring_recvmsg_out *o) 831 + IOURINGINLINE void *io_uring_recvmsg_name(struct io_uring_recvmsg_out *o) 802 832 { 803 833 return (void *) &o[1]; 804 834 } 805 835 806 - static inline struct cmsghdr * 836 + IOURINGINLINE struct cmsghdr * 807 837 io_uring_recvmsg_cmsg_firsthdr(struct io_uring_recvmsg_out *o, 808 838 struct msghdr *msgh) 809 839 { ··· 814 844 msgh->msg_namelen); 815 845 } 816 846 817 - static inline struct cmsghdr * 847 + IOURINGINLINE struct cmsghdr * 818 848 io_uring_recvmsg_cmsg_nexthdr(struct io_uring_recvmsg_out *o, struct msghdr *msgh, 819 849 struct cmsghdr *cmsg) 820 850 { ··· 835 865 return cmsg; 836 866 } 837 867 838 - static inline void *io_uring_recvmsg_payload(struct io_uring_recvmsg_out *o, 868 + IOURINGINLINE void *io_uring_recvmsg_payload(struct io_uring_recvmsg_out *o, 839 869 struct msghdr *msgh) 840 870 { 841 871 return (void *)((unsigned char *)io_uring_recvmsg_name(o) + 842 872 msgh->msg_namelen + msgh->msg_controllen); 843 873 } 844 874 845 - static inline unsigned int 875 + IOURINGINLINE unsigned int 846 876 io_uring_recvmsg_payload_length(struct io_uring_recvmsg_out *o, 847 877 int buf_len, struct msghdr *msgh) 848 878 { ··· 853 883 return (unsigned int) (payload_end - payload_start); 854 884 } 855 885 856 - static inline void io_uring_prep_openat2(struct io_uring_sqe *sqe, int dfd, 886 + IOURINGINLINE void io_uring_prep_openat2(struct io_uring_sqe *sqe, int dfd, 857 887 const char *path, struct open_how *how) 858 888 { 859 889 io_uring_prep_rw(IORING_OP_OPENAT2, sqe, dfd, path, sizeof(*how), ··· 861 891 } 862 892 863 893 /* open directly into the fixed file table */ 864 - static inline void io_uring_prep_openat2_direct(struct io_uring_sqe *sqe, 894 + IOURINGINLINE void io_uring_prep_openat2_direct(struct io_uring_sqe *sqe, 865 895 int dfd, const char *path, 866 896 struct open_how *how, 867 897 unsigned file_index) 868 898 { 869 899 io_uring_prep_openat2(sqe, dfd, path, how); 900 + /* offset by 1 for allocation */ 901 + if (file_index == IORING_FILE_INDEX_ALLOC) 902 + file_index--; 870 903 __io_uring_set_target_fixed_file(sqe, file_index); 871 904 } 872 905 873 906 struct epoll_event; 874 - static inline void io_uring_prep_epoll_ctl(struct io_uring_sqe *sqe, int epfd, 907 + IOURINGINLINE void io_uring_prep_epoll_ctl(struct io_uring_sqe *sqe, int epfd, 875 908 int fd, int op, 876 909 struct epoll_event *ev) 877 910 { ··· 879 912 (__u32) op, (__u32) fd); 880 913 } 881 914 882 - static inline void io_uring_prep_provide_buffers(struct io_uring_sqe *sqe, 915 + IOURINGINLINE void io_uring_prep_provide_buffers(struct io_uring_sqe *sqe, 883 916 void *addr, int len, int nr, 884 917 int bgid, int bid) 885 918 { ··· 888 921 sqe->buf_group = (__u16) bgid; 889 922 } 890 923 891 - static inline void io_uring_prep_remove_buffers(struct io_uring_sqe *sqe, 924 + IOURINGINLINE void io_uring_prep_remove_buffers(struct io_uring_sqe *sqe, 892 925 int nr, int bgid) 893 926 { 894 927 io_uring_prep_rw(IORING_OP_REMOVE_BUFFERS, sqe, nr, NULL, 0, 0); 895 928 sqe->buf_group = (__u16) bgid; 896 929 } 897 930 898 - static inline void io_uring_prep_shutdown(struct io_uring_sqe *sqe, int fd, 931 + IOURINGINLINE void io_uring_prep_shutdown(struct io_uring_sqe *sqe, int fd, 899 932 int how) 900 933 { 901 934 io_uring_prep_rw(IORING_OP_SHUTDOWN, sqe, fd, NULL, (__u32) how, 0); 902 935 } 903 936 904 - static inline void io_uring_prep_unlinkat(struct io_uring_sqe *sqe, int dfd, 937 + IOURINGINLINE void io_uring_prep_unlinkat(struct io_uring_sqe *sqe, int dfd, 905 938 const char *path, int flags) 906 939 { 907 940 io_uring_prep_rw(IORING_OP_UNLINKAT, sqe, dfd, path, 0, 0); 908 941 sqe->unlink_flags = (__u32) flags; 909 942 } 910 943 911 - static inline void io_uring_prep_unlink(struct io_uring_sqe *sqe, 944 + IOURINGINLINE void io_uring_prep_unlink(struct io_uring_sqe *sqe, 912 945 const char *path, int flags) 913 946 { 914 947 io_uring_prep_unlinkat(sqe, AT_FDCWD, path, flags); 915 948 } 916 949 917 - static inline void io_uring_prep_renameat(struct io_uring_sqe *sqe, int olddfd, 950 + IOURINGINLINE void io_uring_prep_renameat(struct io_uring_sqe *sqe, int olddfd, 918 951 const char *oldpath, int newdfd, 919 952 const char *newpath, unsigned int flags) 920 953 { ··· 924 957 sqe->rename_flags = (__u32) flags; 925 958 } 926 959 927 - static inline void io_uring_prep_rename(struct io_uring_sqe *sqe, 928 - const char *oldpath, const char *newpath) 960 + IOURINGINLINE void io_uring_prep_rename(struct io_uring_sqe *sqe, 961 + const char *oldpath, 962 + const char *newpath) 929 963 { 930 964 io_uring_prep_renameat(sqe, AT_FDCWD, oldpath, AT_FDCWD, newpath, 0); 931 965 } 932 966 933 - static inline void io_uring_prep_sync_file_range(struct io_uring_sqe *sqe, 967 + IOURINGINLINE void io_uring_prep_sync_file_range(struct io_uring_sqe *sqe, 934 968 int fd, unsigned len, 935 969 __u64 offset, int flags) 936 970 { ··· 938 972 sqe->sync_range_flags = (__u32) flags; 939 973 } 940 974 941 - static inline void io_uring_prep_mkdirat(struct io_uring_sqe *sqe, int dfd, 975 + IOURINGINLINE void io_uring_prep_mkdirat(struct io_uring_sqe *sqe, int dfd, 942 976 const char *path, mode_t mode) 943 977 { 944 978 io_uring_prep_rw(IORING_OP_MKDIRAT, sqe, dfd, path, mode, 0); 945 979 } 946 980 947 - static inline void io_uring_prep_mkdir(struct io_uring_sqe *sqe, 981 + IOURINGINLINE void io_uring_prep_mkdir(struct io_uring_sqe *sqe, 948 982 const char *path, mode_t mode) 949 983 { 950 984 io_uring_prep_mkdirat(sqe, AT_FDCWD, path, mode); 951 985 } 952 986 953 - static inline void io_uring_prep_symlinkat(struct io_uring_sqe *sqe, 987 + IOURINGINLINE void io_uring_prep_symlinkat(struct io_uring_sqe *sqe, 954 988 const char *target, int newdirfd, 955 989 const char *linkpath) 956 990 { ··· 958 992 (uint64_t) (uintptr_t) linkpath); 959 993 } 960 994 961 - static inline void io_uring_prep_symlink(struct io_uring_sqe *sqe, 962 - const char *target, const char *linkpath) 995 + IOURINGINLINE void io_uring_prep_symlink(struct io_uring_sqe *sqe, 996 + const char *target, 997 + const char *linkpath) 963 998 { 964 999 io_uring_prep_symlinkat(sqe, target, AT_FDCWD, linkpath); 965 1000 } 966 1001 967 - static inline void io_uring_prep_linkat(struct io_uring_sqe *sqe, int olddfd, 1002 + IOURINGINLINE void io_uring_prep_linkat(struct io_uring_sqe *sqe, int olddfd, 968 1003 const char *oldpath, int newdfd, 969 1004 const char *newpath, int flags) 970 1005 { ··· 973 1008 sqe->hardlink_flags = (__u32) flags; 974 1009 } 975 1010 976 - static inline void io_uring_prep_link(struct io_uring_sqe *sqe, 977 - const char *oldpath, const char *newpath, int flags) 1011 + IOURINGINLINE void io_uring_prep_link(struct io_uring_sqe *sqe, 1012 + const char *oldpath, const char *newpath, 1013 + int flags) 978 1014 { 979 1015 io_uring_prep_linkat(sqe, AT_FDCWD, oldpath, AT_FDCWD, newpath, flags); 980 1016 } 981 1017 982 - static inline void io_uring_prep_msg_ring(struct io_uring_sqe *sqe, int fd, 1018 + IOURINGINLINE void io_uring_prep_msg_ring_cqe_flags(struct io_uring_sqe *sqe, 1019 + int fd, unsigned int len, __u64 data, 1020 + unsigned int flags, unsigned int cqe_flags) 1021 + { 1022 + io_uring_prep_rw(IORING_OP_MSG_RING, sqe, fd, NULL, len, data); 1023 + sqe->msg_ring_flags = IORING_MSG_RING_FLAGS_PASS | flags; 1024 + sqe->file_index = cqe_flags; 1025 + } 1026 + 1027 + IOURINGINLINE void io_uring_prep_msg_ring(struct io_uring_sqe *sqe, int fd, 983 1028 unsigned int len, __u64 data, 984 1029 unsigned int flags) 985 1030 { 986 1031 io_uring_prep_rw(IORING_OP_MSG_RING, sqe, fd, NULL, len, data); 987 - sqe->rw_flags = flags; 1032 + sqe->msg_ring_flags = flags; 1033 + } 1034 + 1035 + IOURINGINLINE void io_uring_prep_msg_ring_fd(struct io_uring_sqe *sqe, int fd, 1036 + int source_fd, int target_fd, 1037 + __u64 data, unsigned int flags) 1038 + { 1039 + io_uring_prep_rw(IORING_OP_MSG_RING, sqe, fd, 1040 + (void *) (uintptr_t) IORING_MSG_SEND_FD, 0, data); 1041 + sqe->addr3 = source_fd; 1042 + /* offset by 1 for allocation */ 1043 + if ((unsigned int) target_fd == IORING_FILE_INDEX_ALLOC) 1044 + target_fd--; 1045 + __io_uring_set_target_fixed_file(sqe, target_fd); 1046 + sqe->msg_ring_flags = flags; 1047 + } 1048 + 1049 + IOURINGINLINE void io_uring_prep_msg_ring_fd_alloc(struct io_uring_sqe *sqe, 1050 + int fd, int source_fd, 1051 + __u64 data, unsigned int flags) 1052 + { 1053 + io_uring_prep_msg_ring_fd(sqe, fd, source_fd, IORING_FILE_INDEX_ALLOC, 1054 + data, flags); 988 1055 } 989 1056 990 - static inline void io_uring_prep_getxattr(struct io_uring_sqe *sqe, 991 - const char *name, 992 - char *value, 993 - const char *path, 994 - unsigned int len) 1057 + IOURINGINLINE void io_uring_prep_getxattr(struct io_uring_sqe *sqe, 1058 + const char *name, char *value, 1059 + const char *path, unsigned int len) 995 1060 { 996 1061 io_uring_prep_rw(IORING_OP_GETXATTR, sqe, 0, name, len, 997 1062 (__u64) (uintptr_t) value); ··· 999 1064 sqe->xattr_flags = 0; 1000 1065 } 1001 1066 1002 - static inline void io_uring_prep_setxattr(struct io_uring_sqe *sqe, 1003 - const char *name, 1004 - const char *value, 1005 - const char *path, 1006 - int flags, 1067 + IOURINGINLINE void io_uring_prep_setxattr(struct io_uring_sqe *sqe, 1068 + const char *name, const char *value, 1069 + const char *path, int flags, 1007 1070 unsigned int len) 1008 1071 { 1009 1072 io_uring_prep_rw(IORING_OP_SETXATTR, sqe, 0, name, len, ··· 1012 1075 sqe->xattr_flags = flags; 1013 1076 } 1014 1077 1015 - static inline void io_uring_prep_fgetxattr(struct io_uring_sqe *sqe, 1016 - int fd, 1017 - const char *name, 1018 - char *value, 1019 - unsigned int len) 1078 + IOURINGINLINE void io_uring_prep_fgetxattr(struct io_uring_sqe *sqe, 1079 + int fd, const char *name, 1080 + char *value, unsigned int len) 1020 1081 { 1021 1082 io_uring_prep_rw(IORING_OP_FGETXATTR, sqe, fd, name, len, 1022 1083 (__u64) (uintptr_t) value); 1023 1084 sqe->xattr_flags = 0; 1024 1085 } 1025 1086 1026 - static inline void io_uring_prep_fsetxattr(struct io_uring_sqe *sqe, 1027 - int fd, 1028 - const char *name, 1029 - const char *value, 1030 - int flags, 1031 - unsigned int len) 1087 + IOURINGINLINE void io_uring_prep_fsetxattr(struct io_uring_sqe *sqe, int fd, 1088 + const char *name, const char *value, 1089 + int flags, unsigned int len) 1032 1090 { 1033 1091 io_uring_prep_rw(IORING_OP_FSETXATTR, sqe, fd, name, len, 1034 1092 (__u64) (uintptr_t) value); 1035 1093 sqe->xattr_flags = flags; 1036 1094 } 1037 1095 1038 - static inline void io_uring_prep_socket(struct io_uring_sqe *sqe, int domain, 1096 + IOURINGINLINE void io_uring_prep_socket(struct io_uring_sqe *sqe, int domain, 1039 1097 int type, int protocol, 1040 1098 unsigned int flags) 1041 1099 { ··· 1043 1101 sqe->rw_flags = flags; 1044 1102 } 1045 1103 1046 - static inline void io_uring_prep_socket_direct(struct io_uring_sqe *sqe, 1104 + IOURINGINLINE void io_uring_prep_socket_direct(struct io_uring_sqe *sqe, 1047 1105 int domain, int type, 1048 1106 int protocol, 1049 1107 unsigned file_index, ··· 1051 1109 { 1052 1110 io_uring_prep_rw(IORING_OP_SOCKET, sqe, domain, NULL, protocol, type); 1053 1111 sqe->rw_flags = flags; 1112 + /* offset by 1 for allocation */ 1113 + if (file_index == IORING_FILE_INDEX_ALLOC) 1114 + file_index--; 1054 1115 __io_uring_set_target_fixed_file(sqe, file_index); 1055 1116 } 1056 1117 1057 - static inline void io_uring_prep_socket_direct_alloc(struct io_uring_sqe *sqe, 1058 - int domain, int type, int protocol, 1059 - unsigned int flags) 1118 + IOURINGINLINE void io_uring_prep_socket_direct_alloc(struct io_uring_sqe *sqe, 1119 + int domain, int type, 1120 + int protocol, 1121 + unsigned int flags) 1060 1122 { 1061 1123 io_uring_prep_rw(IORING_OP_SOCKET, sqe, domain, NULL, protocol, type); 1062 1124 sqe->rw_flags = flags; ··· 1067 1129 * Returns number of unconsumed (if SQPOLL) or unsubmitted entries exist in 1068 1130 * the SQ ring 1069 1131 */ 1070 - static inline unsigned io_uring_sq_ready(const struct io_uring *ring) 1132 + IOURINGINLINE unsigned io_uring_sq_ready(const struct io_uring *ring) 1071 1133 { 1072 1134 unsigned khead = *ring->sq.khead; 1073 1135 ··· 1086 1148 /* 1087 1149 * Returns how much space is left in the SQ ring. 1088 1150 */ 1089 - static inline unsigned io_uring_sq_space_left(const struct io_uring *ring) 1151 + IOURINGINLINE unsigned io_uring_sq_space_left(const struct io_uring *ring) 1090 1152 { 1091 1153 return ring->sq.ring_entries - io_uring_sq_ready(ring); 1092 1154 } ··· 1098 1160 * action is taken. Note: may return -EINVAL if the kernel doesn't support 1099 1161 * this feature. 1100 1162 */ 1101 - static inline int io_uring_sqring_wait(struct io_uring *ring) 1163 + IOURINGINLINE int io_uring_sqring_wait(struct io_uring *ring) 1102 1164 { 1103 1165 if (!(ring->flags & IORING_SETUP_SQPOLL)) 1104 1166 return 0; ··· 1111 1173 /* 1112 1174 * Returns how many unconsumed entries are ready in the CQ ring 1113 1175 */ 1114 - static inline unsigned io_uring_cq_ready(const struct io_uring *ring) 1176 + IOURINGINLINE unsigned io_uring_cq_ready(const struct io_uring *ring) 1115 1177 { 1116 1178 return io_uring_smp_load_acquire(ring->cq.ktail) - *ring->cq.khead; 1117 1179 } ··· 1120 1182 * Returns true if there are overflow entries waiting to be flushed onto 1121 1183 * the CQ ring 1122 1184 */ 1123 - static inline bool io_uring_cq_has_overflow(const struct io_uring *ring) 1185 + IOURINGINLINE bool io_uring_cq_has_overflow(const struct io_uring *ring) 1124 1186 { 1125 1187 return IO_URING_READ_ONCE(*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW; 1126 1188 } ··· 1128 1190 /* 1129 1191 * Returns true if the eventfd notification is currently enabled 1130 1192 */ 1131 - static inline bool io_uring_cq_eventfd_enabled(const struct io_uring *ring) 1193 + IOURINGINLINE bool io_uring_cq_eventfd_enabled(const struct io_uring *ring) 1132 1194 { 1133 1195 if (!ring->cq.kflags) 1134 1196 return true; ··· 1140 1202 * Toggle eventfd notification on or off, if an eventfd is registered with 1141 1203 * the ring. 1142 1204 */ 1143 - static inline int io_uring_cq_eventfd_toggle(struct io_uring *ring, 1205 + IOURINGINLINE int io_uring_cq_eventfd_toggle(struct io_uring *ring, 1144 1206 bool enabled) 1145 1207 { 1146 1208 uint32_t flags; ··· 1168 1230 * readily available. Returns 0 with cqe_ptr filled in on success, -errno on 1169 1231 * failure. 1170 1232 */ 1171 - static inline int io_uring_wait_cqe_nr(struct io_uring *ring, 1233 + IOURINGINLINE int io_uring_wait_cqe_nr(struct io_uring *ring, 1172 1234 struct io_uring_cqe **cqe_ptr, 1173 1235 unsigned wait_nr) 1174 1236 { ··· 1180 1242 * "official" versions of this, io_uring_peek_cqe(), io_uring_wait_cqe(), 1181 1243 * or io_uring_wait_cqes*(). 1182 1244 */ 1183 - static inline int __io_uring_peek_cqe(struct io_uring *ring, 1245 + IOURINGINLINE int __io_uring_peek_cqe(struct io_uring *ring, 1184 1246 struct io_uring_cqe **cqe_ptr, 1185 1247 unsigned *nr_available) 1186 1248 { ··· 1226 1288 * Return an IO completion, if one is readily available. Returns 0 with 1227 1289 * cqe_ptr filled in on success, -errno on failure. 1228 1290 */ 1229 - static inline int io_uring_peek_cqe(struct io_uring *ring, 1291 + IOURINGINLINE int io_uring_peek_cqe(struct io_uring *ring, 1230 1292 struct io_uring_cqe **cqe_ptr) 1231 1293 { 1232 1294 if (!__io_uring_peek_cqe(ring, cqe_ptr, NULL) && *cqe_ptr) ··· 1239 1301 * Return an IO completion, waiting for it if necessary. Returns 0 with 1240 1302 * cqe_ptr filled in on success, -errno on failure. 1241 1303 */ 1242 - static inline int io_uring_wait_cqe(struct io_uring *ring, 1304 + IOURINGINLINE int io_uring_wait_cqe(struct io_uring *ring, 1243 1305 struct io_uring_cqe **cqe_ptr) 1244 1306 { 1245 1307 if (!__io_uring_peek_cqe(ring, cqe_ptr, NULL) && *cqe_ptr) ··· 1255 1317 * 1256 1318 * Returns a vacant sqe, or NULL if we're full. 1257 1319 */ 1258 - static inline struct io_uring_sqe *_io_uring_get_sqe(struct io_uring *ring) 1320 + IOURINGINLINE struct io_uring_sqe *_io_uring_get_sqe(struct io_uring *ring) 1259 1321 { 1260 1322 struct io_uring_sq *sq = &ring->sq; 1261 1323 unsigned int head, next = sq->sqe_tail + 1; ··· 1282 1344 /* 1283 1345 * Return the appropriate mask for a buffer ring of size 'ring_entries' 1284 1346 */ 1285 - static inline int io_uring_buf_ring_mask(__u32 ring_entries) 1347 + IOURINGINLINE int io_uring_buf_ring_mask(__u32 ring_entries) 1286 1348 { 1287 1349 return ring_entries - 1; 1288 1350 } 1289 1351 1290 - static inline void io_uring_buf_ring_init(struct io_uring_buf_ring *br) 1352 + IOURINGINLINE void io_uring_buf_ring_init(struct io_uring_buf_ring *br) 1291 1353 { 1292 1354 br->tail = 0; 1293 1355 } ··· 1295 1357 /* 1296 1358 * Assign 'buf' with the addr/len/buffer ID supplied 1297 1359 */ 1298 - static inline void io_uring_buf_ring_add(struct io_uring_buf_ring *br, 1360 + IOURINGINLINE void io_uring_buf_ring_add(struct io_uring_buf_ring *br, 1299 1361 void *addr, unsigned int len, 1300 1362 unsigned short bid, int mask, 1301 1363 int buf_offset) ··· 1312 1374 * io_uring_buf_ring_add() has been called 'count' times to fill in new 1313 1375 * buffers. 1314 1376 */ 1315 - static inline void io_uring_buf_ring_advance(struct io_uring_buf_ring *br, 1377 + IOURINGINLINE void io_uring_buf_ring_advance(struct io_uring_buf_ring *br, 1316 1378 int count) 1317 1379 { 1318 1380 unsigned short new_tail = br->tail + count; ··· 1320 1382 io_uring_smp_store_release(&br->tail, new_tail); 1321 1383 } 1322 1384 1385 + IOURINGINLINE void __io_uring_buf_ring_cq_advance(struct io_uring *ring, 1386 + struct io_uring_buf_ring *br, 1387 + int cq_count, int buf_count) 1388 + { 1389 + br->tail += buf_count; 1390 + io_uring_cq_advance(ring, cq_count); 1391 + } 1392 + 1323 1393 /* 1324 1394 * Make 'count' new buffers visible to the kernel while at the same time 1325 1395 * advancing the CQ ring seen entries. This can be used when the application ··· 1327 1397 * avoiding an extra atomic when needing to increment both the CQ ring and 1328 1398 * the ring buffer index at the same time. 1329 1399 */ 1330 - static inline void io_uring_buf_ring_cq_advance(struct io_uring *ring, 1400 + IOURINGINLINE void io_uring_buf_ring_cq_advance(struct io_uring *ring, 1331 1401 struct io_uring_buf_ring *br, 1332 1402 int count) 1333 1403 { 1334 - br->tail += count; 1335 - io_uring_cq_advance(ring, count); 1404 + __io_uring_buf_ring_cq_advance(ring, br, count, count); 1336 1405 } 1337 1406 1338 1407 #ifndef LIBURING_INTERNAL 1339 - static inline struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring) 1408 + IOURINGINLINE struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring) 1340 1409 { 1341 1410 return _io_uring_get_sqe(ring); 1342 1411 } ··· 1347 1416 ssize_t io_uring_mlock_size(unsigned entries, unsigned flags); 1348 1417 ssize_t io_uring_mlock_size_params(unsigned entries, struct io_uring_params *p); 1349 1418 1419 + /* 1420 + * Versioning information for liburing. 1421 + * 1422 + * Use IO_URING_CHECK_VERSION() for compile time checks including from 1423 + * preprocessor directives. 1424 + * 1425 + * Use io_uring_check_version() for runtime checks of the version of 1426 + * liburing that was loaded by the dynamic linker. 1427 + */ 1428 + int io_uring_major_version(void); 1429 + int io_uring_minor_version(void); 1430 + bool io_uring_check_version(int major, int minor); 1431 + 1432 + #define IO_URING_CHECK_VERSION(major,minor) \ 1433 + (major > IO_URING_VERSION_MAJOR || \ 1434 + (major == IO_URING_VERSION_MAJOR && \ 1435 + minor >= IO_URING_VERSION_MINOR)) 1436 + 1350 1437 #ifdef __cplusplus 1351 1438 } 1439 + #endif 1440 + 1441 + #ifdef IOURINGINLINE 1442 + #undef IOURINGINLINE 1352 1443 #endif 1353 1444 1354 1445 #endif
+49 -21
vendor/opam/uring/vendor/liburing/src/include/liburing/io_uring.h
··· 12 12 #include <linux/types.h> 13 13 /* 14 14 * this file is shared with liburing and that has to autodetect 15 - * if linux/time_types.h is available 15 + * if linux/time_types.h is available or not, it can 16 + * define UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 17 + * if linux/time_types.h is not available 16 18 */ 17 - #ifdef __KERNEL__ 18 - #define HAVE_LINUX_TIME_TYPES_H 1 19 - #endif 20 - #ifdef HAVE_LINUX_TIME_TYPES_H 19 + #ifndef UAPI_LINUX_IO_URING_H_SKIP_LINUX_TIME_TYPES_H 21 20 #include <linux/time_types.h> 22 21 #endif 23 22 ··· 231 230 232 231 /* 233 232 * sqe->uring_cmd_flags 234 - * IORING_URING_CMD_FIXED use registered buffer; pass thig flag 233 + * IORING_URING_CMD_FIXED use registered buffer; pass this flag 235 234 * along with setting sqe->buf_index. 236 235 */ 237 236 #define IORING_URING_CMD_FIXED (1U << 0) ··· 251 250 #define IORING_TIMEOUT_REALTIME (1U << 3) 252 251 #define IORING_LINK_TIMEOUT_UPDATE (1U << 4) 253 252 #define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5) 253 + #define IORING_TIMEOUT_MULTISHOT (1U << 6) 254 254 #define IORING_TIMEOUT_CLOCK_MASK (IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME) 255 255 #define IORING_TIMEOUT_UPDATE_MASK (IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE) 256 256 /* ··· 305 305 * 306 306 * IORING_RECVSEND_FIXED_BUF Use registered buffers, the index is stored in 307 307 * the buf_index field. 308 + * 309 + * IORING_SEND_ZC_REPORT_USAGE 310 + * If set, SEND[MSG]_ZC should report 311 + * the zerocopy usage in cqe.res 312 + * for the IORING_CQE_F_NOTIF cqe. 313 + * 0 is reported if zerocopy was actually possible. 314 + * IORING_NOTIF_USAGE_ZC_COPIED if data was copied 315 + * (at least partially). 308 316 */ 309 317 #define IORING_RECVSEND_POLL_FIRST (1U << 0) 310 318 #define IORING_RECV_MULTISHOT (1U << 1) 311 319 #define IORING_RECVSEND_FIXED_BUF (1U << 2) 320 + #define IORING_SEND_ZC_REPORT_USAGE (1U << 3) 321 + 322 + /* 323 + * cqe.res for IORING_CQE_F_NOTIF if 324 + * IORING_SEND_ZC_REPORT_USAGE was requested 325 + * 326 + * It should be treated as a flag, all other 327 + * bits of cqe.res should be treated as reserved! 328 + */ 329 + #define IORING_NOTIF_USAGE_ZC_COPIED (1U << 31) 312 330 313 331 /* 314 332 * accept flags stored in sqe->ioprio ··· 330 348 * applicable for IORING_MSG_DATA, obviously. 331 349 */ 332 350 #define IORING_MSG_RING_CQE_SKIP (1U << 0) 351 + /* Pass through the flags from sqe->file_index to cqe->flags */ 352 + #define IORING_MSG_RING_FLAGS_PASS (1U << 1) 333 353 334 354 /* 335 355 * IO completion data structure (Completion Queue Entry) ··· 370 390 #define IORING_OFF_SQ_RING 0ULL 371 391 #define IORING_OFF_CQ_RING 0x8000000ULL 372 392 #define IORING_OFF_SQES 0x10000000ULL 393 + #define IORING_OFF_PBUF_RING 0x80000000ULL 394 + #define IORING_OFF_PBUF_SHIFT 16 395 + #define IORING_OFF_MMAP_MASK 0xf8000000ULL 373 396 374 397 /* 375 398 * Filled with the offset for mmap(2) ··· 453 476 #define IORING_FEAT_RSRC_TAGS (1U << 10) 454 477 #define IORING_FEAT_CQE_SKIP (1U << 11) 455 478 #define IORING_FEAT_LINKED_FILE (1U << 12) 479 + #define IORING_FEAT_REG_REG_RING (1U << 13) 456 480 457 481 /* 458 482 * io_uring_register(2) opcodes and arguments ··· 500 524 IORING_REGISTER_FILE_ALLOC_RANGE = 25, 501 525 502 526 /* this goes last */ 503 - IORING_REGISTER_LAST 527 + IORING_REGISTER_LAST, 528 + 529 + /* flag added to the opcode to use a registered ring fd */ 530 + IORING_REGISTER_USE_REGISTERED_RING = 1U << 31 504 531 }; 505 532 506 533 /* io-wq worker categories */ ··· 545 572 __u32 resv2; 546 573 }; 547 574 548 - struct io_uring_notification_slot { 549 - __u64 tag; 550 - __u64 resv[3]; 551 - }; 552 - 553 - struct io_uring_notification_register { 554 - __u32 nr_slots; 555 - __u32 resv; 556 - __u64 resv2; 557 - __u64 data; 558 - __u64 resv3; 559 - }; 560 - 561 575 /* Skip updating fd indexes set to this value in the fd table */ 562 576 #define IORING_REGISTER_FILES_SKIP (-2) 563 577 ··· 612 626 }; 613 627 }; 614 628 629 + /* 630 + * Flags for IORING_REGISTER_PBUF_RING. 631 + * 632 + * IOU_PBUF_RING_MMAP: If set, kernel will allocate the memory for the ring. 633 + * The application must not set a ring_addr in struct 634 + * io_uring_buf_reg, instead it must subsequently call 635 + * mmap(2) with the offset set as: 636 + * IORING_OFF_PBUF_RING | (bgid << IORING_OFF_PBUF_SHIFT) 637 + * to get a virtual mapping for the ring. 638 + */ 639 + enum { 640 + IOU_PBUF_RING_MMAP = 1, 641 + }; 642 + 615 643 /* argument for IORING_(UN)REGISTER_PBUF_RING */ 616 644 struct io_uring_buf_reg { 617 645 __u64 ring_addr; 618 646 __u32 ring_entries; 619 647 __u16 bgid; 620 - __u16 pad; 648 + __u16 flags; 621 649 __u64 resv[3]; 622 650 }; 623 651
+1
vendor/opam/uring/vendor/liburing/src/int_flags.h
··· 4 4 5 5 enum { 6 6 INT_FLAG_REG_RING = 1, 7 + INT_FLAG_REG_REG_RING = 2, 7 8 }; 8 9 9 10 #endif
+5 -16
vendor/opam/uring/vendor/liburing/src/lib.h
··· 37 37 #define __hot __attribute__((__hot__)) 38 38 #define __cold __attribute__((__cold__)) 39 39 40 + #ifdef CONFIG_NOLIBC 41 + void *__uring_memset(void *s, int c, size_t n); 40 42 void *__uring_malloc(size_t len); 41 43 void __uring_free(void *p); 42 44 43 - static inline void *uring_malloc(size_t len) 44 - { 45 - #ifdef CONFIG_NOLIBC 46 - return __uring_malloc(len); 47 - #else 48 - return malloc(len); 45 + #define malloc(LEN) __uring_malloc(LEN) 46 + #define free(PTR) __uring_free(PTR) 47 + #define memset(PTR, C, LEN) __uring_memset(PTR, C, LEN) 49 48 #endif 50 - } 51 - 52 - static inline void uring_free(void *ptr) 53 - { 54 - #ifdef CONFIG_NOLIBC 55 - __uring_free(ptr); 56 - #else 57 - free(ptr); 58 - #endif 59 - } 60 49 61 50 #endif /* #ifndef LIBURING_LIB_H */
+177
vendor/opam/uring/vendor/liburing/src/liburing-ffi.map
··· 1 + LIBURING_2.4 { 2 + global: 3 + io_uring_get_probe; 4 + io_uring_get_probe_ring; 5 + io_uring_free_probe; 6 + io_uring_get_sqe; 7 + io_uring_peek_batch_cqe; 8 + io_uring_queue_exit; 9 + io_uring_queue_init; 10 + io_uring_queue_init_params; 11 + io_uring_queue_mmap; 12 + io_uring_register_buffers; 13 + io_uring_register_eventfd; 14 + io_uring_register_eventfd_async; 15 + io_uring_register_files; 16 + io_uring_register_files_update; 17 + io_uring_register_personality; 18 + io_uring_register_probe; 19 + io_uring_ring_dontfork; 20 + io_uring_submit; 21 + io_uring_submit_and_wait; 22 + io_uring_unregister_buffers; 23 + io_uring_unregister_eventfd; 24 + io_uring_unregister_files; 25 + io_uring_unregister_personality; 26 + io_uring_wait_cqe_timeout; 27 + io_uring_wait_cqes; 28 + 29 + __io_uring_get_cqe; 30 + __io_uring_sqring_wait; 31 + 32 + io_uring_mlock_size_params; 33 + io_uring_mlock_size; 34 + io_uring_register_buffers_tags; 35 + io_uring_register_buffers_update_tag; 36 + io_uring_register_files_tags; 37 + io_uring_register_files_update_tag; 38 + io_uring_register_iowq_aff; 39 + io_uring_unregister_iowq_aff; 40 + io_uring_register_iowq_max_workers; 41 + 42 + io_uring_submit_and_wait_timeout; 43 + io_uring_register_ring_fd; 44 + io_uring_unregister_ring_fd; 45 + io_uring_register_files_sparse; 46 + io_uring_register_buffers_sparse; 47 + io_uring_register_buf_ring; 48 + io_uring_unregister_buf_ring; 49 + io_uring_close_ring_fd; 50 + io_uring_setup_buf_ring; 51 + io_uring_free_buf_ring; 52 + 53 + io_uring_register_sync_cancel; 54 + io_uring_register_file_alloc_range; 55 + io_uring_enter; 56 + io_uring_enter2; 57 + io_uring_setup; 58 + io_uring_register; 59 + io_uring_get_events; 60 + io_uring_submit_and_get_events; 61 + 62 + io_uring_major_version; 63 + io_uring_minor_version; 64 + io_uring_check_version; 65 + 66 + io_uring_peek_cqe; 67 + io_uring_prep_timeout_update; 68 + io_uring_buf_ring_init; 69 + io_uring_prep_mkdirat; 70 + io_uring_prep_recv_multishot; 71 + io_uring_cq_advance; 72 + io_uring_prep_multishot_accept; 73 + io_uring_prep_fallocate; 74 + io_uring_prep_link_timeout; 75 + io_uring_prep_fsync; 76 + io_uring_prep_openat_direct; 77 + io_uring_prep_multishot_accept_direct; 78 + io_uring_opcode_supported; 79 + io_uring_prep_madvise; 80 + io_uring_prep_send_set_addr; 81 + io_uring_recvmsg_payload_length; 82 + io_uring_prep_readv2; 83 + io_uring_prep_msg_ring; 84 + io_uring_prep_rename; 85 + io_uring_prep_fadvise; 86 + io_uring_prep_send_zc; 87 + io_uring_buf_ring_advance; 88 + io_uring_cqe_get_data; 89 + io_uring_prep_symlinkat; 90 + io_uring_prep_writev; 91 + io_uring_cq_eventfd_toggle; 92 + io_uring_prep_provide_buffers; 93 + io_uring_cq_has_overflow; 94 + io_uring_prep_cancel_fd; 95 + io_uring_prep_socket; 96 + io_uring_prep_close_direct; 97 + io_uring_recvmsg_name; 98 + io_uring_prep_timeout_remove; 99 + io_uring_sqring_wait; 100 + io_uring_cq_eventfd_enabled; 101 + io_uring_prep_remove_buffers; 102 + io_uring_prep_tee; 103 + io_uring_prep_accept_direct; 104 + io_uring_prep_nop; 105 + io_uring_prep_getxattr; 106 + io_uring_prep_link; 107 + io_uring_prep_cancel; 108 + io_uring_prep_readv; 109 + io_uring_prep_connect; 110 + io_uring_cq_ready; 111 + io_uring_enable_rings; 112 + io_uring_prep_shutdown; 113 + io_uring_prep_openat; 114 + io_uring_sq_space_left; 115 + io_uring_recvmsg_payload; 116 + io_uring_prep_send; 117 + io_uring_buf_ring_add; 118 + io_uring_prep_send_zc_fixed; 119 + io_uring_prep_epoll_ctl; 120 + io_uring_recvmsg_cmsg_firsthdr; 121 + io_uring_prep_socket_direct; 122 + io_uring_buf_ring_cq_advance; 123 + __io_uring_buf_ring_cq_advance; 124 + io_uring_prep_mkdir; 125 + io_uring_wait_cqe_nr; 126 + io_uring_prep_unlink; 127 + io_uring_prep_writev2; 128 + io_uring_prep_openat2_direct; 129 + io_uring_sqe_set_flags; 130 + io_uring_sqe_set_data; 131 + io_uring_prep_accept; 132 + io_uring_prep_poll_update; 133 + io_uring_prep_splice; 134 + io_uring_prep_poll_multishot; 135 + io_uring_prep_symlink; 136 + io_uring_sqe_set_data64; 137 + io_uring_prep_cancel64; 138 + io_uring_prep_fsetxattr; 139 + io_uring_prep_recvmsg_multishot; 140 + io_uring_cqe_seen; 141 + io_uring_prep_sendmsg_zc; 142 + io_uring_prep_read; 143 + io_uring_prep_statx; 144 + io_uring_prep_sendmsg; 145 + io_uring_prep_unlinkat; 146 + io_uring_prep_setxattr; 147 + io_uring_cqe_get_data64; 148 + io_uring_prep_renameat; 149 + io_uring_prep_poll_remove; 150 + io_uring_prep_close; 151 + io_uring_sq_ready; 152 + io_uring_prep_files_update; 153 + io_uring_wait_cqe; 154 + io_uring_prep_fgetxattr; 155 + io_uring_prep_socket_direct_alloc; 156 + io_uring_prep_sync_file_range; 157 + io_uring_prep_read_fixed; 158 + io_uring_prep_openat2; 159 + io_uring_prep_recvmsg; 160 + io_uring_recvmsg_cmsg_nexthdr; 161 + io_uring_recvmsg_validate; 162 + io_uring_prep_rw; 163 + io_uring_prep_timeout; 164 + io_uring_prep_linkat; 165 + io_uring_prep_write_fixed; 166 + io_uring_prep_poll_add; 167 + io_uring_buf_ring_mask; 168 + io_uring_register_restrictions; 169 + io_uring_prep_write; 170 + io_uring_prep_recv; 171 + io_uring_prep_msg_ring_cqe_flags; 172 + io_uring_prep_msg_ring_fd; 173 + io_uring_prep_msg_ring_fd_alloc; 174 + io_uring_prep_sendto; 175 + local: 176 + *; 177 + };
+13
vendor/opam/uring/vendor/liburing/src/liburing.map
··· 67 67 io_uring_get_events; 68 68 io_uring_submit_and_get_events; 69 69 } LIBURING_2.2; 70 + 71 + LIBURING_2.4 { 72 + global: 73 + io_uring_major_version; 74 + io_uring_minor_version; 75 + io_uring_check_version; 76 + 77 + io_uring_close_ring_fd; 78 + io_uring_enable_rings; 79 + io_uring_register_restrictions; 80 + io_uring_setup_buf_ring; 81 + io_uring_free_buf_ring; 82 + } LIBURING_2.3;
+9 -2
vendor/opam/uring/vendor/liburing/src/nolibc.c
··· 7 7 #include "lib.h" 8 8 #include "syscall.h" 9 9 10 - void *memset(void *s, int c, size_t n) 10 + void *__uring_memset(void *s, int c, size_t n) 11 11 { 12 12 size_t i; 13 13 unsigned char *p = s; 14 14 15 - for (i = 0; i < n; i++) 15 + for (i = 0; i < n; i++) { 16 16 p[i] = (unsigned char) c; 17 + 18 + /* 19 + * An empty inline ASM to avoid auto-vectorization 20 + * because it's too bloated for liburing. 21 + */ 22 + __asm__ volatile (""); 23 + } 17 24 18 25 return s; 19 26 }
+2 -2
vendor/opam/uring/vendor/liburing/src/queue.c
··· 81 81 } 82 82 if (!cqe && !data->wait_nr && !data->submit) { 83 83 /* 84 - * If we already looped once, we already entererd 84 + * If we already looped once, we already entered 85 85 * the kernel. Since there's nothing to submit or 86 86 * wait for, don't keep retrying. 87 87 */ ··· 201 201 * Sync internal state with kernel ring state on the SQ side. Returns the 202 202 * number of pending items in the SQ ring, for the shared ring. 203 203 */ 204 - unsigned __io_uring_flush_sq(struct io_uring *ring) 204 + static unsigned __io_uring_flush_sq(struct io_uring *ring) 205 205 { 206 206 struct io_uring_sq *sq = &ring->sq; 207 207 unsigned tail = sq->sqe_tail;
+65 -96
vendor/opam/uring/vendor/liburing/src/register.c
··· 8 8 #include "liburing/compat.h" 9 9 #include "liburing/io_uring.h" 10 10 11 + static inline int do_register(struct io_uring *ring, unsigned int opcode, 12 + const void *arg, unsigned int nr_args) 13 + { 14 + if (ring->int_flags & INT_FLAG_REG_REG_RING) 15 + opcode |= IORING_REGISTER_USE_REGISTERED_RING; 16 + 17 + return __sys_io_uring_register(ring->enter_ring_fd, opcode, arg, nr_args); 18 + } 19 + 11 20 int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off, 12 21 const struct iovec *iovecs, 13 22 const __u64 *tags, ··· 20 29 .nr = nr, 21 30 }; 22 31 23 - return __sys_io_uring_register(ring->ring_fd,IORING_REGISTER_BUFFERS_UPDATE, &up, 24 - sizeof(up)); 32 + return do_register(ring, IORING_REGISTER_BUFFERS_UPDATE, &up, sizeof(up)); 25 33 } 26 34 27 35 int io_uring_register_buffers_tags(struct io_uring *ring, ··· 35 43 .tags = (unsigned long)tags, 36 44 }; 37 45 38 - return __sys_io_uring_register(ring->ring_fd, 39 - IORING_REGISTER_BUFFERS2, &reg, 40 - sizeof(reg)); 46 + return do_register(ring, IORING_REGISTER_BUFFERS2, &reg, sizeof(reg)); 41 47 } 42 48 43 49 int io_uring_register_buffers_sparse(struct io_uring *ring, unsigned nr) ··· 47 53 .nr = nr, 48 54 }; 49 55 50 - return __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_BUFFERS2, 51 - &reg, sizeof(reg)); 56 + return do_register(ring, IORING_REGISTER_BUFFERS2, &reg, sizeof(reg)); 52 57 } 53 58 54 59 int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs, 55 60 unsigned nr_iovecs) 56 61 { 57 - int ret; 58 - 59 - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_BUFFERS, 60 - iovecs, nr_iovecs); 61 - return (ret < 0) ? ret : 0; 62 + return do_register(ring, IORING_REGISTER_BUFFERS, iovecs, nr_iovecs); 62 63 } 63 64 64 65 int io_uring_unregister_buffers(struct io_uring *ring) 65 66 { 66 - int ret; 67 - 68 - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_BUFFERS, 69 - NULL, 0); 70 - return (ret < 0) ? ret : 0; 67 + return do_register(ring, IORING_UNREGISTER_BUFFERS, NULL, 0); 71 68 } 72 69 73 70 int io_uring_register_files_update_tag(struct io_uring *ring, unsigned off, ··· 81 78 .nr = nr_files, 82 79 }; 83 80 84 - return __sys_io_uring_register(ring->ring_fd, 85 - IORING_REGISTER_FILES_UPDATE2, &up, 86 - sizeof(up)); 81 + return do_register(ring, IORING_REGISTER_FILES_UPDATE2, &up, sizeof(up)); 87 82 } 88 83 89 84 /* ··· 101 96 .fds = (unsigned long) files, 102 97 }; 103 98 104 - return __sys_io_uring_register(ring->ring_fd, 105 - IORING_REGISTER_FILES_UPDATE, &up, 106 - nr_files); 99 + return do_register(ring, IORING_REGISTER_FILES_UPDATE, &up, nr_files); 107 100 } 108 101 109 102 static int increase_rlimit_nofile(unsigned nr) ··· 132 125 int ret, did_increase = 0; 133 126 134 127 do { 135 - ret = __sys_io_uring_register(ring->ring_fd, 136 - IORING_REGISTER_FILES2, &reg, 137 - sizeof(reg)); 128 + ret = do_register(ring, IORING_REGISTER_FILES2, &reg, sizeof(reg)); 138 129 if (ret >= 0) 139 130 break; 140 131 if (ret == -EMFILE && !did_increase) { ··· 159 150 int ret, did_increase = 0; 160 151 161 152 do { 162 - ret = __sys_io_uring_register(ring->ring_fd, 163 - IORING_REGISTER_FILES2, &reg, 164 - sizeof(reg)); 153 + ret = do_register(ring, IORING_REGISTER_FILES2, &reg, sizeof(reg)); 165 154 if (ret >= 0) 166 155 break; 167 156 if (ret == -EMFILE && !did_increase) { ··· 181 170 int ret, did_increase = 0; 182 171 183 172 do { 184 - ret = __sys_io_uring_register(ring->ring_fd, 185 - IORING_REGISTER_FILES, files, 186 - nr_files); 173 + ret = do_register(ring, IORING_REGISTER_FILES, files, nr_files); 187 174 if (ret >= 0) 188 175 break; 189 176 if (ret == -EMFILE && !did_increase) { ··· 199 186 200 187 int io_uring_unregister_files(struct io_uring *ring) 201 188 { 202 - int ret; 203 - 204 - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_FILES, 205 - NULL, 0); 206 - return (ret < 0) ? ret : 0; 189 + return do_register(ring, IORING_UNREGISTER_FILES, NULL, 0); 207 190 } 208 191 209 192 int io_uring_register_eventfd(struct io_uring *ring, int event_fd) 210 193 { 211 - int ret; 212 - 213 - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD, 214 - &event_fd, 1); 215 - return (ret < 0) ? ret : 0; 194 + return do_register(ring, IORING_REGISTER_EVENTFD, &event_fd, 1); 216 195 } 217 196 218 197 int io_uring_unregister_eventfd(struct io_uring *ring) 219 198 { 220 - int ret; 221 - 222 - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_EVENTFD, 223 - NULL, 0); 224 - return (ret < 0) ? ret : 0; 199 + return do_register(ring, IORING_UNREGISTER_EVENTFD, NULL, 0); 225 200 } 226 201 227 202 int io_uring_register_eventfd_async(struct io_uring *ring, int event_fd) 228 203 { 229 - int ret; 230 - 231 - ret = __sys_io_uring_register(ring->ring_fd, 232 - IORING_REGISTER_EVENTFD_ASYNC, &event_fd, 233 - 1); 234 - return (ret < 0) ? ret : 0; 204 + return do_register(ring, IORING_REGISTER_EVENTFD_ASYNC, &event_fd, 1); 235 205 } 236 206 237 207 int io_uring_register_probe(struct io_uring *ring, struct io_uring_probe *p, 238 208 unsigned int nr_ops) 239 209 { 240 - int ret; 241 - 242 - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PROBE, p, 243 - nr_ops); 244 - return (ret < 0) ? ret : 0; 210 + return do_register(ring, IORING_REGISTER_PROBE, p, nr_ops); 245 211 } 246 212 247 213 int io_uring_register_personality(struct io_uring *ring) 248 214 { 249 - return __sys_io_uring_register(ring->ring_fd, 250 - IORING_REGISTER_PERSONALITY, NULL, 0); 215 + return do_register(ring, IORING_REGISTER_PERSONALITY, NULL, 0); 251 216 } 252 217 253 218 int io_uring_unregister_personality(struct io_uring *ring, int id) 254 219 { 255 - return __sys_io_uring_register(ring->ring_fd, 256 - IORING_UNREGISTER_PERSONALITY, NULL, id); 220 + return do_register(ring, IORING_UNREGISTER_PERSONALITY, NULL, id); 257 221 } 258 222 259 223 int io_uring_register_restrictions(struct io_uring *ring, 260 224 struct io_uring_restriction *res, 261 225 unsigned int nr_res) 262 226 { 263 - int ret; 264 - 265 - ret = __sys_io_uring_register(ring->ring_fd, 266 - IORING_REGISTER_RESTRICTIONS, res, 267 - nr_res); 268 - return (ret < 0) ? ret : 0; 227 + return do_register(ring, IORING_REGISTER_RESTRICTIONS, res, nr_res); 269 228 } 270 229 271 230 int io_uring_enable_rings(struct io_uring *ring) 272 231 { 273 - return __sys_io_uring_register(ring->ring_fd, 274 - IORING_REGISTER_ENABLE_RINGS, NULL, 0); 232 + return do_register(ring, IORING_REGISTER_ENABLE_RINGS, NULL, 0); 275 233 } 276 234 277 235 int io_uring_register_iowq_aff(struct io_uring *ring, size_t cpusz, ··· 280 238 if (cpusz >= (1U << 31)) 281 239 return -EINVAL; 282 240 283 - return __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_IOWQ_AFF, 284 - mask, (int) cpusz); 241 + return do_register(ring, IORING_REGISTER_IOWQ_AFF, mask, (int) cpusz); 285 242 } 286 243 287 244 int io_uring_unregister_iowq_aff(struct io_uring *ring) 288 245 { 289 - return __sys_io_uring_register(ring->ring_fd, 290 - IORING_UNREGISTER_IOWQ_AFF, NULL, 0); 246 + return do_register(ring, IORING_UNREGISTER_IOWQ_AFF, NULL, 0); 291 247 } 292 248 293 249 int io_uring_register_iowq_max_workers(struct io_uring *ring, unsigned int *val) 294 250 { 295 - return __sys_io_uring_register(ring->ring_fd, 296 - IORING_REGISTER_IOWQ_MAX_WORKERS, val, 297 - 2); 251 + return do_register(ring, IORING_REGISTER_IOWQ_MAX_WORKERS, val, 2); 298 252 } 299 253 300 254 int io_uring_register_ring_fd(struct io_uring *ring) ··· 305 259 }; 306 260 int ret; 307 261 308 - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_RING_FDS, 309 - &up, 1); 262 + if (ring->int_flags & INT_FLAG_REG_RING) 263 + return -EEXIST; 264 + 265 + ret = do_register(ring, IORING_REGISTER_RING_FDS, &up, 1); 310 266 if (ret == 1) { 311 267 ring->enter_ring_fd = up.offset; 312 268 ring->int_flags |= INT_FLAG_REG_RING; 269 + if (ring->features & IORING_FEAT_REG_REG_RING) { 270 + ring->int_flags |= INT_FLAG_REG_REG_RING; 271 + } 313 272 } 314 273 return ret; 315 274 } ··· 322 281 }; 323 282 int ret; 324 283 325 - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_RING_FDS, 326 - &up, 1); 284 + if (!(ring->int_flags & INT_FLAG_REG_RING)) 285 + return -EINVAL; 286 + 287 + ret = do_register(ring, IORING_UNREGISTER_RING_FDS, &up, 1); 327 288 if (ret == 1) { 328 289 ring->enter_ring_fd = ring->ring_fd; 329 - ring->int_flags &= ~INT_FLAG_REG_RING; 290 + ring->int_flags &= ~(INT_FLAG_REG_RING | INT_FLAG_REG_REG_RING); 330 291 } 331 292 return ret; 332 293 } 333 294 295 + int io_uring_close_ring_fd(struct io_uring *ring) 296 + { 297 + if (!(ring->features & IORING_FEAT_REG_REG_RING)) 298 + return -EOPNOTSUPP; 299 + if (!(ring->int_flags & INT_FLAG_REG_RING)) 300 + return -EINVAL; 301 + if (ring->ring_fd == -1) 302 + return -EBADF; 303 + 304 + __sys_close(ring->ring_fd); 305 + ring->ring_fd = -1; 306 + return 1; 307 + } 308 + 334 309 int io_uring_register_buf_ring(struct io_uring *ring, 335 310 struct io_uring_buf_reg *reg, 336 311 unsigned int __maybe_unused flags) 337 312 { 338 - return __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PBUF_RING, 339 - reg, 1); 313 + return do_register(ring, IORING_REGISTER_PBUF_RING, reg, 1); 340 314 } 341 315 342 316 int io_uring_unregister_buf_ring(struct io_uring *ring, int bgid) 343 317 { 344 318 struct io_uring_buf_reg reg = { .bgid = bgid }; 345 319 346 - return __sys_io_uring_register(ring->ring_fd, 347 - IORING_UNREGISTER_PBUF_RING, &reg, 1); 320 + return do_register(ring, IORING_UNREGISTER_PBUF_RING, &reg, 1); 348 321 } 349 322 350 323 int io_uring_register_sync_cancel(struct io_uring *ring, 351 324 struct io_uring_sync_cancel_reg *reg) 352 325 { 353 - return __sys_io_uring_register(ring->ring_fd, 354 - IORING_REGISTER_SYNC_CANCEL, reg, 1); 326 + return do_register(ring, IORING_REGISTER_SYNC_CANCEL, reg, 1); 355 327 } 356 328 357 329 int io_uring_register_file_alloc_range(struct io_uring *ring, 358 330 unsigned off, unsigned len) 359 331 { 360 - struct io_uring_file_index_range range; 361 - 362 - memset(&range, 0, sizeof(range)); 363 - range.off = off; 364 - range.len = len; 332 + struct io_uring_file_index_range range = { 333 + .off = off, 334 + .len = len 335 + }; 365 336 366 - return __sys_io_uring_register(ring->ring_fd, 367 - IORING_REGISTER_FILE_ALLOC_RANGE, &range, 368 - 0); 337 + return do_register(ring, IORING_REGISTER_FILE_ALLOC_RANGE, &range, 0); 369 338 }
+108 -6
vendor/opam/uring/vendor/liburing/src/setup.c
··· 105 105 ring->flags = p->flags; 106 106 ring->ring_fd = ring->enter_ring_fd = fd; 107 107 ring->int_flags = 0; 108 + return 0; 108 109 } 109 110 return ret; 110 111 } ··· 205 206 */ 206 207 if (ring->int_flags & INT_FLAG_REG_RING) 207 208 io_uring_unregister_ring_fd(ring); 208 - __sys_close(ring->ring_fd); 209 + if (ring->ring_fd != -1) 210 + __sys_close(ring->ring_fd); 209 211 } 210 212 211 213 __cold struct io_uring_probe *io_uring_get_probe_ring(struct io_uring *ring) ··· 215 217 int r; 216 218 217 219 len = sizeof(*probe) + 256 * sizeof(struct io_uring_probe_op); 218 - probe = uring_malloc(len); 220 + probe = malloc(len); 219 221 if (!probe) 220 222 return NULL; 221 223 memset(probe, 0, len); ··· 224 226 if (r >= 0) 225 227 return probe; 226 228 227 - uring_free(probe); 229 + free(probe); 228 230 return NULL; 229 231 } 230 232 ··· 245 247 246 248 __cold void io_uring_free_probe(struct io_uring_probe *probe) 247 249 { 248 - uring_free(probe); 250 + free(probe); 249 251 } 250 252 251 253 static inline int __fls(unsigned long x) ··· 304 306 __cold ssize_t io_uring_mlock_size_params(unsigned entries, 305 307 struct io_uring_params *p) 306 308 { 307 - struct io_uring_params lp = { }; 309 + struct io_uring_params lp; 308 310 struct io_uring ring; 309 311 unsigned cq_entries; 310 312 long page_size; 311 313 ssize_t ret; 312 314 315 + memset(&lp, 0, sizeof(lp)); 316 + 313 317 /* 314 318 * We only really use this inited ring to see if the kernel is newer 315 319 * or not. Newer kernels don't require memlocked memory. If we fail, ··· 363 367 */ 364 368 __cold ssize_t io_uring_mlock_size(unsigned entries, unsigned flags) 365 369 { 366 - struct io_uring_params p = { .flags = flags, }; 370 + struct io_uring_params p; 367 371 372 + memset(&p, 0, sizeof(p)); 373 + p.flags = flags; 368 374 return io_uring_mlock_size_params(entries, &p); 369 375 } 376 + 377 + #if defined(__hppa__) 378 + static struct io_uring_buf_ring *br_setup(struct io_uring *ring, 379 + unsigned int nentries, int bgid, 380 + unsigned int flags, int *ret) 381 + { 382 + struct io_uring_buf_ring *br; 383 + struct io_uring_buf_reg reg; 384 + size_t ring_size; 385 + off_t off; 386 + int lret; 387 + 388 + memset(&reg, 0, sizeof(reg)); 389 + reg.ring_entries = nentries; 390 + reg.bgid = bgid; 391 + reg.flags = IOU_PBUF_RING_MMAP; 392 + 393 + *ret = 0; 394 + lret = io_uring_register_buf_ring(ring, &reg, flags); 395 + if (lret) { 396 + *ret = lret; 397 + return NULL; 398 + } 399 + 400 + off = IORING_OFF_PBUF_RING | (unsigned long long) bgid << IORING_OFF_PBUF_SHIFT; 401 + ring_size = nentries * sizeof(struct io_uring_buf); 402 + br = __sys_mmap(NULL, ring_size, PROT_READ | PROT_WRITE, 403 + MAP_SHARED | MAP_POPULATE, ring->ring_fd, off); 404 + if (IS_ERR(br)) { 405 + *ret = PTR_ERR(br); 406 + return NULL; 407 + } 408 + 409 + return br; 410 + } 411 + #else 412 + static struct io_uring_buf_ring *br_setup(struct io_uring *ring, 413 + unsigned int nentries, int bgid, 414 + unsigned int flags, int *ret) 415 + { 416 + struct io_uring_buf_ring *br; 417 + struct io_uring_buf_reg reg; 418 + size_t ring_size; 419 + int lret; 420 + 421 + memset(&reg, 0, sizeof(reg)); 422 + ring_size = nentries * sizeof(struct io_uring_buf); 423 + br = __sys_mmap(NULL, ring_size, PROT_READ | PROT_WRITE, 424 + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 425 + if (IS_ERR(br)) { 426 + *ret = PTR_ERR(br); 427 + return NULL; 428 + } 429 + 430 + reg.ring_addr = (unsigned long) (uintptr_t) br; 431 + reg.ring_entries = nentries; 432 + reg.bgid = bgid; 433 + 434 + *ret = 0; 435 + lret = io_uring_register_buf_ring(ring, &reg, flags); 436 + if (lret) { 437 + __sys_munmap(br, ring_size); 438 + *ret = lret; 439 + br = NULL; 440 + } 441 + 442 + return br; 443 + } 444 + #endif 445 + 446 + struct io_uring_buf_ring *io_uring_setup_buf_ring(struct io_uring *ring, 447 + unsigned int nentries, 448 + int bgid, unsigned int flags, 449 + int *ret) 450 + { 451 + struct io_uring_buf_ring *br; 452 + 453 + br = br_setup(ring, nentries, bgid, flags, ret); 454 + if (br) 455 + io_uring_buf_ring_init(br); 456 + 457 + return br; 458 + } 459 + 460 + int io_uring_free_buf_ring(struct io_uring *ring, struct io_uring_buf_ring *br, 461 + unsigned int nentries, int bgid) 462 + { 463 + int ret; 464 + 465 + ret = io_uring_unregister_buf_ring(ring, bgid); 466 + if (ret) 467 + return ret; 468 + 469 + __sys_munmap(br, nentries * sizeof(struct io_uring_buf)); 470 + return 0; 471 + }
+21
vendor/opam/uring/vendor/liburing/src/version.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + 3 + #include "liburing.h" 4 + #include "liburing/io_uring_version.h" 5 + 6 + int io_uring_major_version(void) 7 + { 8 + return IO_URING_VERSION_MAJOR; 9 + } 10 + 11 + int io_uring_minor_version(void) 12 + { 13 + return IO_URING_VERSION_MINOR; 14 + } 15 + 16 + bool io_uring_check_version(int major, int minor) 17 + { 18 + return major > io_uring_major_version() || 19 + (major == io_uring_major_version() && 20 + minor >= io_uring_minor_version()); 21 + }
+3 -3
vendor/opam/uring/vendor/liburing/test/232c93d07b74.c
··· 33 33 __be16 bind_port; 34 34 }; 35 35 36 - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 37 - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 38 - int rcv_ready = 0; 36 + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 37 + static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 38 + static int rcv_ready = 0; 39 39 40 40 static void set_rcv_ready(void) 41 41 {
+3 -3
vendor/opam/uring/vendor/liburing/test/35fa71a030ca.c
··· 176 176 } 177 177 178 178 #define SYZ_HAVE_SETUP_TEST 1 179 - static void setup_test() 179 + static void setup_test(void) 180 180 { 181 181 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 182 182 setpgrp(); ··· 262 262 } 263 263 } 264 264 265 - uint64_t r[1] = {0xffffffffffffffff}; 265 + static uint64_t r[1] = {0xffffffffffffffff}; 266 266 267 267 void execute_call(int call) 268 268 { ··· 320 320 if (argc > 1) 321 321 return T_EXIT_SKIP; 322 322 signal(SIGINT, sig_int); 323 - mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0); 323 + mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0); 324 324 signal(SIGALRM, sig_int); 325 325 alarm(5); 326 326
+2
vendor/opam/uring/vendor/liburing/test/500f9fbadef8.c
··· 42 42 sprintf(buf, "./XXXXXX"); 43 43 fd = mkostemp(buf, O_WRONLY | O_DIRECT | O_CREAT); 44 44 if (fd < 0) { 45 + if (errno == EINVAL) 46 + return T_EXIT_SKIP; 45 47 perror("mkostemp"); 46 48 return T_EXIT_FAIL; 47 49 }
+1 -1
vendor/opam/uring/vendor/liburing/test/917257daa0fe.c
··· 19 19 if (argc > 1) 20 20 return T_EXIT_SKIP; 21 21 22 - mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0); 22 + mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0); 23 23 24 24 *(uint32_t*)0x20000000 = 0; 25 25 *(uint32_t*)0x20000004 = 0;
+30 -8
vendor/opam/uring/vendor/liburing/test/Makefile
··· 13 13 -D_GNU_SOURCE \ 14 14 -D__SANE_USERSPACE_TYPES__ \ 15 15 -I../src/include/ \ 16 - -include ../config-host.h 16 + -include ../config-host.h \ 17 + -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 17 18 18 19 CFLAGS ?= -g -O3 -Wall -Wextra 19 20 XCFLAGS = -Wno-unused-parameter -Wno-sign-compare ··· 54 55 ce593a6c480a.c \ 55 56 close-opath.c \ 56 57 connect.c \ 58 + connect-rep.c \ 57 59 cq-full.c \ 58 60 cq-overflow.c \ 59 61 cq-peek-batch.c \ ··· 67 69 drop-submit.c \ 68 70 eeed8b54e0df.c \ 69 71 empty-eownerdead.c \ 72 + eploop.c \ 70 73 eventfd.c \ 71 74 eventfd-disable.c \ 72 75 eventfd-reg.c \ 73 76 eventfd-ring.c \ 77 + evloop.c \ 74 78 exec-target.c \ 75 79 exit-no-cleanup.c \ 76 80 fadvise.c \ ··· 86 90 fixed-link.c \ 87 91 fixed-reuse.c \ 88 92 fpos.c \ 93 + fsnotify.c \ 89 94 fsync.c \ 90 95 hardlink.c \ 91 96 io-cancel.c \ 92 97 iopoll.c \ 93 98 iopoll-leak.c \ 99 + iopoll-overflow.c \ 94 100 io_uring_enter.c \ 95 101 io_uring_passthrough.c \ 96 102 io_uring_register.c \ ··· 103 109 madvise.c \ 104 110 mkdir.c \ 105 111 msg-ring.c \ 112 + msg-ring-flags.c \ 113 + msg-ring-overflow.c \ 106 114 multicqes_drain.c \ 107 115 nolibc.c \ 108 116 nop-all-sizes.c \ ··· 112 120 open-direct-link.c \ 113 121 open-direct-pick.c \ 114 122 personality.c \ 123 + pipe-bug.c \ 115 124 pipe-eof.c \ 116 125 pipe-reuse.c \ 117 126 poll.c \ ··· 120 129 poll-cancel-ton.c \ 121 130 poll-link.c \ 122 131 poll-many.c \ 123 - poll-mshot-update.c \ 124 132 poll-mshot-overflow.c \ 133 + poll-mshot-update.c \ 134 + poll-race.c \ 135 + poll-race-mshot.c \ 125 136 poll-ring.c \ 126 137 poll-v-poll.c \ 127 138 pollfree.c \ ··· 131 142 recv-msgall.c \ 132 143 recv-msgall-stream.c \ 133 144 recv-multishot.c \ 145 + reg-hint.c \ 146 + reg-reg-ring.c \ 147 + regbuf-merge.c \ 134 148 register-restrictions.c \ 135 149 rename.c \ 136 150 ringbuf-read.c \ ··· 142 156 sendmsg_fs_cve.c \ 143 157 send_recv.c \ 144 158 send_recvmsg.c \ 159 + send-zerocopy.c \ 145 160 shared-wq.c \ 146 161 short-read.c \ 147 162 shutdown.c \ 148 163 sigfd-deadlock.c \ 164 + single-issuer.c \ 149 165 skip-cqe.c \ 150 166 socket.c \ 151 167 socket-rw.c \ ··· 166 182 submit-and-wait.c \ 167 183 submit-link-fail.c \ 168 184 submit-reuse.c \ 169 - sync-cancel.c \ 170 185 symlink.c \ 186 + sync-cancel.c \ 171 187 teardowns.c \ 172 188 thread-exit.c \ 173 189 timeout.c \ 174 190 timeout-new.c \ 175 - timeout-overflow.c \ 176 191 tty-write-dpoll.c \ 177 192 unlink.c \ 193 + version.c \ 178 194 wakeup-hang.c \ 179 195 xattr.c \ 180 - skip-cqe.c \ 181 - single-issuer.c \ 182 - send-zerocopy.c \ 183 196 # EOL 184 197 185 198 all_targets := ··· 213 226 %.t: %.c $(helpers) helpers.h ../src/liburing.a 214 227 $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(helpers) $(LDFLAGS) 215 228 229 + # 230 + # Clang++ is not happy with -Wmissing-prototypes: 231 + # 232 + # cc1plus: warning: command-line option '-Wmissing-prototypes' \ 233 + # is valid for C/ObjC but not for C++ 234 + # 216 235 %.t: %.cc $(helpers) helpers.h ../src/liburing.a 217 - $(QUIET_CXX)$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< $(helpers) $(LDFLAGS) 236 + $(QUIET_CXX)$(CXX) \ 237 + $(patsubst -Wmissing-prototypes,,$(CPPFLAGS)) \ 238 + $(patsubst -Wmissing-prototypes,,$(CXXFLAGS)) \ 239 + -o $@ $< $(helpers) $(LDFLAGS) 218 240 219 241 220 242 install: $(test_targets) runtests.sh runtests-loop.sh
+2 -2
vendor/opam/uring/vendor/liburing/test/a0908ae19763.c
··· 14 14 #include "helpers.h" 15 15 #include "../src/syscall.h" 16 16 17 - uint64_t r[1] = {0xffffffffffffffff}; 17 + static uint64_t r[1] = {0xffffffffffffffff}; 18 18 19 19 int main(int argc, char *argv[]) 20 20 { 21 21 if (argc > 1) 22 22 return T_EXIT_SKIP; 23 - mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0); 23 + mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0); 24 24 intptr_t res = 0; 25 25 *(uint32_t*)0x20000080 = 0; 26 26 *(uint32_t*)0x20000084 = 0;
+2 -2
vendor/opam/uring/vendor/liburing/test/a4c0b3decb33.c
··· 95 95 } 96 96 } 97 97 98 - static void setup_test() 98 + static void setup_test(void) 99 99 { 100 100 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 101 101 setpgrp(); ··· 175 175 if (argc > 1) 176 176 return T_EXIT_SKIP; 177 177 signal(SIGINT, sig_int); 178 - mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0); 178 + mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0); 179 179 loop(); 180 180 return T_EXIT_PASS; 181 181 }
+4 -4
vendor/opam/uring/vendor/liburing/test/accept-link.c
··· 16 16 #include "liburing.h" 17 17 #include "helpers.h" 18 18 19 - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 20 - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 19 + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 20 + static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 21 21 22 22 static int recv_thread_ready = 0; 23 23 static int recv_thread_done = 0; ··· 77 77 return NULL; 78 78 } 79 79 80 - void *recv_thread(void *arg) 80 + static void *recv_thread(void *arg) 81 81 { 82 82 struct data *data = arg; 83 83 struct io_uring ring; ··· 195 195 if (ret) { 196 196 fprintf(stderr, "queue_init: %d\n", ret); 197 197 return 1; 198 - }; 198 + } 199 199 200 200 fast_poll = (p.features & IORING_FEAT_FAST_POLL) != 0; 201 201 io_uring_queue_exit(&ring);
+5 -7
vendor/opam/uring/vendor/liburing/test/accept-reuse.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 - #include <liburing.h> 3 2 #include <netdb.h> 4 3 #include <string.h> 5 4 #include <sys/socket.h> ··· 11 10 #include "helpers.h" 12 11 #include "../src/syscall.h" 13 12 14 - struct io_uring io_uring; 13 + static struct io_uring io_uring; 15 14 16 - int sys_io_uring_enter(const int fd, 17 - const unsigned to_submit, 18 - const unsigned min_complete, 19 - const unsigned flags, sigset_t * const sig) 15 + static int sys_io_uring_enter(const int fd, const unsigned to_submit, 16 + const unsigned min_complete, 17 + const unsigned flags, sigset_t * const sig) 20 18 { 21 19 return __sys_io_uring_enter(fd, to_submit, min_complete, flags, sig); 22 20 } 23 21 24 - int submit_sqe(void) 22 + static int submit_sqe(void) 25 23 { 26 24 struct io_uring_sq *sq = &io_uring.sq; 27 25 const unsigned tail = *sq->ktail;
+34 -31
vendor/opam/uring/vendor/liburing/test/accept.c
··· 272 272 uint32_t multishot_mask = 0; 273 273 int nr_fds = multishot ? MAX_FDS : 1; 274 274 int multishot_idx = multishot ? INITIAL_USER_DATA : 0; 275 + int err_ret = T_EXIT_FAIL; 275 276 276 277 if (args.overflow) 277 278 cause_overflow(ring); ··· 298 299 no_accept_multi = 1; 299 300 else 300 301 no_accept = 1; 302 + ret = T_EXIT_SKIP; 301 303 goto out; 302 304 } else if (s_fd[i] < 0) { 303 305 if (args.accept_should_error && ··· 360 362 361 363 out: 362 364 close_sock_fds(s_fd, c_fd, nr_fds, fixed); 363 - return 0; 365 + return T_EXIT_PASS; 364 366 err: 365 367 close_sock_fds(s_fd, c_fd, nr_fds, fixed); 366 - return 1; 368 + return err_ret; 367 369 } 368 370 369 371 static int test(struct io_uring *ring, struct accept_test_args args) ··· 372 374 int ret = 0; 373 375 int loop; 374 376 int32_t recv_s0 = start_accept_listen(&addr, 0, 375 - args.nonblock ? O_NONBLOCK : 0); 377 + args.nonblock ? SOCK_NONBLOCK : 0); 376 378 if (args.queue_accept_before_connect) 377 379 queue_accept_conn(ring, recv_s0, args); 378 380 for (loop = 0; loop < 1 + args.extra_loops; loop++) { ··· 458 460 459 461 for (i = 0; i < nr_socks; i++) 460 462 fds[i] = start_accept_listen(NULL, i, 461 - args.nonblock ? O_NONBLOCK : 0); 463 + args.nonblock ? SOCK_NONBLOCK : 0); 462 464 463 465 for (i = 0; i < nr; i++) { 464 466 int sock_idx = args.single_sock ? 0 : i; ··· 611 613 return ret; 612 614 } 613 615 614 - static int test_accept_multishot_wrong_arg() 616 + static int test_accept_multishot_wrong_arg(void) 615 617 { 616 618 struct io_uring m_io_uring; 617 619 struct io_uring_cqe *cqe; ··· 733 735 734 736 if (argc > 1) 735 737 return T_EXIT_SKIP; 738 + 736 739 ret = test_accept(1, false); 737 - if (ret) { 740 + if (ret == T_EXIT_FAIL) { 738 741 fprintf(stderr, "test_accept failed\n"); 739 742 return ret; 740 743 } ··· 742 745 return T_EXIT_SKIP; 743 746 744 747 ret = test_accept(2, false); 745 - if (ret) { 748 + if (ret == T_EXIT_FAIL) { 746 749 fprintf(stderr, "test_accept(2) failed\n"); 747 750 return ret; 748 751 } 749 752 750 753 ret = test_accept(2, true); 751 - if (ret) { 754 + if (ret == T_EXIT_FAIL) { 752 755 fprintf(stderr, "test_accept(2, true) failed\n"); 753 756 return ret; 754 757 } 755 758 756 759 ret = test_accept_nonblock(false, 1); 757 - if (ret) { 760 + if (ret == T_EXIT_FAIL) { 758 761 fprintf(stderr, "test_accept_nonblock failed\n"); 759 762 return ret; 760 763 } 761 764 762 765 ret = test_accept_nonblock(true, 1); 763 - if (ret) { 766 + if (ret == T_EXIT_FAIL) { 764 767 fprintf(stderr, "test_accept_nonblock(before, 1) failed\n"); 765 768 return ret; 766 769 } 767 770 768 771 ret = test_accept_nonblock(true, 3); 769 - if (ret) { 772 + if (ret == T_EXIT_FAIL) { 770 773 fprintf(stderr, "test_accept_nonblock(before,3) failed\n"); 771 774 return ret; 772 775 } 773 776 774 777 ret = test_accept_fixed(); 775 - if (ret) { 778 + if (ret == T_EXIT_FAIL) { 776 779 fprintf(stderr, "test_accept_fixed failed\n"); 777 780 return ret; 778 781 } 779 782 780 783 ret = test_multishot_fixed_accept(); 781 - if (ret) { 784 + if (ret == T_EXIT_FAIL) { 782 785 fprintf(stderr, "test_multishot_fixed_accept failed\n"); 783 786 return ret; 784 787 } 785 788 786 789 ret = test_accept_multishot_wrong_arg(); 787 - if (ret) { 790 + if (ret == T_EXIT_FAIL) { 788 791 fprintf(stderr, "test_accept_multishot_wrong_arg failed\n"); 789 792 return ret; 790 793 } 791 794 792 795 ret = test_accept_sqpoll(); 793 - if (ret) { 796 + if (ret == T_EXIT_FAIL) { 794 797 fprintf(stderr, "test_accept_sqpoll failed\n"); 795 798 return ret; 796 799 } 797 800 798 801 ret = test_accept_cancel(0, 1, false); 799 - if (ret) { 802 + if (ret == T_EXIT_FAIL) { 800 803 fprintf(stderr, "test_accept_cancel nodelay failed\n"); 801 804 return ret; 802 805 } 803 806 804 807 ret = test_accept_cancel(10000, 1, false); 805 - if (ret) { 808 + if (ret == T_EXIT_FAIL) { 806 809 fprintf(stderr, "test_accept_cancel delay failed\n"); 807 810 return ret; 808 811 } 809 812 810 813 ret = test_accept_cancel(0, 4, false); 811 - if (ret) { 814 + if (ret == T_EXIT_FAIL) { 812 815 fprintf(stderr, "test_accept_cancel nodelay failed\n"); 813 816 return ret; 814 817 } 815 818 816 819 ret = test_accept_cancel(10000, 4, false); 817 - if (ret) { 820 + if (ret == T_EXIT_FAIL) { 818 821 fprintf(stderr, "test_accept_cancel delay failed\n"); 819 822 return ret; 820 823 } 821 824 822 825 ret = test_accept_cancel(0, 1, true); 823 - if (ret) { 826 + if (ret == T_EXIT_FAIL) { 824 827 fprintf(stderr, "test_accept_cancel multishot nodelay failed\n"); 825 828 return ret; 826 829 } 827 830 828 831 ret = test_accept_cancel(10000, 1, true); 829 - if (ret) { 832 + if (ret == T_EXIT_FAIL) { 830 833 fprintf(stderr, "test_accept_cancel multishot delay failed\n"); 831 834 return ret; 832 835 } 833 836 834 837 ret = test_accept_cancel(0, 4, true); 835 - if (ret) { 838 + if (ret == T_EXIT_FAIL) { 836 839 fprintf(stderr, "test_accept_cancel multishot nodelay failed\n"); 837 840 return ret; 838 841 } 839 842 840 843 ret = test_accept_cancel(10000, 4, true); 841 - if (ret) { 844 + if (ret == T_EXIT_FAIL) { 842 845 fprintf(stderr, "test_accept_cancel multishot delay failed\n"); 843 846 return ret; 844 847 } 845 848 846 849 ret = test_multishot_accept(1, true, true); 847 - if (ret) { 850 + if (ret == T_EXIT_FAIL) { 848 851 fprintf(stderr, "test_multishot_accept(1, false, true) failed\n"); 849 852 return ret; 850 853 } 851 854 852 855 ret = test_multishot_accept(1, false, false); 853 - if (ret) { 856 + if (ret == T_EXIT_FAIL) { 854 857 fprintf(stderr, "test_multishot_accept(1, false, false) failed\n"); 855 858 return ret; 856 859 } 857 860 858 861 ret = test_multishot_accept(1, true, false); 859 - if (ret) { 862 + if (ret == T_EXIT_FAIL) { 860 863 fprintf(stderr, "test_multishot_accept(1, true, false) failed\n"); 861 864 return ret; 862 865 } 863 866 864 867 ret = test_accept_many((struct test_accept_many_args) {}); 865 - if (ret) { 868 + if (ret == T_EXIT_FAIL) { 866 869 fprintf(stderr, "test_accept_many failed\n"); 867 870 return ret; 868 871 } 869 872 870 873 ret = test_accept_many((struct test_accept_many_args) { 871 874 .usecs = 100000 }); 872 - if (ret) { 875 + if (ret == T_EXIT_FAIL) { 873 876 fprintf(stderr, "test_accept_many(sleep) failed\n"); 874 877 return ret; 875 878 } 876 879 877 880 ret = test_accept_many((struct test_accept_many_args) { 878 881 .nonblock = true }); 879 - if (ret) { 882 + if (ret == T_EXIT_FAIL) { 880 883 fprintf(stderr, "test_accept_many(nonblock) failed\n"); 881 884 return ret; 882 885 } ··· 885 888 .nonblock = true, 886 889 .single_sock = true, 887 890 .close_fds = true }); 888 - if (ret) { 891 + if (ret == T_EXIT_FAIL) { 889 892 fprintf(stderr, "test_accept_many(nonblock,close) failed\n"); 890 893 return ret; 891 894 } 892 895 893 896 ret = test_accept_pending_on_exit(); 894 - if (ret) { 897 + if (ret == T_EXIT_FAIL) { 895 898 fprintf(stderr, "test_accept_pending_on_exit failed\n"); 896 899 return ret; 897 900 }
+1 -1
vendor/opam/uring/vendor/liburing/test/b19062a56726.c
··· 19 19 if (argc > 1) 20 20 return T_EXIT_SKIP; 21 21 22 - mmap((void *) 0x20000000, 0x1000000, 3, 0x32, -1, 0); 22 + mmap((void *) 0x20000000, 0x1000000, 3, MAP_ANON|MAP_PRIVATE, -1, 0); 23 23 24 24 *(uint32_t*)0x20000200 = 0; 25 25 *(uint32_t*)0x20000204 = 0;
+86 -72
vendor/opam/uring/vendor/liburing/test/buf-ring.c
··· 9 9 #include <stdlib.h> 10 10 #include <string.h> 11 11 #include <fcntl.h> 12 + #include <sys/mman.h> 12 13 13 14 #include "liburing.h" 14 15 #include "helpers.h" 15 16 16 17 static int no_buf_ring; 18 + static int pagesize; 17 19 18 20 /* test trying to register classic group when ring group exists */ 19 21 static int test_mixed_reg2(int bgid) 20 22 { 21 - struct io_uring_buf_reg reg = { }; 23 + struct io_uring_buf_ring *br; 22 24 struct io_uring_sqe *sqe; 23 25 struct io_uring_cqe *cqe; 24 26 struct io_uring ring; 25 - void *ptr, *bufs; 27 + void *bufs; 26 28 int ret; 27 29 28 30 ret = t_create_ring(1, &ring, 0); ··· 31 33 else if (ret != T_SETUP_OK) 32 34 return 1; 33 35 34 - if (posix_memalign(&ptr, 4096, 4096)) 35 - return 1; 36 - 37 - reg.ring_addr = (unsigned long) ptr; 38 - reg.ring_entries = 32; 39 - reg.bgid = bgid; 40 - 41 - ret = io_uring_register_buf_ring(&ring, &reg, 0); 42 - if (ret) { 36 + br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret); 37 + if (!br) { 43 38 fprintf(stderr, "Buffer ring register failed %d\n", ret); 44 39 return 1; 45 40 } ··· 60 55 } 61 56 io_uring_cqe_seen(&ring, cqe); 62 57 58 + io_uring_free_buf_ring(&ring, br, 32, bgid); 63 59 io_uring_queue_exit(&ring); 64 60 return 0; 65 61 } ··· 67 63 /* test trying to register ring group when classic group exists */ 68 64 static int test_mixed_reg(int bgid) 69 65 { 70 - struct io_uring_buf_reg reg = { }; 66 + struct io_uring_buf_ring *br; 71 67 struct io_uring_sqe *sqe; 72 68 struct io_uring_cqe *cqe; 73 69 struct io_uring ring; 74 - void *ptr, *bufs; 70 + void *bufs; 75 71 int ret; 76 72 77 73 ret = t_create_ring(1, &ring, 0); ··· 96 92 } 97 93 io_uring_cqe_seen(&ring, cqe); 98 94 99 - if (posix_memalign(&ptr, 4096, 4096)) 100 - return 1; 101 - 102 - reg.ring_addr = (unsigned long) ptr; 103 - reg.ring_entries = 32; 104 - reg.bgid = bgid; 105 - 106 - ret = io_uring_register_buf_ring(&ring, &reg, 0); 107 - if (ret != -EEXIST) { 108 - fprintf(stderr, "Buffer ring register failed %d\n", ret); 95 + br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret); 96 + if (br) { 97 + fprintf(stderr, "Buffer ring setup succeeded unexpectedly %d\n", ret); 109 98 return 1; 110 99 } 111 100 ··· 116 105 static int test_double_reg_unreg(int bgid) 117 106 { 118 107 struct io_uring_buf_reg reg = { }; 108 + struct io_uring_buf_ring *br; 119 109 struct io_uring ring; 120 - void *ptr; 121 110 int ret; 122 111 123 112 ret = t_create_ring(1, &ring, 0); ··· 126 115 else if (ret != T_SETUP_OK) 127 116 return 1; 128 117 129 - if (posix_memalign(&ptr, 4096, 4096)) 130 - return 1; 131 - 132 - reg.ring_addr = (unsigned long) ptr; 133 - reg.ring_entries = 32; 134 - reg.bgid = bgid; 135 - 136 - ret = io_uring_register_buf_ring(&ring, &reg, 0); 137 - if (ret) { 118 + br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret); 119 + if (!br) { 138 120 fprintf(stderr, "Buffer ring register failed %d\n", ret); 139 121 return 1; 140 122 } 141 123 142 124 /* check that 2nd register with same bgid fails */ 143 - reg.ring_addr = (unsigned long) ptr; 125 + reg.ring_addr = (unsigned long) br; 144 126 reg.ring_entries = 32; 145 127 reg.bgid = bgid; 146 128 ··· 150 132 return 1; 151 133 } 152 134 153 - ret = io_uring_unregister_buf_ring(&ring, bgid); 135 + ret = io_uring_free_buf_ring(&ring, br, 32, bgid); 154 136 if (ret) { 155 137 fprintf(stderr, "Buffer ring register failed %d\n", ret); 156 138 return 1; ··· 168 150 169 151 static int test_reg_unreg(int bgid) 170 152 { 171 - struct io_uring_buf_reg reg = { }; 153 + struct io_uring_buf_ring *br; 172 154 struct io_uring ring; 173 - void *ptr; 174 155 int ret; 175 156 176 157 ret = t_create_ring(1, &ring, 0); ··· 179 160 else if (ret != T_SETUP_OK) 180 161 return 1; 181 162 182 - if (posix_memalign(&ptr, 4096, 4096)) 183 - return 1; 184 - 185 - reg.ring_addr = (unsigned long) ptr; 186 - reg.ring_entries = 32; 187 - reg.bgid = bgid; 188 - 189 - ret = io_uring_register_buf_ring(&ring, &reg, 0); 190 - if (ret) { 163 + br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret); 164 + if (!br) { 191 165 if (ret == -EINVAL) { 192 166 no_buf_ring = 1; 193 167 return 0; ··· 196 170 return 1; 197 171 } 198 172 199 - ret = io_uring_unregister_buf_ring(&ring, bgid); 173 + ret = io_uring_free_buf_ring(&ring, br, 32, bgid); 200 174 if (ret) { 201 - fprintf(stderr, "Buffer ring register failed %d\n", ret); 175 + fprintf(stderr, "Buffer ring unregister failed %d\n", ret); 202 176 return 1; 203 177 } 204 178 ··· 230 204 return !ret; 231 205 } 232 206 207 + static int test_full_page_reg(int bgid) 208 + { 209 + #if defined(__hppa__) 210 + return T_EXIT_SKIP; 211 + #else 212 + struct io_uring ring; 213 + int ret; 214 + void *ptr; 215 + struct io_uring_buf_reg reg = { }; 216 + int entries = pagesize / sizeof(struct io_uring_buf); 217 + 218 + ret = io_uring_queue_init(1, &ring, 0); 219 + if (ret) { 220 + fprintf(stderr, "queue init failed %d\n", ret); 221 + return T_EXIT_FAIL; 222 + } 223 + 224 + ret = posix_memalign(&ptr, pagesize, pagesize * 2); 225 + if (ret) { 226 + fprintf(stderr, "posix_memalign failed %d\n", ret); 227 + goto err; 228 + } 229 + 230 + ret = mprotect(ptr + pagesize, pagesize, PROT_NONE); 231 + if (ret) { 232 + fprintf(stderr, "mprotect failed %d\n", errno); 233 + goto err1; 234 + } 235 + 236 + reg.ring_addr = (unsigned long) ptr; 237 + reg.ring_entries = entries; 238 + reg.bgid = bgid; 239 + 240 + ret = io_uring_register_buf_ring(&ring, &reg, 0); 241 + if (ret) 242 + fprintf(stderr, "register buf ring failed %d\n", ret); 243 + 244 + if (mprotect(ptr + pagesize, pagesize, PROT_READ | PROT_WRITE)) 245 + fprintf(stderr, "reverting mprotect failed %d\n", errno); 246 + 247 + err1: 248 + free(ptr); 249 + err: 250 + io_uring_queue_exit(&ring); 251 + return ret ? T_EXIT_FAIL : T_EXIT_PASS; 252 + #endif 253 + } 254 + 233 255 static int test_one_read(int fd, int bgid, struct io_uring *ring) 234 256 { 235 257 int ret; ··· 272 294 273 295 static int test_running(int bgid, int entries, int loops) 274 296 { 275 - struct io_uring_buf_reg reg = { }; 297 + int ring_mask = io_uring_buf_ring_mask(entries); 298 + struct io_uring_buf_ring *br; 299 + int ret, loop, idx, read_fd; 276 300 struct io_uring ring; 277 - void *ptr; 278 301 char buffer[8]; 279 - int ret; 280 - int ring_size = (entries * sizeof(struct io_uring_buf) + 4095) & (~4095); 281 - int ring_mask = io_uring_buf_ring_mask(entries); 282 - 283 - int loop, idx; 284 302 bool *buffers; 285 - struct io_uring_buf_ring *br; 286 - int read_fd; 287 303 288 304 ret = t_create_ring(1, &ring, 0); 289 305 if (ret == T_SETUP_SKIP) ··· 291 307 else if (ret != T_SETUP_OK) 292 308 return 1; 293 309 294 - if (posix_memalign(&ptr, 4096, ring_size)) 310 + br = io_uring_setup_buf_ring(&ring, entries, bgid, 0, &ret); 311 + if (!br) { 312 + /* by now should have checked if this is supported or not */ 313 + fprintf(stderr, "Buffer ring register failed %d\n", ret); 295 314 return 1; 296 - 297 - br = (struct io_uring_buf_ring *)ptr; 298 - io_uring_buf_ring_init(br); 315 + } 299 316 300 317 buffers = malloc(sizeof(bool) * entries); 301 318 if (!buffers) ··· 305 322 if (read_fd < 0) 306 323 return 1; 307 324 308 - reg.ring_addr = (unsigned long) ptr; 309 - reg.ring_entries = entries; 310 - reg.bgid = bgid; 311 - 312 - ret = io_uring_register_buf_ring(&ring, &reg, 0); 313 - if (ret) { 314 - /* by now should have checked if this is supported or not */ 315 - fprintf(stderr, "Buffer ring register failed %d\n", ret); 316 - return 1; 317 - } 318 - 319 325 for (loop = 0; loop < loops; loop++) { 320 326 memset(buffers, 0, sizeof(bool) * entries); 321 327 for (idx = 0; idx < entries; idx++) ··· 374 380 if (argc > 1) 375 381 return T_EXIT_SKIP; 376 382 383 + pagesize = getpagesize(); 384 + 377 385 for (i = 0; bgids[i] != -1; i++) { 378 386 ret = test_reg_unreg(bgids[i]); 379 387 if (ret) { ··· 404 412 ret = test_mixed_reg2(bgids[i]); 405 413 if (ret) { 406 414 fprintf(stderr, "test_mixed_reg2 failed\n"); 415 + return T_EXIT_FAIL; 416 + } 417 + 418 + ret = test_full_page_reg(bgids[i]); 419 + if (ret == T_EXIT_FAIL) { 420 + fprintf(stderr, "test_full_page_reg failed\n"); 407 421 return T_EXIT_FAIL; 408 422 } 409 423 }
+2 -2
vendor/opam/uring/vendor/liburing/test/ce593a6c480a.c
··· 15 15 16 16 static int use_sqpoll = 0; 17 17 18 - void notify_fd(int fd) 18 + static void notify_fd(int fd) 19 19 { 20 20 char buf[8] = {0, 0, 0, 0, 0, 0, 1}; 21 21 int ret; ··· 25 25 perror("write"); 26 26 } 27 27 28 - void *delay_set_fd_from_thread(void *data) 28 + static void *delay_set_fd_from_thread(void *data) 29 29 { 30 30 int fd = (intptr_t) data; 31 31
+2 -1
vendor/opam/uring/vendor/liburing/test/close-opath.c
··· 15 15 16 16 #include <errno.h> 17 17 #include <fcntl.h> 18 - #include <liburing.h> 19 18 #include <sys/stat.h> 20 19 #include <stdio.h> 21 20 #include <string.h> 22 21 #include <unistd.h> 22 + 23 + #include "liburing.h" 23 24 24 25 typedef struct 25 26 {
+204
vendor/opam/uring/vendor/liburing/test/connect-rep.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Check that repeated IORING_OP_CONNECT to a socket without a listener keeps 4 + * yielding -ECONNREFUSED rather than -ECONNABORTED. Based on a reproducer 5 + * from: 6 + * 7 + * https://github.com/axboe/liburing/issues/828 8 + * 9 + * and adopted to our usual test cases. Other changes made like looping, 10 + * using different ring types, adding a memset() for reuse, etc. 11 + * 12 + */ 13 + #include <stdio.h> 14 + #include <netinet/in.h> 15 + #include <string.h> 16 + #include <unistd.h> 17 + #include <stdlib.h> 18 + #include <arpa/inet.h> 19 + 20 + #include "liburing.h" 21 + #include "helpers.h" 22 + 23 + static unsigned long ud; 24 + 25 + static int init_test_server(struct sockaddr_in *serv_addr) 26 + { 27 + socklen_t servaddr_len = sizeof(struct sockaddr_in); 28 + int fd; 29 + 30 + /* Init server socket. Bind but don't listen */ 31 + fd = socket(AF_INET, SOCK_STREAM, 0); 32 + if (fd < 0) { 33 + perror("socket"); 34 + return -1; 35 + } 36 + 37 + serv_addr->sin_family = AF_INET; 38 + serv_addr->sin_addr.s_addr = inet_addr("127.0.0.1"); 39 + 40 + if (bind(fd, (struct sockaddr *) serv_addr, servaddr_len) < 0) { 41 + perror("bind"); 42 + return -1; 43 + } 44 + 45 + /* 46 + * Get the addresses the socket is bound to because the port is chosen 47 + * by the network stack. 48 + */ 49 + if (getsockname(fd, (struct sockaddr *)serv_addr, &servaddr_len) < 0) { 50 + perror("getsockname"); 51 + return -1; 52 + } 53 + 54 + return fd; 55 + } 56 + 57 + static int init_test_client(void) 58 + { 59 + socklen_t addr_len = sizeof(struct sockaddr_in); 60 + struct sockaddr_in client_addr = {}; 61 + int clientfd; 62 + 63 + clientfd = socket(AF_INET, SOCK_STREAM, 0); 64 + if (clientfd < 0) { 65 + perror("socket"); 66 + return -1; 67 + } 68 + 69 + client_addr.sin_family = AF_INET; 70 + client_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 71 + 72 + if (bind(clientfd, (struct sockaddr *)&client_addr, addr_len) < 0) { 73 + perror("bind"); 74 + close(clientfd); 75 + return -1; 76 + } 77 + 78 + /* 79 + * Get the addresses the socket is bound to because the port is chosen 80 + * by the network stack. 81 + */ 82 + if (getsockname(clientfd, (struct sockaddr *)&client_addr, &addr_len) < 0) { 83 + perror("getsockname"); 84 + close(clientfd); 85 + return -1; 86 + } 87 + 88 + return clientfd; 89 + } 90 + 91 + static int get_completion_and_print(struct io_uring *ring) 92 + { 93 + struct io_uring_cqe *cqe; 94 + int ret, res; 95 + 96 + ret = io_uring_wait_cqe(ring, &cqe); 97 + if (ret < 0) { 98 + fprintf(stderr, "wait_cqe=%d\n", ret); 99 + return -1; 100 + } 101 + 102 + /* Mark this completion as seen */ 103 + res = cqe->res; 104 + io_uring_cqe_seen(ring, cqe); 105 + return res; 106 + } 107 + 108 + static int test_connect(struct io_uring *ring, 109 + int clientfd, struct sockaddr_in *serv_addr) 110 + { 111 + struct sockaddr_in local_sa; 112 + struct io_uring_sqe *sqe; 113 + int ret; 114 + 115 + sqe = io_uring_get_sqe(ring); 116 + io_uring_prep_connect(sqe, clientfd, (const struct sockaddr *)serv_addr, 117 + sizeof(struct sockaddr_in)); 118 + sqe->user_data = ++ud; 119 + 120 + memcpy(&local_sa, serv_addr, sizeof(local_sa)); 121 + 122 + ret = io_uring_submit_and_wait(ring, 1); 123 + if (ret != 1) { 124 + fprintf(stderr, "submit=%d\n", ret); 125 + return T_EXIT_FAIL; 126 + } 127 + 128 + /* check for reuse at the same time */ 129 + memset(&local_sa, 0xff, sizeof(local_sa)); 130 + 131 + ret = get_completion_and_print(ring); 132 + if (ret != -ECONNREFUSED) { 133 + fprintf(stderr, "Connect got %d\n", ret); 134 + return T_EXIT_FAIL; 135 + } 136 + return T_EXIT_PASS; 137 + } 138 + 139 + static int test(int flags) 140 + { 141 + struct io_uring_params params = { .flags = flags, }; 142 + struct sockaddr_in serv_addr = {}; 143 + struct io_uring ring; 144 + int ret, clientfd, s_fd, i; 145 + 146 + if (flags & IORING_SETUP_SQPOLL) 147 + params.sq_thread_idle = 50; 148 + 149 + ret = io_uring_queue_init_params(8, &ring, &params); 150 + if (ret < 0) { 151 + fprintf(stderr, "Queue init: %d\n", ret); 152 + return T_EXIT_FAIL; 153 + } 154 + 155 + s_fd = init_test_server(&serv_addr); 156 + if (s_fd < 0) 157 + return T_EXIT_FAIL; 158 + 159 + clientfd = init_test_client(); 160 + if (clientfd < 0) { 161 + close(s_fd); 162 + return T_EXIT_FAIL; 163 + } 164 + 165 + /* make sure SQPOLL thread is sleeping */ 166 + if (flags & IORING_SETUP_SQPOLL) 167 + usleep(100000); 168 + 169 + for (i = 0; i < 32; i++) { 170 + ret = test_connect(&ring, clientfd, &serv_addr); 171 + if (ret == T_EXIT_SKIP) 172 + return T_EXIT_SKIP; 173 + else if (ret == T_EXIT_PASS) 174 + continue; 175 + 176 + return T_EXIT_FAIL; 177 + } 178 + 179 + close(s_fd); 180 + close(clientfd); 181 + return T_EXIT_PASS; 182 + } 183 + 184 + int main(int argc, char *argv[]) 185 + { 186 + int ret; 187 + 188 + if (argc > 1) 189 + return T_EXIT_SKIP; 190 + 191 + ret = test(0); 192 + if (ret == T_EXIT_FAIL) { 193 + fprintf(stderr, "test(0) failed\n"); 194 + return T_EXIT_FAIL; 195 + } 196 + 197 + ret = test(IORING_SETUP_SQPOLL); 198 + if (ret == T_EXIT_FAIL) { 199 + fprintf(stderr, "test(SQPOLL) failed\n"); 200 + return T_EXIT_FAIL; 201 + } 202 + 203 + return 0; 204 + }
+8
vendor/opam/uring/vendor/liburing/test/connect.c
··· 15 15 #include <netinet/in.h> 16 16 #include <netinet/tcp.h> 17 17 #include <arpa/inet.h> 18 + #include <sys/stat.h> 18 19 19 20 #include "liburing.h" 20 21 #include "helpers.h" ··· 256 257 struct sockaddr_in addr; 257 258 struct io_uring_sqe *sqe; 258 259 struct __kernel_timespec ts = {.tv_sec = 0, .tv_nsec = 100000}; 260 + struct stat sb; 261 + 262 + /* 263 + * Test reliably fails if syncookies isn't enabled 264 + */ 265 + if (stat("/proc/sys/net/ipv4/tcp_syncookies", &sb) < 0) 266 + return T_EXIT_SKIP; 259 267 260 268 connect_fd[0] = create_socket(); 261 269 if (connect_fd[0] == -1)
+14 -8
vendor/opam/uring/vendor/liburing/test/cq-overflow.c
··· 48 48 * bash -c "echo 1 > /proc/self/make-it-fail && exec ./cq-overflow.t" 49 49 */ 50 50 51 - static int test_io(const char *file, unsigned long usecs, unsigned *drops, int fault) 51 + static int test_io(const char *file, unsigned long usecs, unsigned *drops, 52 + int fault) 52 53 { 53 54 struct io_uring_sqe *sqe; 54 55 struct io_uring_cqe *cqe; ··· 60 61 61 62 fd = open(file, O_RDONLY | O_DIRECT); 62 63 if (fd < 0) { 64 + if (errno == EINVAL) 65 + return T_EXIT_SKIP; 63 66 perror("file open"); 64 - return 1; 67 + return T_EXIT_FAIL; 65 68 } 66 69 67 70 memset(&p, 0, sizeof(p)); ··· 69 72 if (ret) { 70 73 close(fd); 71 74 fprintf(stderr, "ring create failed: %d\n", ret); 72 - return 1; 75 + return T_EXIT_FAIL; 73 76 } 74 77 nodrop = 0; 75 78 if (p.features & IORING_FEAT_NODROP) ··· 173 176 174 177 io_uring_queue_exit(&ring); 175 178 close(fd); 176 - return 0; 179 + return T_EXIT_PASS; 177 180 err: 178 181 if (fd != -1) 179 182 close(fd); 180 183 io_uring_queue_exit(&ring); 181 - return 1; 184 + return T_EXIT_SKIP; 182 185 } 183 186 184 187 static int reap_events(struct io_uring *ring, unsigned nr_events, int do_wait) ··· 496 499 do { 497 500 drops = 0; 498 501 499 - if (test_io(fname, usecs, &drops, 0)) { 502 + ret = test_io(fname, usecs, &drops, 0); 503 + if (ret == T_EXIT_SKIP) 504 + break; 505 + else if (ret != T_EXIT_PASS) { 500 506 fprintf(stderr, "test_io nofault failed\n"); 501 507 goto err; 502 508 } ··· 506 512 iters++; 507 513 } while (iters < 40); 508 514 509 - if (test_io(fname, usecs, &drops, 0)) { 515 + if (test_io(fname, usecs, &drops, 0) == T_EXIT_FAIL) { 510 516 fprintf(stderr, "test_io nofault failed\n"); 511 517 goto err; 512 518 } 513 519 514 - if (test_io(fname, usecs, &drops, 1)) { 520 + if (test_io(fname, usecs, &drops, 1) == T_EXIT_FAIL) { 515 521 fprintf(stderr, "test_io fault failed\n"); 516 522 goto err; 517 523 }
+1 -1
vendor/opam/uring/vendor/liburing/test/d4ae271dfaae.c
··· 29 29 30 30 memset(&p, 0, sizeof(p)); 31 31 p.flags = IORING_SETUP_SQPOLL; 32 - ret = t_create_ring_params(4, &ring, &p); 32 + ret = t_create_ring_params(16, &ring, &p); 33 33 if (ret == T_SETUP_SKIP) 34 34 return T_EXIT_SKIP; 35 35 else if (ret < 0)
+64 -9
vendor/opam/uring/vendor/liburing/test/defer-taskrun.c
··· 4 4 #include <unistd.h> 5 5 #include <stdlib.h> 6 6 #include <string.h> 7 - #include <error.h> 8 7 #include <sys/eventfd.h> 9 8 #include <signal.h> 10 9 #include <poll.h> ··· 57 56 assert(ret == sizeof(val)); 58 57 } 59 58 60 - #define CHECK(x) if (!(x)) { \ 61 - fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \ 62 - return -1; } 59 + #define CHECK(x) \ 60 + do { \ 61 + if (!(x)) { \ 62 + fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \ 63 + return -1; \ 64 + } \ 65 + } while (0) 66 + 63 67 64 68 static int test_eventfd(void) 65 69 { ··· 119 123 char buff[8]; 120 124 }; 121 125 122 - void *thread(void *t) 126 + static void *thread(void *t) 123 127 { 124 128 struct thread_data *td = t; 125 129 ··· 178 182 int wstatus; 179 183 180 184 CHECK(waitpid(fork_pid, &wstatus, 0) != (pid_t)-1); 181 - if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != T_EXIT_SKIP) { 185 + if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) == T_EXIT_FAIL) { 182 186 fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus)); 183 187 return -1; 184 188 } 185 - return 0; 189 + return T_EXIT_PASS; 186 190 } 187 191 188 192 ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | ··· 192 196 193 197 if (filename) { 194 198 fd = open(filename, O_RDONLY | O_DIRECT); 199 + if (fd < 0 && errno == EINVAL) 200 + return T_EXIT_SKIP; 195 201 } else { 196 202 t_create_file(EXEC_FILENAME, EXEC_FILESIZE); 197 203 fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT); 204 + if (fd < 0 && errno == EINVAL) { 205 + unlink(EXEC_FILENAME); 206 + return T_EXIT_SKIP; 207 + } 198 208 unlink(EXEC_FILENAME); 199 209 } 200 210 buff = (char*)malloc(EXEC_FILESIZE); ··· 207 217 ret = execve("/proc/self/exe", new_argv, new_env); 208 218 /* if we get here it failed anyway */ 209 219 fprintf(stderr, "execve failed %d\n", ret); 210 - return -1; 220 + return T_EXIT_FAIL; 211 221 } 212 222 213 223 static int test_flag(void) ··· 283 293 return 0; 284 294 } 285 295 296 + static int test_drain(void) 297 + { 298 + struct io_uring ring; 299 + int ret, i, fd[2]; 300 + struct io_uring_sqe *sqe; 301 + struct io_uring_cqe *cqe; 302 + struct iovec iovecs[128]; 303 + char buff[ARRAY_SIZE(iovecs)]; 304 + 305 + ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | 306 + IORING_SETUP_DEFER_TASKRUN | 307 + IORING_SETUP_TASKRUN_FLAG); 308 + CHECK(!ret); 309 + 310 + for (i = 0; i < ARRAY_SIZE(iovecs); i++) { 311 + iovecs[i].iov_base = &buff[i]; 312 + iovecs[i].iov_len = 1; 313 + } 314 + 315 + ret = t_create_socket_pair(fd, true); 316 + CHECK(!ret); 317 + 318 + sqe = io_uring_get_sqe(&ring); 319 + io_uring_prep_writev(sqe, fd[1], &iovecs[0], ARRAY_SIZE(iovecs), 0); 320 + sqe->flags |= IOSQE_IO_DRAIN; 321 + io_uring_submit(&ring); 322 + 323 + for (i = 0; i < ARRAY_SIZE(iovecs); i++) 324 + iovecs[i].iov_base = NULL; 325 + 326 + CHECK(io_uring_wait_cqe(&ring, &cqe) == 0); 327 + CHECK(cqe->res == 128); 328 + 329 + close(fd[0]); 330 + close(fd[1]); 331 + io_uring_queue_exit(&ring); 332 + return 0; 333 + } 334 + 286 335 int main(int argc, char *argv[]) 287 336 { 288 337 int ret; ··· 309 358 } 310 359 311 360 ret = test_exec(filename); 312 - if (ret) { 361 + if (ret == T_EXIT_FAIL) { 313 362 fprintf(stderr, "test_exec failed\n"); 314 363 return T_EXIT_FAIL; 315 364 } ··· 329 378 ret = test_ring_shutdown(); 330 379 if (ret) { 331 380 fprintf(stderr, "test_ring_shutdown failed\n"); 381 + return T_EXIT_FAIL; 382 + } 383 + 384 + ret = test_drain(); 385 + if (ret) { 386 + fprintf(stderr, "test_drain failed\n"); 332 387 return T_EXIT_FAIL; 333 388 } 334 389
+1 -1
vendor/opam/uring/vendor/liburing/test/defer.c
··· 57 57 case OP_REMOVE_BUFFERS: 58 58 io_uring_prep_remove_buffers(sqe, 10, 1); 59 59 break; 60 - }; 60 + } 61 61 sqe->user_data = i; 62 62 ctx->sqes[i] = sqe; 63 63 }
+3 -3
vendor/opam/uring/vendor/liburing/test/double-poll-crash.c
··· 109 109 } 110 110 } 111 111 112 - uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff}; 112 + static uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff}; 113 113 114 114 int main(int argc, char *argv[]) 115 115 { ··· 121 121 if (argc > 1) 122 122 return T_EXIT_SKIP; 123 123 124 - mmap_ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul); 124 + mmap_ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 125 125 if (mmap_ret == MAP_FAILED) 126 126 return T_EXIT_SKIP; 127 - mmap_ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); 127 + mmap_ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 128 128 if (mmap_ret == MAP_FAILED) 129 129 return T_EXIT_SKIP; 130 130 intptr_t res = 0;
+8 -3
vendor/opam/uring/vendor/liburing/test/eeed8b54e0df.c
··· 102 102 goto err; 103 103 } 104 104 105 + ret = T_EXIT_PASS; 105 106 if (cqe->res != -EAGAIN && cqe->res != 4096) { 106 - printf("cqe error: %d\n", cqe->res); 107 - goto err; 107 + if (cqe->res == -EOPNOTSUPP) { 108 + ret = T_EXIT_SKIP; 109 + } else { 110 + printf("cqe error: %d\n", cqe->res); 111 + goto err; 112 + } 108 113 } 109 114 110 115 close(fd); 111 - return T_EXIT_PASS; 116 + return ret; 112 117 err: 113 118 close(fd); 114 119 return T_EXIT_FAIL;
+74
vendor/opam/uring/vendor/liburing/test/eploop.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Test that we don't recursively generate completion events if an io_uring 4 + * fd is added to an epoll context, and the ring itself polls for events on 5 + * the epollfd. Older kernels will stop on overflow, newer kernels will 6 + * detect this earlier and abort correctly. 7 + */ 8 + #include <stdio.h> 9 + #include <unistd.h> 10 + #include <stdlib.h> 11 + #include <sys/epoll.h> 12 + #include <sys/types.h> 13 + #include <poll.h> 14 + #include "liburing.h" 15 + #include "helpers.h" 16 + 17 + int main(int argc, char *argv[]) 18 + { 19 + struct io_uring ring; 20 + struct io_uring_sqe *sqe; 21 + struct io_uring_cqe *cqe; 22 + struct epoll_event ev = { }; 23 + int epollfd, ret, i; 24 + 25 + if (argc > 1) 26 + return T_EXIT_SKIP; 27 + 28 + ret = io_uring_queue_init(8, &ring, 0); 29 + if (ret) { 30 + fprintf(stderr, "Ring init failed: %d\n", ret); 31 + return T_EXIT_FAIL; 32 + } 33 + 34 + epollfd = epoll_create1(0); 35 + if (epollfd < 0) { 36 + perror("epoll_create"); 37 + return T_EXIT_FAIL; 38 + } 39 + 40 + ev.events = EPOLLIN; 41 + ev.data.fd = ring.ring_fd; 42 + ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, ring.ring_fd, &ev); 43 + if (ret < 0) { 44 + perror("epoll_ctl"); 45 + return T_EXIT_FAIL; 46 + } 47 + 48 + sqe = io_uring_get_sqe(&ring); 49 + io_uring_prep_poll_multishot(sqe, epollfd, POLLIN); 50 + sqe->user_data = 1; 51 + io_uring_submit(&ring); 52 + 53 + sqe = io_uring_get_sqe(&ring); 54 + sqe->user_data = 2; 55 + io_uring_prep_nop(sqe); 56 + io_uring_submit(&ring); 57 + 58 + for (i = 0; i < 2; i++) { 59 + ret = io_uring_wait_cqe(&ring, &cqe); 60 + if (ret) { 61 + fprintf(stderr, "wait_cqe ret = %d\n", ret); 62 + break; 63 + } 64 + io_uring_cqe_seen(&ring, cqe); 65 + } 66 + 67 + ret = io_uring_peek_cqe(&ring, &cqe); 68 + if (!ret) { 69 + fprintf(stderr, "Generated too many events\n"); 70 + return T_EXIT_FAIL; 71 + } 72 + 73 + return T_EXIT_PASS; 74 + }
+1 -1
vendor/opam/uring/vendor/liburing/test/eventfd-ring.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 2 /* 3 - * Description: run various nop tests 3 + * Description: test use of eventfds with multiple rings 4 4 * 5 5 */ 6 6 #include <errno.h>
+1 -1
vendor/opam/uring/vendor/liburing/test/eventfd.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 2 /* 3 - * Description: run various nop tests 3 + * Description: run various eventfd tests 4 4 * 5 5 */ 6 6 #include <errno.h>
+73
vendor/opam/uring/vendor/liburing/test/evloop.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Test that we don't recursively generate completion events if an io_uring 4 + * has an eventfd registered that triggers on completions, and we add a poll 5 + * request with multishot on the eventfd. Older kernels will stop on overflow, 6 + * newer kernels will detect this earlier and abort correctly. 7 + */ 8 + #include <errno.h> 9 + #include <stdio.h> 10 + #include <unistd.h> 11 + #include <stdlib.h> 12 + #include <sys/eventfd.h> 13 + #include <sys/types.h> 14 + #include <poll.h> 15 + #include <assert.h> 16 + #include "liburing.h" 17 + #include "helpers.h" 18 + 19 + int main(int argc, char *argv[]) 20 + { 21 + struct io_uring ring; 22 + struct io_uring_sqe *sqe; 23 + struct io_uring_cqe *cqe; 24 + int ret, efd, i; 25 + 26 + if (argc > 1) 27 + return T_EXIT_SKIP; 28 + 29 + ret = io_uring_queue_init(8, &ring, 0); 30 + if (ret) { 31 + fprintf(stderr, "Ring init failed: %d\n", ret); 32 + return T_EXIT_FAIL; 33 + } 34 + 35 + efd = eventfd(0, 0); 36 + if (efd < 0) { 37 + perror("eventfd"); 38 + return T_EXIT_FAIL; 39 + } 40 + 41 + ret = io_uring_register_eventfd(&ring, efd); 42 + if (ret) { 43 + fprintf(stderr, "Ring eventfd register failed: %d\n", ret); 44 + return T_EXIT_FAIL; 45 + } 46 + 47 + sqe = io_uring_get_sqe(&ring); 48 + io_uring_prep_poll_multishot(sqe, efd, POLLIN); 49 + sqe->user_data = 1; 50 + io_uring_submit(&ring); 51 + 52 + sqe = io_uring_get_sqe(&ring); 53 + sqe->user_data = 2; 54 + io_uring_prep_nop(sqe); 55 + io_uring_submit(&ring); 56 + 57 + for (i = 0; i < 2; i++) { 58 + ret = io_uring_wait_cqe(&ring, &cqe); 59 + if (ret) { 60 + fprintf(stderr, "wait_cqe ret = %d\n", ret); 61 + break; 62 + } 63 + io_uring_cqe_seen(&ring, cqe); 64 + } 65 + 66 + ret = io_uring_peek_cqe(&ring, &cqe); 67 + if (!ret) { 68 + fprintf(stderr, "Generated too many events\n"); 69 + return T_EXIT_FAIL; 70 + } 71 + 72 + return T_EXIT_PASS; 73 + }
+1 -1
vendor/opam/uring/vendor/liburing/test/exit-no-cleanup.c
··· 26 26 static int sleep_fd, notify_fd; 27 27 static sem_t sem; 28 28 29 - void *thread_func(void *arg) 29 + static void *thread_func(void *arg) 30 30 { 31 31 struct io_uring ring; 32 32 int res;
+1 -1
vendor/opam/uring/vendor/liburing/test/fadvise.c
··· 186 186 } 187 187 188 188 /* too hard to reliably test, just ignore */ 189 - if (0 && bad > good) { 189 + if ((0) && bad > good) { 190 190 fprintf(stderr, "Suspicious timings\n"); 191 191 goto err; 192 192 }
+9
vendor/opam/uring/vendor/liburing/test/fallocate.c
··· 12 12 #include <stdlib.h> 13 13 #include <string.h> 14 14 #include <fcntl.h> 15 + #include <signal.h> 15 16 16 17 #include "liburing.h" 17 18 #include "helpers.h" ··· 216 217 return 1; 217 218 } 218 219 220 + static void sig_xfsz(int sig) 221 + { 222 + } 223 + 219 224 int main(int argc, char *argv[]) 220 225 { 226 + struct sigaction act = { }; 221 227 struct io_uring ring; 222 228 int ret; 223 229 224 230 if (argc > 1) 225 231 return T_EXIT_SKIP; 232 + 233 + act.sa_handler = sig_xfsz; 234 + sigaction(SIGXFSZ, &act, NULL); 226 235 227 236 ret = io_uring_queue_init(8, &ring, 0); 228 237 if (ret) {
+3 -3
vendor/opam/uring/vendor/liburing/test/fc2a85cb02ef.c
··· 54 54 return fd; 55 55 } 56 56 57 - static int setup_fault() 57 + static int setup_fault(void) 58 58 { 59 59 static struct { 60 60 const char* file; ··· 79 79 return 0; 80 80 } 81 81 82 - uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; 82 + static uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; 83 83 84 84 int main(int argc, char *argv[]) 85 85 { 86 86 if (argc > 1) 87 87 return T_EXIT_SKIP; 88 - mmap((void *) 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0); 88 + mmap((void *) 0x20000000ul, 0x1000000ul, 3ul, MAP_ANON|MAP_PRIVATE, -1, 0); 89 89 if (setup_fault()) { 90 90 printf("Test needs failslab/fail_futex/fail_page_alloc enabled, skipped\n"); 91 91 return T_EXIT_SKIP;
+67 -17
vendor/opam/uring/vendor/liburing/test/fd-pass.c
··· 13 13 #include "liburing.h" 14 14 #include "helpers.h" 15 15 16 - #define FSIZE 128 17 - #define PAT 0x9a 16 + #define FSIZE 128 17 + #define PAT 0x9a 18 + #define USER_DATA 0x89 18 19 19 20 static int no_fd_pass; 20 21 ··· 49 50 return 0; 50 51 } 51 52 52 - static int test(const char *filename) 53 + static int test(const char *filename, int source_fd, int target_fd) 53 54 { 54 55 struct io_uring sring, dring; 55 56 struct io_uring_sqe *sqe; ··· 79 80 fprintf(stderr, "register files failed %d\n", ret); 80 81 return T_EXIT_FAIL; 81 82 } 83 + if (target_fd == IORING_FILE_INDEX_ALLOC) { 84 + /* we want to test installing into a non-zero slot */ 85 + ret = io_uring_register_file_alloc_range(&dring, 1, 1); 86 + if (ret) { 87 + fprintf(stderr, "io_uring_register_file_alloc_range %d\n", ret); 88 + return T_EXIT_FAIL; 89 + } 90 + } 82 91 83 92 /* open direct descriptor */ 84 93 sqe = io_uring_get_sqe(&sring); 85 - io_uring_prep_openat_direct(sqe, AT_FDCWD, filename, 0, 0644, 0); 94 + io_uring_prep_openat_direct(sqe, AT_FDCWD, filename, 0, 0644, source_fd); 86 95 io_uring_submit(&sring); 87 96 ret = io_uring_wait_cqe(&sring, &cqe); 88 97 if (ret) { ··· 96 105 io_uring_cqe_seen(&sring, cqe); 97 106 98 107 /* verify data is sane for source ring */ 99 - if (verify_fixed_read(&sring, 0, 0)) 108 + if (verify_fixed_read(&sring, source_fd, 0)) 100 109 return T_EXIT_FAIL; 101 110 102 111 /* send direct descriptor to destination ring */ 103 112 sqe = io_uring_get_sqe(&sring); 104 - io_uring_prep_msg_ring(sqe, dring.ring_fd, 0, 0x89, 0); 105 - sqe->addr = 1; 106 - sqe->addr3 = 0; 107 - sqe->file_index = 1; 113 + if (target_fd == IORING_FILE_INDEX_ALLOC) { 114 + io_uring_prep_msg_ring_fd_alloc(sqe, dring.ring_fd, source_fd, 115 + USER_DATA, 0); 116 + } else { 117 + 118 + io_uring_prep_msg_ring_fd(sqe, dring.ring_fd, source_fd, 119 + target_fd, USER_DATA, 0); 120 + } 108 121 io_uring_submit(&sring); 109 122 110 123 ret = io_uring_wait_cqe(&sring, &cqe); ··· 112 125 fprintf(stderr, "wait cqe failed %d\n", ret); 113 126 return T_EXIT_FAIL; 114 127 } 115 - if (cqe->res) { 128 + if (cqe->res < 0) { 116 129 if (cqe->res == -EINVAL && !no_fd_pass) { 117 130 no_fd_pass = 1; 118 131 return T_EXIT_SKIP; ··· 128 141 fprintf(stderr, "wait cqe failed %d\n", ret); 129 142 return T_EXIT_FAIL; 130 143 } 131 - if (cqe->user_data != 0x89) { 144 + if (cqe->user_data != USER_DATA) { 132 145 fprintf(stderr, "bad user_data %ld\n", (long) cqe->res); 133 146 return T_EXIT_FAIL; 134 147 } 148 + if (cqe->res < 0) { 149 + fprintf(stderr, "bad result %i\n", cqe->res); 150 + return T_EXIT_FAIL; 151 + } 152 + if (target_fd == IORING_FILE_INDEX_ALLOC) { 153 + if (cqe->res != 1) { 154 + fprintf(stderr, "invalid allocated index %i\n", cqe->res); 155 + return T_EXIT_FAIL; 156 + } 157 + target_fd = cqe->res; 158 + } 135 159 io_uring_cqe_seen(&dring, cqe); 136 160 137 161 /* now verify we can read the sane data from the destination ring */ 138 - if (verify_fixed_read(&dring, 0, 0)) 162 + if (verify_fixed_read(&dring, target_fd, 0)) 139 163 return T_EXIT_FAIL; 140 164 141 165 /* close descriptor in source ring */ 142 166 sqe = io_uring_get_sqe(&sring); 143 - io_uring_prep_close_direct(sqe, 0); 167 + io_uring_prep_close_direct(sqe, source_fd); 144 168 io_uring_submit(&sring); 145 169 146 170 ret = io_uring_wait_cqe(&sring, &cqe); ··· 155 179 io_uring_cqe_seen(&sring, cqe); 156 180 157 181 /* check that source ring fails after close */ 158 - if (verify_fixed_read(&sring, 0, 1)) 182 + if (verify_fixed_read(&sring, source_fd, 1)) 159 183 return T_EXIT_FAIL; 160 184 161 185 /* check we can still read from destination ring */ 162 - if (verify_fixed_read(&dring, 0, 0)) 186 + if (verify_fixed_read(&dring, target_fd, 0)) 163 187 return T_EXIT_FAIL; 164 188 189 + io_uring_queue_exit(&sring); 190 + io_uring_queue_exit(&dring); 165 191 return T_EXIT_PASS; 166 192 } 167 193 ··· 176 202 sprintf(fname, ".fd-pass.%d", getpid()); 177 203 t_create_file_pattern(fname, FSIZE, PAT); 178 204 179 - ret = test(fname); 205 + ret = test(fname, 0, 1); 180 206 if (ret == T_EXIT_FAIL) { 181 - fprintf(stderr, "test failed\n"); 207 + fprintf(stderr, "test failed 0 1\n"); 208 + ret = T_EXIT_FAIL; 209 + } 210 + 211 + ret = test(fname, 0, 2); 212 + if (ret == T_EXIT_FAIL) { 213 + fprintf(stderr, "test failed 0 2\n"); 214 + ret = T_EXIT_FAIL; 215 + } 216 + 217 + ret = test(fname, 1, 1); 218 + if (ret == T_EXIT_FAIL) { 219 + fprintf(stderr, "test failed 1 1\n"); 220 + ret = T_EXIT_FAIL; 221 + } 222 + 223 + ret = test(fname, 1, 0); 224 + if (ret == T_EXIT_FAIL) { 225 + fprintf(stderr, "test failed 1 0\n"); 226 + ret = T_EXIT_FAIL; 227 + } 228 + 229 + ret = test(fname, 1, IORING_FILE_INDEX_ALLOC); 230 + if (ret == T_EXIT_FAIL) { 231 + fprintf(stderr, "test failed 1 ALLOC\n"); 182 232 ret = T_EXIT_FAIL; 183 233 } 184 234
+61
vendor/opam/uring/vendor/liburing/test/file-register.c
··· 935 935 return 0; 936 936 } 937 937 938 + static int test_defer_taskrun(void) 939 + { 940 + struct io_uring_sqe *sqe; 941 + struct io_uring ring; 942 + int ret, fds[2]; 943 + char buff = 'x'; 944 + 945 + ret = io_uring_queue_init(8, &ring, 946 + IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER); 947 + if (ret) { 948 + fprintf(stderr, "ring init\n"); 949 + return 1; 950 + } 951 + 952 + ret = pipe(fds); 953 + if (ret) { 954 + fprintf(stderr, "bad pipes\n"); 955 + return 1; 956 + } 957 + 958 + ret = io_uring_register_files(&ring, &fds[0], 2); 959 + if (ret) { 960 + fprintf(stderr, "bad register %d\n", ret); 961 + return 1; 962 + } 963 + 964 + sqe = io_uring_get_sqe(&ring); 965 + io_uring_prep_read(sqe, 0, &buff, 1, 0); 966 + sqe->flags |= IOSQE_FIXED_FILE; 967 + ret = io_uring_submit(&ring); 968 + if (ret != 1) { 969 + fprintf(stderr, "bad submit\n"); 970 + return 1; 971 + } 972 + 973 + ret = write(fds[1], &buff, 1); 974 + if (ret != 1) { 975 + fprintf(stderr, "bad pipe write\n"); 976 + return 1; 977 + } 978 + 979 + ret = io_uring_unregister_files(&ring); 980 + if (ret) { 981 + fprintf(stderr, "bad unregister %d\n", ret); 982 + return 1; 983 + } 984 + 985 + close(fds[0]); 986 + close(fds[1]); 987 + io_uring_queue_exit(&ring); 988 + return 0; 989 + } 990 + 938 991 static int test_file_alloc_ranges(void) 939 992 { 940 993 struct io_uring ring; ··· 1118 1171 if (ret) { 1119 1172 fprintf(stderr, "test_partial_register_fail failed\n"); 1120 1173 return T_EXIT_FAIL; 1174 + } 1175 + 1176 + if (t_probe_defer_taskrun()) { 1177 + ret = test_defer_taskrun(); 1178 + if (ret) { 1179 + fprintf(stderr, "test_defer_taskrun failed\n"); 1180 + return T_EXIT_FAIL; 1181 + } 1121 1182 } 1122 1183 1123 1184 return T_EXIT_PASS;
+29 -8
vendor/opam/uring/vendor/liburing/test/file-verify.c
··· 10 10 #include <string.h> 11 11 #include <fcntl.h> 12 12 #include <assert.h> 13 - #include <string.h> 14 13 #include <sys/ioctl.h> 15 14 #include <sys/stat.h> 16 15 #include <linux/fs.h> ··· 33 32 */ 34 33 #define READ_BATCH 16 35 34 35 + static void verify_buf_sync(void *buf, size_t size, bool registered) 36 + { 37 + #if defined(__hppa__) 38 + if (registered) { 39 + unsigned long off = (unsigned long) buf & 4095; 40 + unsigned long p = (unsigned long) buf & ~4095; 41 + int i; 42 + 43 + size += off; 44 + for (i = 0; i < size; i += 32) 45 + asm volatile("fdc 0(%0)" : : "r" (p + i)); 46 + } 47 + #endif 48 + } 49 + 36 50 /* 37 51 * Each offset in the file has the offset / sizeof(int) stored for every 38 52 * sizeof(int) address. 39 53 */ 40 - static int verify_buf(void *buf, size_t size, off_t off) 54 + static int verify_buf(void *buf, size_t size, off_t off, bool registered) 41 55 { 42 56 int i, u_in_buf = size / sizeof(unsigned int); 43 57 unsigned int *ptr; 44 58 59 + verify_buf_sync(buf, size, registered); 60 + 45 61 off /= sizeof(unsigned int); 46 62 ptr = buf; 47 63 for (i = 0; i < u_in_buf; i++) { 48 64 if (off != *ptr) { 49 - fprintf(stderr, "Found %u, wanted %lu\n", *ptr, off); 65 + fprintf(stderr, "Found %u, wanted %llu\n", *ptr, 66 + (unsigned long long) off); 50 67 return 1; 51 68 } 52 69 ptr++; ··· 197 214 goto err; 198 215 } 199 216 200 - if (verify_buf(buf, CHUNK_SIZE / 2, 0)) 217 + if (verify_buf(buf, CHUNK_SIZE / 2, 0, false)) 201 218 goto err; 202 219 203 220 /* ··· 364 381 v[i].iov_base = buf[i]; 365 382 v[i].iov_len = CHUNK_SIZE; 366 383 } 367 - ret = io_uring_register_buffers(ring, v, READ_BATCH); 384 + ret = t_register_buffers(ring, v, READ_BATCH); 368 385 if (ret) { 369 - fprintf(stderr, "Error buffer reg %d\n", ret); 386 + if (ret == T_SETUP_SKIP) { 387 + ret = 0; 388 + goto free_bufs; 389 + } 370 390 goto err; 371 391 } 372 392 } ··· 445 465 void *buf = vecs[index][j].iov_base; 446 466 size_t len = vecs[index][j].iov_len; 447 467 448 - if (verify_buf(buf, len, voff)) 468 + if (verify_buf(buf, len, voff, registered)) 449 469 goto err; 450 470 voff += len; 451 471 } 452 472 } else { 453 - if (verify_buf(buf[index], CHUNK_SIZE, voff)) 473 + if (verify_buf(buf[index], CHUNK_SIZE, voff, registered)) 454 474 goto err; 455 475 } 456 476 } ··· 460 480 done: 461 481 if (registered) 462 482 io_uring_unregister_buffers(ring); 483 + free_bufs: 463 484 if (vectored) { 464 485 for (j = 0; j < READ_BATCH; j++) 465 486 for (i = 0; i < nr_vecs; i++)
+2 -2
vendor/opam/uring/vendor/liburing/test/files-exit-hang-timeout.c
··· 21 21 22 22 #define PORT 9100 23 23 24 - struct io_uring ring; 24 + static struct io_uring ring; 25 25 26 - struct __kernel_timespec ts = { 26 + static struct __kernel_timespec ts = { 27 27 .tv_sec = 300, 28 28 .tv_nsec = 0, 29 29 };
+1 -1
vendor/opam/uring/vendor/liburing/test/fixed-link.c
··· 36 36 for (i = 0; i < IOVECS_LEN; ++i) { 37 37 iovecs[i].iov_base = t_malloc(64); 38 38 iovecs[i].iov_len = 64; 39 - }; 39 + } 40 40 41 41 ret = io_uring_register_buffers(&ring, iovecs, IOVECS_LEN); 42 42 if (ret) {
+118
vendor/opam/uring/vendor/liburing/test/fsnotify.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: test fsnotify access off O_DIRECT read 4 + */ 5 + 6 + #include "helpers.h" 7 + 8 + #ifdef CONFIG_HAVE_FANOTIFY 9 + #include <stdio.h> 10 + #include <stdlib.h> 11 + #include <unistd.h> 12 + #include <fcntl.h> 13 + #include <sys/fanotify.h> 14 + #include <sys/stat.h> 15 + #include <sys/wait.h> 16 + 17 + #include "liburing.h" 18 + 19 + int main(int argc, char *argv[]) 20 + { 21 + struct io_uring_sqe *sqe; 22 + struct io_uring_cqe *cqe; 23 + struct io_uring ring; 24 + int fan, ret, fd, err; 25 + char fname[64], *f; 26 + struct stat sb; 27 + void *buf; 28 + 29 + fan = fanotify_init(FAN_CLASS_NOTIF|FAN_CLASS_CONTENT, 0); 30 + if (fan < 0) { 31 + if (errno == ENOSYS) 32 + return T_EXIT_SKIP; 33 + if (geteuid()) 34 + return T_EXIT_SKIP; 35 + perror("fanotify_init"); 36 + return T_EXIT_FAIL; 37 + } 38 + 39 + err = T_EXIT_FAIL; 40 + if (argc > 1) { 41 + f = argv[1]; 42 + fd = open(argv[1], O_RDONLY | O_DIRECT); 43 + if (fd < 0 && errno == EINVAL) 44 + return T_EXIT_SKIP; 45 + } else { 46 + sprintf(fname, ".fsnotify.%d", getpid()); 47 + f = fname; 48 + t_create_file(fname, 8192); 49 + fd = open(fname, O_RDONLY | O_DIRECT); 50 + if (fd < 0 && errno == EINVAL) { 51 + unlink(fname); 52 + return T_EXIT_SKIP; 53 + } 54 + } 55 + if (fd < 0) { 56 + perror("open"); 57 + goto out; 58 + } 59 + 60 + if (fstat(fd, &sb) < 0) { 61 + perror("fstat"); 62 + goto out; 63 + } 64 + if ((sb.st_mode & S_IFMT) != S_IFREG) { 65 + err = T_EXIT_SKIP; 66 + close(fd); 67 + goto out; 68 + } 69 + 70 + ret = fanotify_mark(fan, FAN_MARK_ADD, FAN_ACCESS|FAN_MODIFY, fd, NULL); 71 + if (ret < 0) { 72 + perror("fanotify_mark"); 73 + goto out; 74 + } 75 + 76 + if (fork()) { 77 + int wstat; 78 + 79 + io_uring_queue_init(1, &ring, 0); 80 + if (posix_memalign(&buf, 4096, 4096)) 81 + goto out; 82 + sqe = io_uring_get_sqe(&ring); 83 + io_uring_prep_read(sqe, fd, buf, 4096, 0); 84 + io_uring_submit(&ring); 85 + ret = io_uring_wait_cqe(&ring, &cqe); 86 + if (ret) { 87 + fprintf(stderr, "wait_ret=%d\n", ret); 88 + goto out; 89 + } 90 + wait(&wstat); 91 + if (!WEXITSTATUS(wstat)) 92 + err = T_EXIT_PASS; 93 + } else { 94 + struct fanotify_event_metadata m; 95 + int fret; 96 + 97 + fret = read(fan, &m, sizeof(m)); 98 + if (fret < 0) 99 + perror("fanotify read"); 100 + /* fail if mask isn't right or pid indicates non-task context */ 101 + else if (!(m.mask & 1) || !m.pid) 102 + exit(1); 103 + exit(0); 104 + } 105 + 106 + out: 107 + if (f == fname) 108 + unlink(fname); 109 + return err; 110 + } 111 + 112 + #else /* #ifdef CONFIG_HAVE_FANOTIFY */ 113 + 114 + int main(void) 115 + { 116 + return T_EXIT_SKIP; 117 + } 118 + #endif /* #ifdef CONFIG_HAVE_FANOTIFY */
+1 -1
vendor/opam/uring/vendor/liburing/test/hardlink.c
··· 44 44 return 1; 45 45 } 46 46 47 - int files_linked_ok(const char* fn1, const char *fn2) 47 + static int files_linked_ok(const char* fn1, const char *fn2) 48 48 { 49 49 struct stat s1, s2; 50 50
+54 -2
vendor/opam/uring/vendor/liburing/test/helpers.c
··· 8 8 #include <stdio.h> 9 9 #include <fcntl.h> 10 10 #include <unistd.h> 11 + #include <stdarg.h> 11 12 #include <sys/types.h> 12 13 13 14 #include <arpa/inet.h> ··· 134 135 return T_SETUP_SKIP; 135 136 } 136 137 137 - fprintf(stderr, "queue_init: %s\n", strerror(-ret)); 138 + if (ret != -EINVAL) 139 + fprintf(stderr, "queue_init: %s\n", strerror(-ret)); 138 140 return ret; 139 141 } 140 142 ··· 173 175 int val; 174 176 struct sockaddr_in serv_addr; 175 177 struct sockaddr *paddr; 176 - size_t paddrlen; 178 + socklen_t paddrlen; 177 179 178 180 type |= SOCK_CLOEXEC; 179 181 fd[0] = socket(AF_INET, type, 0); ··· 266 268 io_uring_queue_exit(&ring); 267 269 return true; 268 270 } 271 + 272 + /* 273 + * Sync internal state with kernel ring state on the SQ side. Returns the 274 + * number of pending items in the SQ ring, for the shared ring. 275 + */ 276 + unsigned __io_uring_flush_sq(struct io_uring *ring) 277 + { 278 + struct io_uring_sq *sq = &ring->sq; 279 + unsigned tail = sq->sqe_tail; 280 + 281 + if (sq->sqe_head != tail) { 282 + sq->sqe_head = tail; 283 + /* 284 + * Ensure kernel sees the SQE updates before the tail update. 285 + */ 286 + if (!(ring->flags & IORING_SETUP_SQPOLL)) 287 + IO_URING_WRITE_ONCE(*sq->ktail, tail); 288 + else 289 + io_uring_smp_store_release(sq->ktail, tail); 290 + } 291 + /* 292 + * This _may_ look problematic, as we're not supposed to be reading 293 + * SQ->head without acquire semantics. When we're in SQPOLL mode, the 294 + * kernel submitter could be updating this right now. For non-SQPOLL, 295 + * task itself does it, and there's no potential race. But even for 296 + * SQPOLL, the load is going to be potentially out-of-date the very 297 + * instant it's done, regardless or whether or not it's done 298 + * atomically. Worst case, we're going to be over-estimating what 299 + * we can submit. The point is, we need to be able to deal with this 300 + * situation regardless of any perceived atomicity. 301 + */ 302 + return tail - *sq->khead; 303 + } 304 + 305 + /* 306 + * Implementation of error(3), prints an error message and exits. 307 + */ 308 + void t_error(int status, int errnum, const char *format, ...) 309 + { 310 + va_list args; 311 + va_start(args, format); 312 + 313 + vfprintf(stderr, format, args); 314 + if (errnum) 315 + fprintf(stderr, ": %s", strerror(errnum)); 316 + 317 + fprintf(stderr, "\n"); 318 + va_end(args); 319 + exit(status); 320 + }
+4
vendor/opam/uring/vendor/liburing/test/helpers.h
··· 85 85 86 86 bool t_probe_defer_taskrun(void); 87 87 88 + unsigned __io_uring_flush_sq(struct io_uring *ring); 89 + 88 90 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 91 + 92 + void t_error(int status, int errnum, const char *format, ...); 89 93 90 94 #ifdef __cplusplus 91 95 }
+3 -1
vendor/opam/uring/vendor/liburing/test/io-cancel.c
··· 161 161 162 162 fd = open(file, O_RDWR | O_DIRECT); 163 163 if (fd < 0) { 164 + if (errno == EINVAL) 165 + return T_EXIT_SKIP; 164 166 perror("file open"); 165 167 goto err; 166 168 } ··· 540 542 int async = (i & 4) != 0; 541 543 542 544 ret = test_io_cancel(fname, write, partial, async); 543 - if (ret) { 545 + if (ret == T_EXIT_FAIL) { 544 546 fprintf(stderr, "test_io_cancel %d %d %d failed\n", 545 547 write, partial, async); 546 548 goto err;
+39 -8
vendor/opam/uring/vendor/liburing/test/io_uring_passthrough.c
··· 18 18 #define BUFFERS (FILE_SIZE / BS) 19 19 20 20 static struct iovec *vecs; 21 + static int no_pt; 21 22 22 23 /* 23 24 * Each offset in the file has the ((test_case / 2) * FILE_SIZE) ··· 34 35 ptr = buf; 35 36 for (i = 0; i < u_in_buf; i++) { 36 37 if (off != *ptr) { 37 - fprintf(stderr, "Found %u, wanted %lu\n", *ptr, off); 38 + fprintf(stderr, "Found %u, wanted %llu\n", *ptr, 39 + (unsigned long long) off); 38 40 return 1; 39 41 } 40 42 ptr++; ··· 205 207 goto err; 206 208 } 207 209 if (cqe->res != 0) { 210 + if (!no_pt) { 211 + no_pt = 1; 212 + goto skip; 213 + } 208 214 fprintf(stderr, "cqe res %d, wanted 0\n", cqe->res); 209 215 goto err; 210 216 } ··· 234 240 } 235 241 } 236 242 243 + skip: 237 244 close(fd); 238 245 return 0; 239 246 err: ··· 258 265 if (ret == T_SETUP_SKIP) 259 266 return 0; 260 267 if (ret != T_SETUP_OK) { 268 + if (ret == -EINVAL) { 269 + no_pt = 1; 270 + return T_SETUP_SKIP; 271 + } 261 272 fprintf(stderr, "ring create failed: %d\n", ret); 262 273 return 1; 263 274 } ··· 267 278 268 279 return ret; 269 280 } 270 - 271 - extern unsigned __io_uring_flush_sq(struct io_uring *ring); 272 281 273 282 /* 274 283 * Send a passthrough command that nvme will fail during submission. ··· 282 291 struct io_uring_sqe *sqe; 283 292 struct nvme_uring_cmd *cmd; 284 293 285 - ring_flags = IORING_SETUP_IOPOLL | IORING_SETUP_SQE128; 286 - ring_flags |= IORING_SETUP_CQE32; 294 + ring_flags = IORING_SETUP_CQE32 | IORING_SETUP_SQE128; 287 295 288 296 ret = t_create_ring(1, &ring, ring_flags); 289 297 if (ret != T_SETUP_OK) { ··· 346 354 int fd, i, ret, ring_flags, open_flags; 347 355 unsigned head; 348 356 struct io_uring_cqe *cqe; 357 + struct nvme_uring_cmd *cmd; 358 + struct io_uring_sqe *sqe; 349 359 350 360 ring_flags = IORING_SETUP_IOPOLL; 351 361 ring_flags |= IORING_SETUP_SQE128; ··· 365 375 } 366 376 367 377 for (i = 0; i < BUFFERS; i++) { 368 - struct io_uring_sqe *sqe; 369 378 off_t offset = BS * (rand() % BUFFERS); 379 + __u64 slba; 380 + __u32 nlb; 370 381 371 382 sqe = io_uring_get_sqe(&ring); 372 - io_uring_prep_writev(sqe, fd, &vecs[i], 1, offset); 373 - sqe->user_data = 1; 383 + io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset); 384 + sqe->user_data = i; 385 + sqe->opcode = IORING_OP_URING_CMD; 386 + sqe->cmd_op = NVME_URING_CMD_IO; 387 + cmd = (struct nvme_uring_cmd *)sqe->cmd; 388 + memset(cmd, 0, sizeof(struct nvme_uring_cmd)); 389 + 390 + slba = offset >> lba_shift; 391 + nlb = (BS >> lba_shift) - 1; 392 + 393 + cmd->opcode = nvme_cmd_read; 394 + cmd->cdw10 = slba & 0xffffffff; 395 + cmd->cdw11 = slba >> 32; 396 + cmd->cdw12 = nlb; 397 + cmd->addr = (__u64)(uintptr_t)&vecs[i]; 398 + cmd->data_len = 1; 399 + cmd->nsid = nsid; 374 400 } 375 401 376 402 /* submit manually to avoid adding IORING_ENTER_GETEVENTS */ ··· 426 452 int nonvec = (i & 8) != 0; 427 453 428 454 ret = test_io(fname, i, read, sqthread, fixed, nonvec); 455 + if (no_pt) 456 + break; 429 457 if (ret) { 430 458 fprintf(stderr, "test_io failed %d/%d/%d/%d\n", 431 459 read, sqthread, fixed, nonvec); 432 460 goto err; 433 461 } 434 462 } 463 + 464 + if (no_pt) 465 + return T_EXIT_SKIP; 435 466 436 467 ret = test_io_uring_submit_enters(fname); 437 468 if (ret) {
+1 -1
vendor/opam/uring/vendor/liburing/test/io_uring_register.c
··· 410 410 return 1; 411 411 } 412 412 ret = 0; 413 - if (cqe->res != POLLOUT) { 413 + if (!(cqe->res & POLLOUT)) { 414 414 fprintf(stderr, "io_uring_wait_cqe: expected 0x%.8x, got 0x%.8x\n", 415 415 POLLOUT, cqe->res); 416 416 ret = 1;
+3 -80
vendor/opam/uring/vendor/liburing/test/io_uring_setup.c
··· 19 19 20 20 #include "../syscall.h" 21 21 22 - char *features_string(struct io_uring_params *p) 23 - { 24 - static char flagstr[64]; 25 - 26 - if (!p || !p->features) 27 - return "none"; 28 - 29 - if (p->features & ~IORING_FEAT_SINGLE_MMAP) { 30 - snprintf(flagstr, 64, "0x%.8x", p->features); 31 - return flagstr; 32 - } 33 - 34 - if (p->features & IORING_FEAT_SINGLE_MMAP) 35 - strncat(flagstr, "IORING_FEAT_SINGLE_MMAP", 64 - strlen(flagstr)); 36 - 37 - return flagstr; 38 - } 39 - 40 - /* 41 - * Attempt the call with the given args. Return 0 when expect matches 42 - * the return value of the system call, 1 otherwise. 43 - */ 44 - char * 45 - flags_string(struct io_uring_params *p) 46 - { 47 - static char flagstr[64]; 48 - int add_pipe = 0; 49 - 50 - memset(flagstr, 0, sizeof(flagstr)); 51 - 52 - if (!p || p->flags == 0) 53 - return "none"; 54 - 55 - /* 56 - * If unsupported flags are present, just print the bitmask. 57 - */ 58 - if (p->flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL | 59 - IORING_SETUP_SQ_AFF)) { 60 - snprintf(flagstr, 64, "0x%.8x", p->flags); 61 - return flagstr; 62 - } 63 - 64 - if (p->flags & IORING_SETUP_IOPOLL) { 65 - strncat(flagstr, "IORING_SETUP_IOPOLL", 64 - strlen(flagstr)); 66 - add_pipe = 1; 67 - } 68 - if (p->flags & IORING_SETUP_SQPOLL) { 69 - if (add_pipe) 70 - strncat(flagstr, "|", 64 - strlen(flagstr)); 71 - else 72 - add_pipe = 1; 73 - strncat(flagstr, "IORING_SETUP_SQPOLL", 64 - strlen(flagstr)); 74 - } 75 - if (p->flags & IORING_SETUP_SQ_AFF) { 76 - if (add_pipe) 77 - strncat(flagstr, "|", 64 - strlen(flagstr)); 78 - strncat(flagstr, "IORING_SETUP_SQ_AFF", 64 - strlen(flagstr)); 79 - } 80 - 81 - return flagstr; 82 - } 83 - 84 - char * 85 - dump_resv(struct io_uring_params *p) 86 - { 87 - static char resvstr[4096]; 88 - 89 - if (!p) 90 - return ""; 91 - 92 - sprintf(resvstr, "0x%.8x 0x%.8x 0x%.8x", p->resv[0], 93 - p->resv[1], p->resv[2]); 94 - 95 - return resvstr; 96 - } 97 - 98 22 /* bogus: setup returns a valid fd on success... expect can't predict the 99 23 fd we'll get, so this really only takes 1 parameter: error */ 100 - int 101 - try_io_uring_setup(unsigned entries, struct io_uring_params *p, int expect) 24 + static int try_io_uring_setup(unsigned entries, struct io_uring_params *p, 25 + int expect) 102 26 { 103 27 int ret; 104 28 ··· 123 47 return 0; 124 48 } 125 49 126 - int 127 - main(int argc, char **argv) 50 + int main(int argc, char **argv) 128 51 { 129 52 int fd; 130 53 unsigned int status = 0;
+118
vendor/opam/uring/vendor/liburing/test/iopoll-overflow.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: IOPOLL with overflow test case 4 + */ 5 + #include <errno.h> 6 + #include <stdio.h> 7 + #include <unistd.h> 8 + #include <stdlib.h> 9 + #include <string.h> 10 + #include <fcntl.h> 11 + #include <sys/types.h> 12 + #include <poll.h> 13 + #include <sys/eventfd.h> 14 + #include <sys/resource.h> 15 + #include "helpers.h" 16 + #include "liburing.h" 17 + #include "../src/syscall.h" 18 + 19 + #define FILE_SIZE (128 * 1024) 20 + #define BS 4096 21 + #define BUFFERS (FILE_SIZE / BS) 22 + 23 + static struct iovec *vecs; 24 + 25 + static int test(struct io_uring *ring, int fd) 26 + { 27 + struct io_uring_sqe *sqe; 28 + int i, j, ret; 29 + loff_t off; 30 + 31 + off = FILE_SIZE - BS; 32 + for (j = 0; j < 8; j++) { 33 + for (i = 0; i < BUFFERS; i++) { 34 + sqe = io_uring_get_sqe(ring); 35 + io_uring_prep_read(sqe, fd, vecs[i].iov_base, 36 + vecs[i].iov_len, off); 37 + if (!off) 38 + off = FILE_SIZE - BS; 39 + else 40 + off -= BS; 41 + } 42 + ret = io_uring_submit(ring); 43 + if (ret != BUFFERS) { 44 + fprintf(stderr, "submitted %d\n", ret); 45 + return T_EXIT_FAIL; 46 + } 47 + } 48 + 49 + sleep(1); 50 + 51 + ret = __sys_io_uring_enter(ring->ring_fd, 0, BUFFERS * 8, 52 + IORING_ENTER_GETEVENTS, NULL); 53 + 54 + for (i = 0; i < BUFFERS * 8; i++) { 55 + struct io_uring_cqe *cqe; 56 + 57 + ret = io_uring_wait_cqe(ring, &cqe); 58 + if (ret) { 59 + fprintf(stderr, "wait=%d\n", ret); 60 + return T_EXIT_FAIL; 61 + } 62 + io_uring_cqe_seen(ring, cqe); 63 + } 64 + 65 + return T_EXIT_PASS; 66 + } 67 + 68 + int main(int argc, char *argv[]) 69 + { 70 + struct io_uring_params p = { }; 71 + struct io_uring ring; 72 + char buf[256]; 73 + char *fname; 74 + int ret, fd; 75 + 76 + p.flags = IORING_SETUP_IOPOLL | IORING_SETUP_CQSIZE; 77 + p.cq_entries = 64; 78 + ret = t_create_ring_params(64, &ring, &p); 79 + if (ret == T_SETUP_SKIP) 80 + return 0; 81 + if (ret != T_SETUP_OK) { 82 + fprintf(stderr, "ring create failed: %d\n", ret); 83 + return 1; 84 + } 85 + 86 + if (argc > 1) { 87 + fname = argv[1]; 88 + } else { 89 + srand((unsigned)time(NULL)); 90 + snprintf(buf, sizeof(buf), ".basic-rw-%u-%u", 91 + (unsigned)rand(), (unsigned)getpid()); 92 + fname = buf; 93 + t_create_file(fname, FILE_SIZE); 94 + } 95 + 96 + fd = open(fname, O_RDONLY | O_DIRECT); 97 + if (fd < 0) { 98 + if (errno == EINVAL) { 99 + if (fname != argv[1]) 100 + unlink(fname); 101 + return T_EXIT_SKIP; 102 + } 103 + perror("open"); 104 + goto err; 105 + } 106 + 107 + vecs = t_create_buffers(BUFFERS, BS); 108 + 109 + ret = test(&ring, fd); 110 + 111 + if (fname != argv[1]) 112 + unlink(fname); 113 + return ret; 114 + err: 115 + if (fname != argv[1]) 116 + unlink(fname); 117 + return T_EXIT_FAIL; 118 + }
+90 -4
vendor/opam/uring/vendor/liburing/test/iopoll.c
··· 87 87 } 88 88 fd = open(file, open_flags); 89 89 if (fd < 0) { 90 + if (errno == EINVAL) 91 + return 0; 90 92 perror("file open"); 91 93 goto err; 92 94 } ··· 201 203 return 1; 202 204 } 203 205 204 - extern unsigned __io_uring_flush_sq(struct io_uring *ring); 206 + static void sig_alrm(int sig) 207 + { 208 + fprintf(stderr, "Ran out of time for peek test!\n"); 209 + exit(T_EXIT_FAIL); 210 + } 211 + 212 + /* 213 + * if we are polling, io_uring_cqe_peek() always needs to enter the kernel 214 + */ 215 + static int test_io_uring_cqe_peek(const char *file) 216 + { 217 + struct io_uring_cqe *cqe; 218 + struct io_uring ring; 219 + struct sigaction act; 220 + int fd, i, ret = T_EXIT_FAIL; 221 + 222 + if (no_iopoll) 223 + return 0; 224 + 225 + ret = io_uring_queue_init(64, &ring, IORING_SETUP_IOPOLL); 226 + if (ret) { 227 + fprintf(stderr, "ring create failed: %d\n", ret); 228 + return 1; 229 + } 230 + 231 + fd = open(file, O_RDONLY | O_DIRECT); 232 + if (fd < 0) { 233 + if (errno == EINVAL) { 234 + io_uring_queue_exit(&ring); 235 + return T_EXIT_SKIP; 236 + } 237 + perror("file open"); 238 + goto err; 239 + } 240 + 241 + for (i = 0; i < BUFFERS; i++) { 242 + struct io_uring_sqe *sqe; 243 + off_t offset = BS * (rand() % BUFFERS); 244 + 245 + sqe = io_uring_get_sqe(&ring); 246 + io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset); 247 + sqe->user_data = 1; 248 + } 249 + 250 + /* 251 + * Set alarm for 5 seconds, we should be done way before that 252 + */ 253 + memset(&act, 0, sizeof(act)); 254 + act.sa_handler = sig_alrm; 255 + sigaction(SIGALRM, &act, NULL); 256 + alarm(5); 257 + 258 + ret = io_uring_submit(&ring); 259 + if (ret != BUFFERS) { 260 + fprintf(stderr, "submit=%d\n", ret); 261 + goto err; 262 + } 263 + 264 + ret = T_EXIT_PASS; 265 + i = 0; 266 + do { 267 + ret = io_uring_peek_cqe(&ring, &cqe); 268 + if (ret) 269 + continue; 270 + io_uring_cqe_seen(&ring, cqe); 271 + i++; 272 + } while (i < BUFFERS); 273 + 274 + err: 275 + if (fd != -1) 276 + close(fd); 277 + io_uring_queue_exit(&ring); 278 + return ret; 279 + } 205 280 206 281 /* 207 282 * if we are polling io_uring_submit needs to always enter the ··· 227 302 open_flags = O_WRONLY | O_DIRECT; 228 303 fd = open(file, open_flags); 229 304 if (fd < 0) { 305 + if (errno == EINVAL) 306 + return T_EXIT_SKIP; 230 307 perror("file open"); 231 308 goto err; 232 309 } ··· 364 441 } 365 442 366 443 ret = test_io_uring_submit_enters(fname); 367 - if (ret) { 368 - fprintf(stderr, "test_io_uring_submit_enters failed\n"); 369 - goto err; 444 + if (ret == T_EXIT_FAIL) { 445 + fprintf(stderr, "test_io_uring_submit_enters failed\n"); 446 + goto err; 447 + } 448 + 449 + /* 450 + * Keep this last, it exits on failure 451 + */ 452 + ret = test_io_uring_cqe_peek(fname); 453 + if (ret == T_EXIT_FAIL) { 454 + fprintf(stderr, "test_io_uring_cqe_peek failed\n"); 455 + goto err; 370 456 } 371 457 372 458 if (fname != argv[1])
+7 -9
vendor/opam/uring/vendor/liburing/test/lfs-openat-write.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 2 3 - #define _LARGEFILE_SOURCE 4 - #define _FILE_OFFSET_BITS 64 5 - 6 - #include <liburing.h> 7 3 #include <string.h> 8 4 #include <stdio.h> 9 5 #include <stdlib.h> ··· 14 10 #include <sys/resource.h> 15 11 #include <unistd.h> 16 12 13 + #include "liburing.h" 17 14 #include "helpers.h" 18 15 19 16 static const int RSIZE = 2; 20 - static const int OPEN_FLAGS = O_RDWR | O_CREAT; 17 + static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE; 21 18 static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR; 22 19 23 - #define DIE(...) do {\ 24 - fprintf(stderr, __VA_ARGS__);\ 25 - abort();\ 26 - } while(0); 20 + #define DIE(...) \ 21 + do { \ 22 + fprintf(stderr, __VA_ARGS__); \ 23 + abort(); \ 24 + } while(0) 27 25 28 26 static int do_write(struct io_uring *ring, int fd, off_t offset) 29 27 {
+6 -8
vendor/opam/uring/vendor/liburing/test/lfs-openat.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 2 3 - #define _LARGEFILE_SOURCE 4 - #define _FILE_OFFSET_BITS 64 5 - 6 3 #include <string.h> 7 4 #include <stdio.h> 8 5 #include <stdlib.h> ··· 15 12 16 13 #include "liburing.h" 17 14 18 - #define DIE(...) do {\ 19 - fprintf(stderr, __VA_ARGS__);\ 20 - abort();\ 21 - } while(0); 15 + #define DIE(...) \ 16 + do { \ 17 + fprintf(stderr, __VA_ARGS__); \ 18 + abort(); \ 19 + } while(0) 22 20 23 21 static const int RSIZE = 2; 24 - static const int OPEN_FLAGS = O_RDWR | O_CREAT; 22 + static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE; 25 23 static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR; 26 24 27 25 static int open_io_uring(struct io_uring *ring, int dfd, const char *fn)
+1 -1
vendor/opam/uring/vendor/liburing/test/madvise.c
··· 182 182 } 183 183 184 184 /* too hard to reliably test, just ignore */ 185 - if (0 && bad > good) 185 + if ((0) && bad > good) 186 186 fprintf(stderr, "Suspicious timings (%u > %u)\n", bad, good); 187 187 if (fname != argv[1]) 188 188 unlink(fname);
+192
vendor/opam/uring/vendor/liburing/test/msg-ring-flags.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: test ring messaging with flags command 4 + * 5 + */ 6 + #include <errno.h> 7 + #include <stdio.h> 8 + #include <unistd.h> 9 + #include <stdlib.h> 10 + #include <string.h> 11 + #include <fcntl.h> 12 + #include <pthread.h> 13 + 14 + #include "liburing.h" 15 + #include "helpers.h" 16 + 17 + #define CUSTOM_FLAG 0x42 18 + #define USER_DATA 0x5aa5 19 + #define LEN 0x20 20 + #define ID 0x1 21 + 22 + struct data { 23 + pthread_barrier_t barrier; 24 + int fd; 25 + }; 26 + 27 + static int recv_msg(struct io_uring *ring) 28 + { 29 + struct io_uring_cqe *cqe; 30 + int ret; 31 + 32 + ret = io_uring_wait_cqe(ring, &cqe); 33 + if (ret) { 34 + fprintf(stderr, "wait cqe %d\n", ret); 35 + return T_EXIT_FAIL; 36 + } 37 + if (cqe->user_data != USER_DATA) { 38 + fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data); 39 + return T_EXIT_FAIL; 40 + } 41 + if (cqe->res != LEN) { 42 + fprintf(stderr, "len %x\n", cqe->res); 43 + return T_EXIT_FAIL; 44 + } 45 + if (cqe->flags != CUSTOM_FLAG) { 46 + fprintf(stderr, "flags %x\n", cqe->flags); 47 + return T_EXIT_FAIL; 48 + } 49 + 50 + return T_EXIT_PASS; 51 + } 52 + 53 + static int send_msg(struct io_uring *ring, int target_fd) 54 + { 55 + struct io_uring_cqe *cqe; 56 + struct io_uring_sqe *sqe; 57 + int ret; 58 + 59 + sqe = io_uring_get_sqe(ring); 60 + if (!sqe) { 61 + fprintf(stderr, "get sqe failed\n"); 62 + return T_EXIT_FAIL; 63 + } 64 + 65 + io_uring_prep_msg_ring_cqe_flags(sqe, target_fd, LEN, USER_DATA, 66 + 0, CUSTOM_FLAG); 67 + sqe->user_data = ID; 68 + 69 + ret = io_uring_submit(ring); 70 + if (ret <= 0) { 71 + if (ret == -EINVAL) 72 + return T_EXIT_SKIP; 73 + 74 + fprintf(stderr, "sqe submit failed: %d\n", ret); 75 + return T_EXIT_FAIL; 76 + } 77 + 78 + ret = io_uring_wait_cqe(ring, &cqe); 79 + if (ret < 0) { 80 + fprintf(stderr, "wait completion %d\n", ret); 81 + return T_EXIT_FAIL; 82 + } 83 + if (cqe->res != 0) { 84 + if (cqe->res == -EINVAL) 85 + return T_EXIT_SKIP; 86 + fprintf(stderr, "cqe res %d\n", cqe->res); 87 + return T_EXIT_FAIL; 88 + } 89 + if (cqe->user_data != ID) { 90 + fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data); 91 + return T_EXIT_FAIL; 92 + } 93 + 94 + io_uring_cqe_seen(ring, cqe); 95 + return T_EXIT_PASS; 96 + } 97 + 98 + static void *thread_fn(void *data) 99 + { 100 + struct data *d = data; 101 + struct io_uring ring; 102 + int ret; 103 + 104 + ret = io_uring_queue_init(2, &ring, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER); 105 + if (ret) { 106 + fprintf(stderr, "ring init failed %d\n", ret); 107 + pthread_barrier_wait(&d->barrier); 108 + return NULL; 109 + } 110 + 111 + d->fd = ring.ring_fd; 112 + pthread_barrier_wait(&d->barrier); 113 + 114 + if (recv_msg(&ring)) 115 + return (void *) 1; 116 + 117 + return NULL; 118 + } 119 + 120 + int main(int argc, char *argv[]) 121 + { 122 + struct io_uring ring, ring2; 123 + pthread_t thread; 124 + struct data d; 125 + void *ret2; 126 + int ret, i; 127 + 128 + if (argc > 1) 129 + return T_EXIT_SKIP; 130 + 131 + ret = io_uring_queue_init(2, &ring, 0); 132 + if (ret) { 133 + fprintf(stderr, "io_uring_queue_init failed for ring1: %d\n", ret); 134 + return T_EXIT_FAIL; 135 + } 136 + 137 + ret = io_uring_queue_init(2, &ring2, 0); 138 + if (ret) { 139 + fprintf(stderr, "io_uring_queue_init failed for ring2: %d\n", ret); 140 + return T_EXIT_FAIL; 141 + } 142 + 143 + ret = send_msg(&ring, ring2.ring_fd); 144 + if (ret) { 145 + if (ret != T_EXIT_SKIP) 146 + fprintf(stderr, "send_msg failed: %d\n", ret); 147 + return ret; 148 + } 149 + 150 + ret = recv_msg(&ring2); 151 + if (ret) { 152 + fprintf(stderr, "recv_msg failed: %d\n", ret); 153 + return ret; 154 + } 155 + 156 + for (i = 0; i < 8; i++) { 157 + ret = send_msg(&ring, ring2.ring_fd); 158 + if (ret) { 159 + if (ret != T_EXIT_SKIP) 160 + fprintf(stderr, "send_msg failed: %d\n", ret); 161 + return ret; 162 + } 163 + } 164 + 165 + for (i = 0; i < 8; i++) { 166 + ret = recv_msg(&ring2); 167 + if (ret) { 168 + fprintf(stderr, "recv_msg failed: %d\n", ret); 169 + return ret; 170 + } 171 + } 172 + 173 + pthread_barrier_init(&d.barrier, NULL, 2); 174 + d.fd = -1; 175 + pthread_create(&thread, NULL, thread_fn, &d); 176 + pthread_barrier_wait(&d.barrier); 177 + if (d.fd == -1) 178 + return T_EXIT_FAIL; 179 + 180 + ret = send_msg(&ring, d.fd); 181 + if (ret) { 182 + fprintf(stderr, "send msg failed: %d\n", ret); 183 + return ret; 184 + } 185 + pthread_join(thread, &ret2); 186 + if (ret2) { 187 + fprintf(stderr, "Remote test failed\n"); 188 + return T_EXIT_FAIL; 189 + } 190 + 191 + return T_EXIT_PASS; 192 + }
+159
vendor/opam/uring/vendor/liburing/test/msg-ring-overflow.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: test ring messaging command 4 + * 5 + */ 6 + #include <errno.h> 7 + #include <stdio.h> 8 + #include <unistd.h> 9 + #include <stdlib.h> 10 + #include <string.h> 11 + #include <fcntl.h> 12 + 13 + #include "liburing.h" 14 + #include "helpers.h" 15 + 16 + static int no_msg; 17 + 18 + static int test(struct io_uring *ring, unsigned dst_flags) 19 + { 20 + struct io_uring_params p = { }; 21 + struct io_uring_cqe *cqe; 22 + struct io_uring_sqe *sqe; 23 + struct io_uring dst; 24 + int ret, i, err_ret = T_EXIT_FAIL; 25 + 26 + p.flags = dst_flags | IORING_SETUP_CQSIZE; 27 + p.cq_entries = 4; 28 + ret = io_uring_queue_init_params(4, &dst, &p); 29 + if (ret) { 30 + fprintf(stderr, "Destination ring create failed %d\n", ret); 31 + return T_EXIT_FAIL; 32 + } 33 + 34 + for (i = 0; i < 8; i++) { 35 + sqe = io_uring_get_sqe(ring); 36 + if (!sqe) { 37 + fprintf(stderr, "get sqe failed\n"); 38 + goto err; 39 + } 40 + 41 + io_uring_prep_msg_ring(sqe, dst.ring_fd, 0x10, 0x1234, 0); 42 + sqe->user_data = i + 1; 43 + } 44 + 45 + ret = io_uring_submit(ring); 46 + if (ret != 8) { 47 + /* 48 + * Likely an old kernel that doesn't support the opcode, 49 + * just skip the test. 50 + */ 51 + if (ret == 1) { 52 + err_ret = T_EXIT_SKIP; 53 + no_msg = 1; 54 + goto err; 55 + } 56 + fprintf(stderr, "sqe submit failed: %d\n", ret); 57 + goto err; 58 + } 59 + 60 + for (i = 0; i < 8; i++) { 61 + ret = io_uring_wait_cqe(ring, &cqe); 62 + if (ret < 0) { 63 + fprintf(stderr, "wait completion %d\n", ret); 64 + goto err; 65 + } 66 + switch (cqe->user_data) { 67 + case 1 ... 8: 68 + if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) { 69 + no_msg = 1; 70 + goto out; 71 + } 72 + if (cqe->res != 0) { 73 + fprintf(stderr, "cqe res %d\n", cqe->res); 74 + goto err; 75 + } 76 + break; 77 + case 0x1234: 78 + if (cqe->res != 0x10) { 79 + fprintf(stderr, "invalid len %x\n", cqe->res); 80 + goto err; 81 + } 82 + break; 83 + default: 84 + fprintf(stderr, "Invalid user_data\n"); 85 + goto err; 86 + } 87 + io_uring_cqe_seen(ring, cqe); 88 + } 89 + 90 + for (i = 0; i < 8; i++) { 91 + ret = io_uring_wait_cqe(&dst, &cqe); 92 + if (ret < 0) { 93 + fprintf(stderr, "wait completion %d\n", ret); 94 + goto err; 95 + } 96 + switch (cqe->user_data) { 97 + case 0x1234: 98 + if (cqe->res != 0x10) { 99 + fprintf(stderr, "invalid len %x\n", cqe->res); 100 + goto err; 101 + } 102 + break; 103 + default: 104 + fprintf(stderr, "Invalid user_data\n"); 105 + goto err; 106 + } 107 + io_uring_cqe_seen(&dst, cqe); 108 + } 109 + 110 + out: 111 + io_uring_queue_exit(&dst); 112 + return no_msg ? T_EXIT_SKIP : T_EXIT_PASS; 113 + err: 114 + io_uring_queue_exit(&dst); 115 + return err_ret; 116 + } 117 + 118 + int main(int argc, char *argv[]) 119 + { 120 + struct io_uring src; 121 + int ret; 122 + 123 + if (argc > 1) 124 + return T_EXIT_SKIP; 125 + 126 + ret = io_uring_queue_init(8, &src, 0); 127 + if (ret) { 128 + fprintf(stderr, "ring setup failed: %d\n", ret); 129 + return T_EXIT_FAIL; 130 + } 131 + 132 + ret = test(&src, 0); 133 + if (ret && !no_msg) { 134 + fprintf(stderr, "test failed\n"); 135 + return ret; 136 + } 137 + if (no_msg) 138 + return T_EXIT_SKIP; 139 + 140 + ret = test(&src, IORING_SETUP_IOPOLL); 141 + if (ret) { 142 + fprintf(stderr, "test IOPOLL failed\n"); 143 + return ret; 144 + } 145 + 146 + ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER); 147 + if (ret) { 148 + fprintf(stderr, "test defer failed\n"); 149 + return ret; 150 + } 151 + 152 + ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_IOPOLL); 153 + if (ret) { 154 + fprintf(stderr, "test defer IOPOLL failed\n"); 155 + return ret; 156 + } 157 + 158 + return T_EXIT_PASS; 159 + }
+173 -13
vendor/opam/uring/vendor/liburing/test/msg-ring.c
··· 93 93 goto err; 94 94 } 95 95 96 + io_uring_cqe_seen(ring, cqe); 96 97 return NULL; 97 98 err: 99 + io_uring_cqe_seen(ring, cqe); 98 100 return (void *) (unsigned long) 1; 99 101 } 100 102 101 103 static int test_remote(struct io_uring *ring, struct io_uring *target) 102 104 { 105 + pthread_t thread; 106 + void *tret; 103 107 struct io_uring_cqe *cqe; 104 108 struct io_uring_sqe *sqe; 105 109 int ret; 110 + 111 + pthread_create(&thread, NULL, wait_cqe_fn, target); 106 112 107 113 sqe = io_uring_get_sqe(ring); 108 114 if (!sqe) { ··· 134 140 } 135 141 136 142 io_uring_cqe_seen(ring, cqe); 143 + pthread_join(thread, &tret); 144 + return 0; 145 + err: 146 + return 1; 147 + } 148 + 149 + static void *remote_submit_fn(void *data) 150 + { 151 + struct io_uring_sqe *sqe; 152 + struct io_uring_cqe *cqe; 153 + struct io_uring *target = data; 154 + struct io_uring ring; 155 + int ret; 156 + 157 + ret = io_uring_queue_init(8, &ring, 0); 158 + if (ret) { 159 + fprintf(stderr, "thread ring setup failed: %d\n", ret); 160 + goto err; 161 + } 162 + sqe = io_uring_get_sqe(&ring); 163 + if (!sqe) { 164 + fprintf(stderr, "get sqe failed\n"); 165 + goto err; 166 + } 167 + 168 + io_uring_prep_msg_ring(sqe, target->ring_fd, 0x20, 0x5aa5, 0); 169 + sqe->user_data = 1; 170 + 171 + ret = io_uring_submit(&ring); 172 + if (ret <= 0) { 173 + fprintf(stderr, "sqe submit failed: %d\n", ret); 174 + goto err; 175 + } 176 + 177 + ret = io_uring_wait_cqe(&ring, &cqe); 178 + if (ret < 0) { 179 + fprintf(stderr, "wait completion %d\n", ret); 180 + goto err; 181 + } 182 + if (cqe->res != 0 || cqe->user_data != 1) { 183 + fprintf(stderr, "invalid cqe\n"); 184 + goto err; 185 + } 186 + io_uring_cqe_seen(&ring, cqe); 187 + io_uring_queue_exit(&ring); 188 + return NULL; 189 + err: 190 + return (void *) (unsigned long) 1; 191 + } 192 + 193 + static int test_remote_submit(struct io_uring *target) 194 + { 195 + struct io_uring_cqe *cqe; 196 + pthread_t thread; 197 + void *tret; 198 + int ret; 199 + 200 + pthread_create(&thread, NULL, remote_submit_fn, target); 201 + 202 + ret = io_uring_wait_cqe(target, &cqe); 203 + if (ret < 0) { 204 + fprintf(stderr, "wait completion %d\n", ret); 205 + goto err; 206 + } 207 + if (cqe->res != 0x20) { 208 + fprintf(stderr, "cqe res %d\n", cqe->res); 209 + return -1; 210 + } 211 + if (cqe->user_data != 0x5aa5) { 212 + fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data); 213 + return -1; 214 + } 215 + io_uring_cqe_seen(target, cqe); 216 + pthread_join(thread, &tret); 137 217 return 0; 138 218 err: 139 219 return 1; ··· 191 271 return 1; 192 272 } 193 273 274 + static int test_disabled_ring(struct io_uring *ring, int flags) 275 + { 276 + struct io_uring_cqe *cqe; 277 + struct io_uring_sqe *sqe; 278 + struct io_uring disabled_ring; 279 + int ret; 280 + 281 + flags |= IORING_SETUP_R_DISABLED; 282 + ret = io_uring_queue_init(8, &disabled_ring, flags); 283 + if (ret) { 284 + fprintf(stderr, "ring setup failed: %d\n", ret); 285 + return 1; 286 + } 287 + 288 + sqe = io_uring_get_sqe(ring); 289 + io_uring_prep_msg_ring(sqe, disabled_ring.ring_fd, 0x10, 0x1234, 0); 290 + sqe->user_data = 1; 291 + 292 + ret = io_uring_submit(ring); 293 + if (ret != 1) { 294 + fprintf(stderr, "sqe submit failed: %d\n", ret); 295 + return 1; 296 + } 297 + 298 + ret = io_uring_wait_cqe(ring, &cqe); 299 + if (ret < 0) { 300 + fprintf(stderr, "wait completion %d\n", ret); 301 + return 1; 302 + } 303 + if (cqe->res != 0 && cqe->res != -EBADFD) { 304 + fprintf(stderr, "cqe res %d\n", cqe->res); 305 + return 1; 306 + } 307 + if (cqe->user_data != 1) { 308 + fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data); 309 + return 1; 310 + } 311 + 312 + io_uring_cqe_seen(ring, cqe); 313 + io_uring_queue_exit(&disabled_ring); 314 + return 0; 315 + } 316 + 194 317 int main(int argc, char *argv[]) 195 318 { 196 319 struct io_uring ring, ring2, pring; 197 - pthread_t thread; 198 - void *tret; 199 320 int ret, i; 200 321 201 322 if (argc > 1) ··· 220 341 ret = test_own(&ring); 221 342 if (ret) { 222 343 fprintf(stderr, "test_own failed\n"); 223 - return ret; 344 + return T_EXIT_FAIL; 224 345 } 225 - if (no_msg) { 226 - fprintf(stdout, "Skipped\n"); 346 + if (no_msg) 227 347 return T_EXIT_SKIP; 228 - } 229 348 ret = test_own(&pring); 230 349 if (ret) { 231 350 fprintf(stderr, "test_own iopoll failed\n"); 232 - return ret; 351 + return T_EXIT_FAIL; 233 352 } 234 353 235 354 ret = test_invalid(&ring, 0); 236 355 if (ret) { 237 356 fprintf(stderr, "test_invalid failed\n"); 238 - return ret; 357 + return T_EXIT_FAIL; 239 358 } 240 359 241 360 for (i = 0; i < 2; i++) { 242 361 ret = test_invalid(&ring, 1); 243 362 if (ret) { 244 363 fprintf(stderr, "test_invalid fixed failed\n"); 245 - return ret; 364 + return T_EXIT_FAIL; 246 365 } 247 366 } 248 367 249 - pthread_create(&thread, NULL, wait_cqe_fn, &ring2); 250 - 251 368 ret = test_remote(&ring, &ring2); 252 369 if (ret) { 253 370 fprintf(stderr, "test_remote failed\n"); 254 - return ret; 371 + return T_EXIT_FAIL; 255 372 } 256 373 257 - pthread_join(thread, &tret); 374 + io_uring_queue_exit(&ring); 375 + io_uring_queue_exit(&pring); 376 + 377 + if (t_probe_defer_taskrun()) { 378 + ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | 379 + IORING_SETUP_DEFER_TASKRUN); 380 + if (ret) { 381 + fprintf(stderr, "deferred ring setup failed: %d\n", ret); 382 + return T_EXIT_FAIL; 383 + } 384 + 385 + ret = test_own(&ring); 386 + if (ret) { 387 + fprintf(stderr, "test_own deferred failed\n"); 388 + return T_EXIT_FAIL; 389 + } 258 390 391 + for (i = 0; i < 2; i++) { 392 + ret = test_invalid(&ring, i); 393 + if (ret) { 394 + fprintf(stderr, "test_invalid(0) deferred failed\n"); 395 + return T_EXIT_FAIL; 396 + } 397 + } 398 + 399 + ret = test_remote_submit(&ring); 400 + if (ret) { 401 + fprintf(stderr, "test_remote_submit failed\n"); 402 + return T_EXIT_FAIL; 403 + } 404 + io_uring_queue_exit(&ring); 405 + 406 + if (test_disabled_ring(&ring2, 0)) { 407 + fprintf(stderr, "test_disabled_ring failed\n"); 408 + return T_EXIT_FAIL; 409 + } 410 + 411 + if (test_disabled_ring(&ring2, IORING_SETUP_SINGLE_ISSUER | 412 + IORING_SETUP_DEFER_TASKRUN)) { 413 + fprintf(stderr, "test_disabled_ring defer failed\n"); 414 + return T_EXIT_FAIL; 415 + } 416 + } 417 + 418 + io_uring_queue_exit(&ring2); 259 419 return T_EXIT_PASS; 260 420 }
+22 -19
vendor/opam/uring/vendor/liburing/test/multicqes_drain.c
··· 42 42 * up an entry in multi_sqes when form a cancellation sqe. 43 43 * multi_cap: limitation of number of multishot sqes 44 44 */ 45 - const unsigned sqe_flags[4] = {0, IOSQE_IO_LINK, IOSQE_IO_DRAIN, 46 - IOSQE_IO_LINK | IOSQE_IO_DRAIN}; 47 - int multi_sqes[max_entry], cnt = 0; 48 - int multi_cap = max_entry / 5; 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; 49 53 50 - int write_pipe(int pipe, char *str) 54 + static int write_pipe(int pipe, char *str) 51 55 { 52 56 int ret; 53 57 do { ··· 57 61 return ret; 58 62 } 59 63 60 - void read_pipe(int pipe) 64 + static void read_pipe(int pipe) 61 65 { 62 66 char str[4] = {0}; 63 67 int ret; ··· 67 71 perror("read"); 68 72 } 69 73 70 - int trigger_event(int p[]) 74 + static int trigger_event(struct io_uring *ring, int p[]) 71 75 { 72 76 int ret; 73 77 if ((ret = write_pipe(p[1], "foo")) != 3) { 74 78 fprintf(stderr, "bad write return %d\n", ret); 75 79 return 1; 76 80 } 81 + usleep(1000); 82 + io_uring_get_events(ring); 77 83 read_pipe(p[0]); 78 84 return 0; 79 85 } 80 86 81 - void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, unsigned sqe_flags, int arg) 87 + static void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, 88 + unsigned sqe_flags, int arg) 82 89 { 83 90 switch (op) { 84 91 case multi: ··· 98 105 sqe->flags = sqe_flags; 99 106 } 100 107 101 - __u8 generate_flags(int sqe_op) 108 + static __u8 generate_flags(int sqe_op) 102 109 { 103 110 __u8 flags = 0; 104 111 /* ··· 136 143 * - ensure number of multishot sqes doesn't exceed multi_cap 137 144 * - don't generate multishot sqes after high watermark 138 145 */ 139 - int generate_opcode(int i, int pre_flags) 146 + static int generate_opcode(int i, int pre_flags) 140 147 { 141 148 int sqe_op; 142 149 int high_watermark = max_entry - max_entry / 5; ··· 163 170 multi_sqes[cnt++] = index; 164 171 } 165 172 166 - int remove_multishot_sqe() 173 + static int remove_multishot_sqe(void) 167 174 { 168 175 int ret; 169 176 ··· 231 238 if (si[i].op != multi && si[i].op != single) 232 239 continue; 233 240 234 - if (trigger_event(pipes[i])) 241 + if (trigger_event(ring, pipes[i])) 235 242 goto err; 236 - 237 - io_uring_get_events(ring); 238 243 } 239 244 sleep(1); 240 245 i = 0; ··· 312 317 } 313 318 314 319 for (i = 0; i < 2; i++) { 315 - if (trigger_event(pipe1)) 320 + if (trigger_event(ring, pipe1)) 316 321 goto err; 317 - io_uring_get_events(ring); 318 322 } 319 - if (trigger_event(pipe2)) 320 - goto err; 321 - io_uring_get_events(ring); 323 + if (trigger_event(ring, pipe2)) 324 + goto err; 322 325 323 326 for (i = 0; i < 2; i++) { 324 327 sqe[i] = io_uring_get_sqe(ring);
+4 -3
vendor/opam/uring/vendor/liburing/test/nvme.h
··· 57 57 nvme_cmd_read = 0x02, 58 58 }; 59 59 60 - int nsid; 61 - __u32 lba_shift; 60 + static int nsid; 61 + static __u32 lba_shift; 62 62 63 63 struct nvme_lbaf { 64 64 __le16 ms; ··· 120 120 return log; 121 121 } 122 122 123 - int nvme_get_info(const char *file) 123 + __attribute__((__unused__)) 124 + static int nvme_get_info(const char *file) 124 125 { 125 126 struct nvme_id_ns ns; 126 127 int fd, err;
+95
vendor/opam/uring/vendor/liburing/test/pipe-bug.c
··· 1 + // SPDX-License-Identifier: MIT 2 + 3 + /* 4 + * Description: tests bug fixed in 5 + * "io_uring: don't gate task_work run on TIF_NOTIFY_SIGNAL" 6 + * 7 + * See: https://github.com/axboe/liburing/issues/665 8 + */ 9 + 10 + #include <stdio.h> 11 + #include <string.h> 12 + #include <unistd.h> 13 + 14 + #include "helpers.h" 15 + #include "liburing.h" 16 + 17 + #define CHECK(x) \ 18 + do { \ 19 + if (!(x)) { \ 20 + fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \ 21 + return -1; \ 22 + } \ 23 + } while (0) 24 + 25 + static int pipe_bug(void) 26 + { 27 + struct io_uring_params p; 28 + struct io_uring ring; 29 + struct io_uring_sqe *sqe; 30 + struct io_uring_cqe *cqe; 31 + char buf[1024]; 32 + int fds[2]; 33 + struct __kernel_timespec to = { 34 + .tv_sec = 1 35 + }; 36 + 37 + CHECK(pipe(fds) == 0); 38 + 39 + memset(&p, 0, sizeof(p)); 40 + CHECK(t_create_ring_params(8, &ring, &p) == 0); 41 + 42 + /* WRITE */ 43 + sqe = io_uring_get_sqe(&ring); 44 + CHECK(sqe); 45 + io_uring_prep_write(sqe, fds[1], "foobar", strlen("foobar"), 0); /* or -1 */ 46 + CHECK(io_uring_submit(&ring) == 1); 47 + CHECK(io_uring_wait_cqe(&ring, &cqe) == 0); 48 + 49 + io_uring_cqe_seen(&ring, cqe); 50 + 51 + /* CLOSE */ 52 + sqe = io_uring_get_sqe(&ring); 53 + CHECK(sqe); 54 + io_uring_prep_close(sqe, fds[1]); 55 + CHECK(io_uring_submit(&ring) == 1); 56 + CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0); 57 + io_uring_cqe_seen(&ring, cqe); 58 + 59 + /* READ */ 60 + sqe = io_uring_get_sqe(&ring); 61 + CHECK(sqe); 62 + io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */ 63 + CHECK(io_uring_submit(&ring) == 1); 64 + CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0); 65 + io_uring_cqe_seen(&ring, cqe); 66 + memset(buf, 0, sizeof(buf)); 67 + 68 + /* READ */ 69 + sqe = io_uring_get_sqe(&ring); 70 + CHECK(sqe); 71 + io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0); /* or -1 */ 72 + CHECK(io_uring_submit(&ring) == 1); 73 + CHECK(io_uring_wait_cqe_timeout(&ring, &cqe, &to) == 0); 74 + io_uring_cqe_seen(&ring, cqe); 75 + 76 + close(fds[0]); 77 + io_uring_queue_exit(&ring); 78 + 79 + return 0; 80 + } 81 + 82 + int main(int argc, char *argv[]) 83 + { 84 + int i; 85 + 86 + if (argc > 1) 87 + return T_EXIT_SKIP; 88 + 89 + for (i = 0; i < 10000; i++) { 90 + if (pipe_bug()) 91 + return T_EXIT_FAIL; 92 + } 93 + 94 + return T_EXIT_PASS; 95 + }
+3 -3
vendor/opam/uring/vendor/liburing/test/poll-link.c
··· 16 16 #include "helpers.h" 17 17 #include "liburing.h" 18 18 19 - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 20 - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 19 + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 20 + static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 21 21 22 22 static int recv_thread_ready = 0; 23 23 static int recv_thread_done = 0; ··· 71 71 return 0; 72 72 } 73 73 74 - void *recv_thread(void *arg) 74 + static void *recv_thread(void *arg) 75 75 { 76 76 struct sockaddr_in addr = { }; 77 77 struct data *data = arg;
+41 -19
vendor/opam/uring/vendor/liburing/test/poll-many.c
··· 14 14 #include <fcntl.h> 15 15 16 16 #include "liburing.h" 17 + #include "helpers.h" 17 18 18 19 #define NFILES 5000 19 20 #define BATCH 500 ··· 137 138 return 0; 138 139 } 139 140 141 + static int do_test(struct io_uring *ring) 142 + { 143 + int i; 144 + 145 + if (arm_polls(ring)) 146 + return 1; 147 + 148 + for (i = 0; i < NLOOPS; i++) { 149 + trigger_polls(); 150 + if (reap_polls(ring)) 151 + return 1; 152 + } 153 + return 0; 154 + } 155 + 140 156 int main(int argc, char *argv[]) 141 157 { 142 158 struct io_uring ring; ··· 149 165 150 166 if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) { 151 167 perror("getrlimit"); 152 - goto err_noring; 168 + return T_EXIT_FAIL; 153 169 } 154 170 155 171 if (rlim.rlim_cur < (2 * NFILES + 5)) { ··· 159 175 if (errno == EPERM) 160 176 goto err_nofail; 161 177 perror("setrlimit"); 162 - goto err_noring; 178 + return T_EXIT_FAIL; 163 179 } 164 180 } 165 181 166 182 for (i = 0; i < NFILES; i++) { 167 183 if (pipe(p[i].fd) < 0) { 168 184 perror("pipe"); 169 - goto err_noring; 185 + return T_EXIT_FAIL; 170 186 } 171 187 } 172 188 ··· 176 192 if (ret) { 177 193 if (ret == -EINVAL) { 178 194 fprintf(stdout, "No CQSIZE, trying without\n"); 179 - ret = io_uring_queue_init(RING_SIZE, &ring, 0); 195 + 196 + params.flags &= ~IORING_SETUP_CQSIZE; 197 + params.cq_entries = 0; 198 + ret = io_uring_queue_init_params(RING_SIZE, &ring, &params); 180 199 if (ret) { 181 200 fprintf(stderr, "ring setup failed: %d\n", ret); 182 - return 1; 201 + return T_EXIT_FAIL; 183 202 } 184 203 } 185 204 } 186 205 187 - if (arm_polls(&ring)) 188 - goto err; 206 + if (do_test(&ring)) { 207 + fprintf(stderr, "test (normal) failed\n"); 208 + return T_EXIT_FAIL; 209 + } 210 + io_uring_queue_exit(&ring); 189 211 190 - for (i = 0; i < NLOOPS; i++) { 191 - trigger_polls(); 192 - ret = reap_polls(&ring); 193 - if (ret) 194 - goto err; 212 + if (t_probe_defer_taskrun()) { 213 + params.flags |= IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN; 214 + ret = io_uring_queue_init_params(RING_SIZE, &ring, &params); 215 + if (ret) { 216 + fprintf(stderr, "ring DEFER setup failed: %d\n", ret); 217 + return T_EXIT_FAIL; 218 + } 219 + if (do_test(&ring)) { 220 + fprintf(stderr, "test (DEFER) failed\n"); 221 + return T_EXIT_FAIL; 222 + } 223 + io_uring_queue_exit(&ring); 195 224 } 196 - 197 - io_uring_queue_exit(&ring); 198 225 return 0; 199 - err: 200 - io_uring_queue_exit(&ring); 201 - err_noring: 202 - fprintf(stderr, "poll-many failed\n"); 203 - return 1; 204 226 err_nofail: 205 227 fprintf(stderr, "poll-many: not enough files available (and not root), " 206 228 "skipped\n");
+105 -2
vendor/opam/uring/vendor/liburing/test/poll-mshot-overflow.c
··· 12 12 #include "liburing.h" 13 13 #include "helpers.h" 14 14 15 - int check_final_cqe(struct io_uring *ring) 15 + static int check_final_cqe(struct io_uring *ring) 16 16 { 17 17 struct io_uring_cqe *cqe; 18 18 int count = 0; ··· 137 137 return ret; 138 138 } 139 139 140 + static int test_downgrade(bool support_defer) 141 + { 142 + struct io_uring_cqe cqes[128]; 143 + struct io_uring_cqe *cqe; 144 + struct io_uring_sqe *sqe; 145 + struct io_uring ring; 146 + int fds[2]; 147 + int ret, i, cqe_count, tmp = 0, more_cqe_count; 148 + 149 + if (pipe(fds) != 0) { 150 + perror("pipe"); 151 + return -1; 152 + } 153 + 154 + struct io_uring_params params = { 155 + .flags = IORING_SETUP_CQSIZE, 156 + .cq_entries = 2 157 + }; 158 + 159 + ret = io_uring_queue_init_params(2, &ring, &params); 160 + if (ret) { 161 + fprintf(stderr, "queue init: %d\n", ret); 162 + return -1; 163 + } 164 + 165 + sqe = io_uring_get_sqe(&ring); 166 + if (!sqe) { 167 + fprintf(stderr, "get sqe failed\n"); 168 + return -1; 169 + } 170 + io_uring_prep_poll_multishot(sqe, fds[0], POLLIN); 171 + io_uring_sqe_set_data64(sqe, 1); 172 + io_uring_submit(&ring); 173 + 174 + for (i = 0; i < 8; i++) { 175 + ret = write(fds[1], &tmp, sizeof(tmp)); 176 + if (ret != sizeof(tmp)) { 177 + perror("write"); 178 + return -1; 179 + } 180 + ret = read(fds[0], &tmp, sizeof(tmp)); 181 + if (ret != sizeof(tmp)) { 182 + perror("read"); 183 + return -1; 184 + } 185 + } 186 + 187 + cqe_count = 0; 188 + while (!io_uring_peek_cqe(&ring, &cqe)) { 189 + cqes[cqe_count++] = *cqe; 190 + io_uring_cqe_seen(&ring, cqe); 191 + } 192 + 193 + /* Some kernels might allow overflows to poll, 194 + * but if they didn't it should stop the MORE flag 195 + */ 196 + if (cqe_count < 3) { 197 + fprintf(stderr, "too few cqes: %d\n", cqe_count); 198 + return -1; 199 + } else if (cqe_count == 8) { 200 + more_cqe_count = cqe_count; 201 + /* downgrade only available since support_defer */ 202 + if (support_defer) { 203 + fprintf(stderr, "did not downgrade on overflow\n"); 204 + return -1; 205 + } 206 + } else { 207 + more_cqe_count = cqe_count - 1; 208 + cqe = &cqes[cqe_count - 1]; 209 + if (cqe->flags & IORING_CQE_F_MORE) { 210 + fprintf(stderr, "incorrect MORE flag %x\n", cqe->flags); 211 + return -1; 212 + } 213 + } 214 + 215 + for (i = 0; i < more_cqe_count; i++) { 216 + cqe = &cqes[i]; 217 + if (!(cqe->flags & IORING_CQE_F_MORE)) { 218 + fprintf(stderr, "missing MORE flag\n"); 219 + return -1; 220 + } 221 + if (cqe->res < 0) { 222 + fprintf(stderr, "bad res: %d\n", cqe->res); 223 + return -1; 224 + } 225 + } 226 + 227 + close(fds[0]); 228 + close(fds[1]); 229 + io_uring_queue_exit(&ring); 230 + return 0; 231 + } 232 + 140 233 int main(int argc, char *argv[]) 141 234 { 142 235 int ret; 236 + bool support_defer; 143 237 144 238 if (argc > 1) 145 239 return T_EXIT_SKIP; 146 240 241 + support_defer = t_probe_defer_taskrun(); 242 + ret = test_downgrade(support_defer); 243 + if (ret) { 244 + fprintf(stderr, "%s: test_downgrade(%d) failed\n", argv[0], support_defer); 245 + return T_EXIT_FAIL; 246 + } 247 + 147 248 ret = test(false); 249 + if (ret == T_EXIT_SKIP) 250 + return ret; 148 251 if (ret != T_EXIT_PASS) { 149 252 fprintf(stderr, "%s: test(false) failed\n", argv[0]); 150 253 return ret; 151 254 } 152 255 153 - if (t_probe_defer_taskrun()) { 256 + if (support_defer) { 154 257 ret = test(true); 155 258 if (ret != T_EXIT_PASS) { 156 259 fprintf(stderr, "%s: test(true) failed\n", argv[0]);
+276
vendor/opam/uring/vendor/liburing/test/poll-race-mshot.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: check that racing wakeups don't re-issue a poll multishot, 4 + * this can leak ring provided buffers. also test if ring 5 + * provided buffers for regular receive can leak if we hit a 6 + * poll race. 7 + */ 8 + #include <stdio.h> 9 + #include <stdlib.h> 10 + #include <unistd.h> 11 + #include <pthread.h> 12 + #include <string.h> 13 + #include <sys/socket.h> 14 + 15 + #include "liburing.h" 16 + #include "helpers.h" 17 + 18 + #define NREQS 64 19 + #define BUF_SIZE 64 20 + 21 + static int no_buf_ring; 22 + 23 + struct data { 24 + pthread_barrier_t barrier; 25 + int fd; 26 + }; 27 + 28 + static void *thread(void *data) 29 + { 30 + struct data *d = data; 31 + char buf[BUF_SIZE]; 32 + int ret, i, fd; 33 + 34 + memset(buf, 0x5a, BUF_SIZE); 35 + pthread_barrier_wait(&d->barrier); 36 + fd = d->fd; 37 + for (i = 0; i < NREQS; i++) { 38 + ret = write(fd, buf, sizeof(buf)); 39 + if (ret != BUF_SIZE) { 40 + if (ret < 0) { 41 + perror("write"); 42 + printf("bad fd %d\n", fd); 43 + } else 44 + fprintf(stderr, "wrote short %d\n", ret); 45 + } 46 + } 47 + return NULL; 48 + } 49 + 50 + static int test(struct io_uring *ring, struct data *d) 51 + { 52 + struct io_uring_buf_ring *br; 53 + struct io_uring_sqe *sqe; 54 + struct io_uring_cqe *cqe; 55 + int fd[2], ret, i; 56 + pthread_t t; 57 + void *buf, *ptr; 58 + void *ret2; 59 + 60 + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) { 61 + perror("socketpair"); 62 + return T_EXIT_FAIL; 63 + } 64 + 65 + d->fd = fd[1]; 66 + 67 + if (posix_memalign((void **) &buf, 16384, BUF_SIZE * NREQS)) 68 + return T_EXIT_FAIL; 69 + 70 + br = io_uring_setup_buf_ring(ring, NREQS, 1, 0, &ret); 71 + if (!br) { 72 + if (ret == -EINVAL) { 73 + no_buf_ring = 1; 74 + return T_EXIT_SKIP; 75 + } 76 + fprintf(stderr, "buf ring reg %d\n", ret); 77 + return T_EXIT_FAIL; 78 + } 79 + 80 + ptr = buf; 81 + for (i = 0; i < NREQS; i++) { 82 + io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1, 83 + io_uring_buf_ring_mask(NREQS), i); 84 + ptr += BUF_SIZE; 85 + } 86 + io_uring_buf_ring_advance(br, NREQS); 87 + 88 + pthread_create(&t, NULL, thread, d); 89 + 90 + for (i = 0; i < NREQS; i++) { 91 + sqe = io_uring_get_sqe(ring); 92 + io_uring_prep_recv(sqe, fd[0], NULL, 0, 0); 93 + sqe->flags |= IOSQE_BUFFER_SELECT; 94 + sqe->buf_group = 1; 95 + } 96 + 97 + pthread_barrier_wait(&d->barrier); 98 + 99 + ret = io_uring_submit(ring); 100 + if (ret != NREQS) { 101 + fprintf(stderr, "submit %d\n", ret); 102 + return T_EXIT_FAIL; 103 + } 104 + 105 + i = 0; 106 + do { 107 + ret = io_uring_wait_cqe(ring, &cqe); 108 + if (ret) { 109 + fprintf(stderr, "cqe wait %d\n", ret); 110 + return T_EXIT_FAIL; 111 + } 112 + i++; 113 + if (cqe->res != BUF_SIZE) { 114 + fprintf(stderr, "Bad cqe res %d\n", cqe->res); 115 + break; 116 + } 117 + if (cqe->flags & IORING_CQE_F_BUFFER) { 118 + int bid = cqe->flags >> 16; 119 + 120 + if (bid > NREQS) { 121 + fprintf(stderr, "Bad BID %d\n", bid); 122 + return T_EXIT_FAIL; 123 + } 124 + } else { 125 + fprintf(stderr, "No BID set!\n"); 126 + printf("ret=%d\n", cqe->res); 127 + return T_EXIT_FAIL; 128 + } 129 + io_uring_cqe_seen(ring, cqe); 130 + if (i > NREQS) { 131 + fprintf(stderr, "Got too many requests?\n"); 132 + return T_EXIT_FAIL; 133 + } 134 + } while (i < NREQS); 135 + 136 + pthread_join(t, &ret2); 137 + free(buf); 138 + io_uring_free_buf_ring(ring, br, NREQS, 1); 139 + close(fd[0]); 140 + close(fd[1]); 141 + return T_EXIT_PASS; 142 + } 143 + 144 + static int test_mshot(struct io_uring *ring, struct data *d) 145 + { 146 + struct io_uring_buf_ring *br; 147 + struct io_uring_sqe *sqe; 148 + struct io_uring_cqe *cqe; 149 + int fd[2], ret, i; 150 + pthread_t t; 151 + void *buf, *ptr; 152 + void *ret2; 153 + 154 + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) { 155 + perror("socketpair"); 156 + return T_EXIT_FAIL; 157 + } 158 + 159 + d->fd = fd[1]; 160 + 161 + if (posix_memalign((void *) &buf, 16384, BUF_SIZE * NREQS)) 162 + return T_EXIT_FAIL; 163 + 164 + br = io_uring_setup_buf_ring(ring, NREQS, 1, 0, &ret); 165 + if (!br) { 166 + fprintf(stderr, "buf ring reg %d\n", ret); 167 + return T_EXIT_FAIL; 168 + } 169 + 170 + ptr = buf; 171 + for (i = 0; i < NREQS; i++) { 172 + io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1, 173 + io_uring_buf_ring_mask(NREQS), i); 174 + ptr += BUF_SIZE; 175 + } 176 + io_uring_buf_ring_advance(br, NREQS); 177 + 178 + pthread_create(&t, NULL, thread, d); 179 + 180 + sqe = io_uring_get_sqe(ring); 181 + io_uring_prep_recv_multishot(sqe, fd[0], NULL, 0, 0); 182 + sqe->flags |= IOSQE_BUFFER_SELECT; 183 + sqe->buf_group = 1; 184 + 185 + pthread_barrier_wait(&d->barrier); 186 + 187 + ret = io_uring_submit(ring); 188 + if (ret != 1) { 189 + fprintf(stderr, "submit %d\n", ret); 190 + return T_EXIT_FAIL; 191 + } 192 + 193 + i = 0; 194 + do { 195 + ret = io_uring_wait_cqe(ring, &cqe); 196 + if (ret) { 197 + fprintf(stderr, "cqe wait %d\n", ret); 198 + return T_EXIT_FAIL; 199 + } 200 + i++; 201 + if (!(cqe->flags & IORING_CQE_F_MORE)) 202 + break; 203 + if (cqe->res != BUF_SIZE) { 204 + fprintf(stderr, "Bad cqe res %d\n", cqe->res); 205 + break; 206 + } 207 + if (cqe->flags & IORING_CQE_F_BUFFER) { 208 + int bid = cqe->flags >> 16; 209 + 210 + if (bid > NREQS) { 211 + fprintf(stderr, "Bad BID %d\n", bid); 212 + return T_EXIT_FAIL; 213 + } 214 + } else { 215 + fprintf(stderr, "No BID set!\n"); 216 + printf("ret=%d\n", cqe->res); 217 + return T_EXIT_FAIL; 218 + } 219 + io_uring_cqe_seen(ring, cqe); 220 + if (i > NREQS) { 221 + fprintf(stderr, "Got too many requests?\n"); 222 + return T_EXIT_FAIL; 223 + } 224 + } while (1); 225 + 226 + if (i != NREQS + 1) { 227 + fprintf(stderr, "Only got %d requests\n", i); 228 + return T_EXIT_FAIL; 229 + } 230 + 231 + pthread_join(t, &ret2); 232 + io_uring_free_buf_ring(ring, br, NREQS, 1); 233 + free(buf); 234 + close(fd[0]); 235 + close(fd[1]); 236 + return T_EXIT_PASS; 237 + } 238 + 239 + int main(int argc, char *argv[]) 240 + { 241 + struct io_uring ring; 242 + struct data d; 243 + int i, ret; 244 + 245 + if (argc > 1) 246 + return T_EXIT_SKIP; 247 + 248 + pthread_barrier_init(&d.barrier, NULL, 2); 249 + 250 + for (i = 0; i < 1000; i++) { 251 + io_uring_queue_init(NREQS, &ring, 0); 252 + ret = test(&ring, &d); 253 + if (ret != T_EXIT_PASS) { 254 + if (no_buf_ring) 255 + break; 256 + fprintf(stderr, "Test failed loop %d\n", i); 257 + return T_EXIT_FAIL; 258 + } 259 + io_uring_queue_exit(&ring); 260 + } 261 + 262 + if (no_buf_ring) 263 + return T_EXIT_SKIP; 264 + 265 + for (i = 0; i < 1000; i++) { 266 + io_uring_queue_init(NREQS, &ring, 0); 267 + ret = test_mshot(&ring, &d); 268 + if (ret != T_EXIT_PASS) { 269 + fprintf(stderr, "Test mshot failed loop %d\n", i); 270 + return T_EXIT_FAIL; 271 + } 272 + io_uring_queue_exit(&ring); 273 + } 274 + 275 + return T_EXIT_PASS; 276 + }
+105
vendor/opam/uring/vendor/liburing/test/poll-race.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: check that multiple receives on the same socket don't get 4 + * stalled if multiple wakers race with the socket readiness. 5 + */ 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <unistd.h> 9 + #include <pthread.h> 10 + #include <sys/socket.h> 11 + 12 + #include "liburing.h" 13 + #include "helpers.h" 14 + 15 + #define NREQS 64 16 + 17 + struct data { 18 + pthread_barrier_t barrier; 19 + int fd; 20 + }; 21 + 22 + static void *thread(void *data) 23 + { 24 + struct data *d = data; 25 + char buf[64]; 26 + int ret, i; 27 + 28 + pthread_barrier_wait(&d->barrier); 29 + for (i = 0; i < NREQS; i++) { 30 + ret = write(d->fd, buf, sizeof(buf)); 31 + if (ret != 64) 32 + fprintf(stderr, "wrote short %d\n", ret); 33 + } 34 + return NULL; 35 + } 36 + 37 + static int test(struct io_uring *ring, struct data *d) 38 + { 39 + struct io_uring_sqe *sqe; 40 + struct io_uring_cqe *cqe; 41 + int fd[2], ret, i; 42 + char buf[64]; 43 + pthread_t t; 44 + void *ret2; 45 + 46 + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) { 47 + perror("socketpair"); 48 + return T_EXIT_FAIL; 49 + } 50 + 51 + d->fd = fd[1]; 52 + 53 + pthread_create(&t, NULL, thread, d); 54 + 55 + for (i = 0; i < NREQS; i++) { 56 + sqe = io_uring_get_sqe(ring); 57 + io_uring_prep_recv(sqe, fd[0], buf, sizeof(buf), 0); 58 + } 59 + 60 + pthread_barrier_wait(&d->barrier); 61 + 62 + ret = io_uring_submit(ring); 63 + if (ret != NREQS) { 64 + fprintf(stderr, "submit %d\n", ret); 65 + return T_EXIT_FAIL; 66 + } 67 + 68 + for (i = 0; i < NREQS; i++) { 69 + ret = io_uring_wait_cqe(ring, &cqe); 70 + if (ret) { 71 + fprintf(stderr, "cqe wait %d\n", ret); 72 + return T_EXIT_FAIL; 73 + } 74 + io_uring_cqe_seen(ring, cqe); 75 + } 76 + 77 + close(fd[0]); 78 + close(fd[1]); 79 + pthread_join(t, &ret2); 80 + return T_EXIT_PASS; 81 + } 82 + 83 + int main(int argc, char *argv[]) 84 + { 85 + struct io_uring ring; 86 + struct data d; 87 + int i, ret; 88 + 89 + if (argc > 1) 90 + return T_EXIT_SKIP; 91 + 92 + pthread_barrier_init(&d.barrier, NULL, 2); 93 + 94 + io_uring_queue_init(NREQS, &ring, 0); 95 + 96 + for (i = 0; i < 1000; i++) { 97 + ret = test(&ring, &d); 98 + if (ret != T_EXIT_PASS) { 99 + fprintf(stderr, "Test failed\n"); 100 + return T_EXIT_FAIL; 101 + } 102 + } 103 + 104 + return T_EXIT_PASS; 105 + }
+244 -26
vendor/opam/uring/vendor/liburing/test/poll.c
··· 11 11 #include <signal.h> 12 12 #include <poll.h> 13 13 #include <sys/wait.h> 14 + #include <assert.h> 14 15 16 + #include "helpers.h" 15 17 #include "liburing.h" 16 18 17 - static void sig_alrm(int sig) 19 + static void do_setsockopt(int fd, int level, int optname, int val) 18 20 { 19 - fprintf(stderr, "Timed out!\n"); 20 - exit(1); 21 + if (setsockopt(fd, level, optname, &val, sizeof(val))) 22 + t_error(1, errno, "setsockopt %d.%d: %d", level, optname, val); 21 23 } 22 24 23 - int main(int argc, char *argv[]) 25 + static bool check_cq_empty(struct io_uring *ring) 26 + { 27 + struct io_uring_cqe *cqe = NULL; 28 + int ret; 29 + 30 + ret = io_uring_peek_cqe(ring, &cqe); /* nothing should be there */ 31 + return ret == -EAGAIN; 32 + } 33 + 34 + static int test_basic(void) 24 35 { 25 36 struct io_uring_cqe *cqe; 26 37 struct io_uring_sqe *sqe; ··· 28 39 int pipe1[2]; 29 40 pid_t p; 30 41 int ret; 31 - 32 - if (argc > 1) 33 - return 0; 34 42 35 43 if (pipe(pipe1) != 0) { 36 44 perror("pipe"); ··· 38 46 } 39 47 40 48 p = fork(); 41 - switch (p) { 42 - case -1: 49 + if (p == -1) { 43 50 perror("fork"); 44 51 exit(2); 45 - case 0: { 46 - struct sigaction act; 47 - 52 + } else if (p == 0) { 48 53 ret = io_uring_queue_init(1, &ring, 0); 49 54 if (ret) { 50 55 fprintf(stderr, "child: ring setup failed: %d\n", ret); 51 56 return 1; 52 57 } 53 58 54 - memset(&act, 0, sizeof(act)); 55 - act.sa_handler = sig_alrm; 56 - act.sa_flags = SA_RESTART; 57 - sigaction(SIGALRM, &act, NULL); 58 - alarm(1); 59 - 60 59 sqe = io_uring_get_sqe(&ring); 61 60 if (!sqe) { 62 61 fprintf(stderr, "get sqe failed\n"); ··· 92 91 (long) cqe->res); 93 92 return 1; 94 93 } 94 + 95 + io_uring_queue_exit(&ring); 95 96 exit(0); 97 + } 98 + 99 + do { 100 + errno = 0; 101 + ret = write(pipe1[1], "foo", 3); 102 + } while (ret == -1 && errno == EINTR); 103 + 104 + if (ret != 3) { 105 + fprintf(stderr, "parent: bad write return %d\n", ret); 106 + return 1; 107 + } 108 + close(pipe1[0]); 109 + close(pipe1[1]); 110 + return 0; 111 + } 112 + 113 + static int test_missing_events(void) 114 + { 115 + struct io_uring_cqe *cqe; 116 + struct io_uring_sqe *sqe; 117 + struct io_uring ring; 118 + int i, ret, sp[2]; 119 + char buf[2] = {}; 120 + int res_mask = 0; 121 + 122 + ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | 123 + IORING_SETUP_DEFER_TASKRUN); 124 + if (ret) { 125 + fprintf(stderr, "ring setup failed: %d\n", ret); 126 + return 1; 127 + } 128 + 129 + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) { 130 + perror("Failed to create Unix-domain socket pair\n"); 131 + return 1; 132 + } 133 + do_setsockopt(sp[0], SOL_SOCKET, SO_SNDBUF, 1); 134 + ret = send(sp[0], buf, sizeof(buf), 0); 135 + if (ret != sizeof(buf)) { 136 + perror("send failed\n"); 137 + return 1; 138 + } 139 + 140 + sqe = io_uring_get_sqe(&ring); 141 + io_uring_prep_poll_multishot(sqe, sp[0], POLLIN|POLLOUT); 142 + ret = io_uring_submit(&ring); 143 + if (ret != 1) { 144 + fprintf(stderr, "sqe submit failed: %d\n", ret); 145 + return 1; 146 + } 147 + 148 + /* trigger EPOLLIN */ 149 + ret = send(sp[1], buf, sizeof(buf), 0); 150 + if (ret != sizeof(buf)) { 151 + fprintf(stderr, "send sp[1] failed %i %i\n", ret, errno); 152 + return 1; 153 + } 154 + 155 + /* trigger EPOLLOUT */ 156 + ret = recv(sp[1], buf, sizeof(buf), 0); 157 + if (ret != sizeof(buf)) { 158 + perror("recv failed\n"); 159 + return 1; 160 + } 161 + 162 + for (i = 0; ; i++) { 163 + if (i == 0) 164 + ret = io_uring_wait_cqe(&ring, &cqe); 165 + else 166 + ret = io_uring_peek_cqe(&ring, &cqe); 167 + 168 + if (i != 0 && ret == -EAGAIN) { 169 + break; 96 170 } 97 - default: 98 - do { 99 - errno = 0; 100 - ret = write(pipe1[1], "foo", 3); 101 - } while (ret == -1 && errno == EINTR); 102 - 103 - if (ret != 3) { 104 - fprintf(stderr, "parent: bad write return %d\n", ret); 171 + if (ret) { 172 + fprintf(stderr, "wait completion %d, %i\n", ret, i); 105 173 return 1; 106 174 } 175 + res_mask |= cqe->res; 176 + io_uring_cqe_seen(&ring, cqe); 177 + } 178 + 179 + if ((res_mask & (POLLIN|POLLOUT)) != (POLLIN|POLLOUT)) { 180 + fprintf(stderr, "missing poll events %i\n", res_mask); 181 + return 1; 182 + } 183 + io_uring_queue_exit(&ring); 184 + close(sp[0]); 185 + close(sp[1]); 186 + return 0; 187 + } 188 + 189 + #define NR_SQES 2048 190 + 191 + static int test_self_poll(void) 192 + { 193 + struct io_uring_cqe *cqe; 194 + struct io_uring_sqe *sqe; 195 + struct io_uring ring; 196 + int ret, i, j; 197 + 198 + ret = io_uring_queue_init(NR_SQES, &ring, 0); 199 + if (ret) { 200 + fprintf(stderr, "ring setup failed: %d\n", ret); 201 + return T_EXIT_FAIL; 202 + } 203 + 204 + for (j = 0; j < 32; j++) { 205 + for (i = 0; i < NR_SQES; i++) { 206 + sqe = io_uring_get_sqe(&ring); 207 + io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN); 208 + } 209 + 210 + ret = io_uring_submit(&ring); 211 + assert(ret == NR_SQES); 212 + } 213 + 214 + sqe = io_uring_get_sqe(&ring); 215 + io_uring_prep_nop(sqe); 216 + ret = io_uring_submit(&ring); 217 + assert(ret == 1); 218 + 219 + ret = io_uring_wait_cqe(&ring, &cqe); 220 + io_uring_cqe_seen(&ring, cqe); 221 + 222 + io_uring_queue_exit(&ring); 223 + return T_EXIT_PASS; 224 + } 225 + 226 + static int test_disabled_ring_lazy_polling(int early_poll) 227 + { 228 + struct io_uring_cqe *cqe; 229 + struct io_uring_sqe *sqe; 230 + struct io_uring ring, ring2; 231 + unsigned head; 232 + int ret, i = 0; 233 + 234 + ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | 235 + IORING_SETUP_DEFER_TASKRUN | 236 + IORING_SETUP_R_DISABLED); 237 + if (ret) { 238 + fprintf(stderr, "ring setup failed: %d\n", ret); 239 + return 1; 240 + } 241 + ret = io_uring_queue_init(8, &ring2, 0); 242 + if (ret) { 243 + fprintf(stderr, "ring2 setup failed: %d\n", ret); 244 + return 1; 245 + } 246 + 247 + if (early_poll) { 248 + /* start polling disabled DEFER_TASKRUN ring */ 249 + sqe = io_uring_get_sqe(&ring2); 250 + io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN); 251 + ret = io_uring_submit(&ring2); 252 + assert(ret == 1); 253 + assert(check_cq_empty(&ring2)); 254 + } 255 + 256 + /* enable rings, which should also activate pollwq */ 257 + ret = io_uring_enable_rings(&ring); 258 + assert(ret >= 0); 259 + 260 + if (!early_poll) { 261 + /* start polling enabled DEFER_TASKRUN ring */ 262 + sqe = io_uring_get_sqe(&ring2); 263 + io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN); 264 + ret = io_uring_submit(&ring2); 265 + assert(ret == 1); 266 + assert(check_cq_empty(&ring2)); 267 + } 268 + 269 + sqe = io_uring_get_sqe(&ring); 270 + io_uring_prep_nop(sqe); 271 + ret = io_uring_submit(&ring); 272 + assert(ret == 1); 273 + 274 + io_uring_for_each_cqe(&ring2, head, cqe) { 275 + i++; 276 + } 277 + if (i != 1) { 278 + fprintf(stderr, "fail, polling stuck\n"); 279 + return 1; 280 + } 281 + io_uring_queue_exit(&ring); 282 + io_uring_queue_exit(&ring2); 283 + return 0; 284 + } 285 + 286 + int main(int argc, char *argv[]) 287 + { 288 + int ret; 289 + 290 + if (argc > 1) 107 291 return 0; 292 + 293 + ret = test_basic(); 294 + if (ret) { 295 + fprintf(stderr, "test_basic() failed %i\n", ret); 296 + return T_EXIT_FAIL; 108 297 } 298 + 299 + 300 + if (t_probe_defer_taskrun()) { 301 + ret = test_missing_events(); 302 + if (ret) { 303 + fprintf(stderr, "test_missing_events() failed %i\n", ret); 304 + return T_EXIT_FAIL; 305 + } 306 + 307 + ret = test_disabled_ring_lazy_polling(false); 308 + if (ret) { 309 + fprintf(stderr, "test_disabled_ring_lazy_polling(false) failed %i\n", ret); 310 + return T_EXIT_FAIL; 311 + } 312 + 313 + ret = test_disabled_ring_lazy_polling(true); 314 + if (ret) { 315 + fprintf(stderr, "test_disabled_ring_lazy_polling(true) failed %i\n", ret); 316 + return T_EXIT_FAIL; 317 + } 318 + } 319 + 320 + ret = test_self_poll(); 321 + if (ret) { 322 + fprintf(stderr, "test_self_poll failed\n"); 323 + return T_EXIT_FAIL; 324 + } 325 + 326 + return 0; 109 327 }
+5 -5
vendor/opam/uring/vendor/liburing/test/pollfree.c
··· 252 252 } 253 253 } 254 254 255 - static void setup_test() 255 + static void setup_test(void) 256 256 { 257 257 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 258 258 setpgrp(); ··· 342 342 #define __NR_io_uring_enter 426 343 343 #endif 344 344 345 - uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0}; 345 + static uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0}; 346 346 347 347 void execute_call(int call) 348 348 { ··· 403 403 if (argc > 1) 404 404 return 0; 405 405 406 - ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); 406 + ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 407 407 if (ret == MAP_FAILED) 408 408 return 0; 409 - ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul); 409 + ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 410 410 if (ret == MAP_FAILED) 411 411 return 0; 412 - ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); 412 + ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 413 413 if (ret == MAP_FAILED) 414 414 return 0; 415 415 loop();
+20 -3
vendor/opam/uring/vendor/liburing/test/read-before-exit.c
··· 14 14 #include "liburing.h" 15 15 #include "helpers.h" 16 16 17 + static int no_iopoll; 18 + 17 19 struct data { 18 20 struct io_uring *ring; 19 21 int timer_fd1; ··· 22 24 uint64_t buf2; 23 25 }; 24 26 25 - void *submit(void *data) 27 + static void *submit(void *data) 26 28 { 27 29 struct io_uring_sqe *sqe; 28 30 struct data *d = data; ··· 35 37 io_uring_prep_read(sqe, d->timer_fd2, &d->buf2, sizeof(d->buf2), 0); 36 38 37 39 ret = io_uring_submit(d->ring); 38 - if (ret != 2) 40 + if (ret != 2) { 41 + struct io_uring_cqe *cqe; 42 + 43 + /* 44 + * Kernels without submit-all-on-error behavior will 45 + * fail submitting all, check if that's the case and 46 + * don't error 47 + */ 48 + ret = io_uring_peek_cqe(d->ring, &cqe); 49 + if (!ret && cqe->res == -EOPNOTSUPP) { 50 + no_iopoll = 1; 51 + return NULL; 52 + } 39 53 return (void *) (uintptr_t) 1; 54 + } 40 55 41 56 /* Exit suddenly. */ 42 57 return NULL; ··· 95 110 for (i = 0; i < 1000; i++) { 96 111 ret = test(IORING_SETUP_IOPOLL); 97 112 if (ret) { 98 - fprintf(stderr, "Test IOPOLL failed\n"); 113 + fprintf(stderr, "Test IOPOLL failed loop %d\n", ret); 99 114 return ret; 100 115 } 116 + if (no_iopoll) 117 + break; 101 118 } 102 119 103 120 for (i = 0; i < 100; i++) {
+55
vendor/opam/uring/vendor/liburing/test/read-write.c
··· 76 76 77 77 fd = open(file, open_flags); 78 78 if (fd < 0) { 79 + if (errno == EINVAL) 80 + return 0; 79 81 perror("file open"); 80 82 goto err; 81 83 } ··· 635 637 return ret; 636 638 } 637 639 640 + static int test_rem_buf_single(int to_rem) 641 + { 642 + struct io_uring_sqe *sqe; 643 + struct io_uring_cqe *cqe; 644 + struct io_uring ring; 645 + int ret, expected; 646 + int bgid = 1; 647 + 648 + if (no_buf_select) 649 + return 0; 650 + 651 + ret = io_uring_queue_init(64, &ring, 0); 652 + if (ret) { 653 + fprintf(stderr, "ring create failed: %d\n", ret); 654 + return 1; 655 + } 656 + 657 + ret = provide_buffers_iovec(&ring, bgid); 658 + if (ret) 659 + return ret; 660 + 661 + expected = (to_rem > BUFFERS) ? BUFFERS : to_rem; 662 + 663 + sqe = io_uring_get_sqe(&ring); 664 + io_uring_prep_remove_buffers(sqe, to_rem, bgid); 665 + 666 + ret = io_uring_submit(&ring); 667 + if (ret != 1) { 668 + fprintf(stderr, "submit: %d\n", ret); 669 + return -1; 670 + } 671 + 672 + ret = io_uring_wait_cqe(&ring, &cqe); 673 + if (ret) { 674 + fprintf(stderr, "wait_cqe=%d\n", ret); 675 + return 1; 676 + } 677 + if (cqe->res != expected) { 678 + fprintf(stderr, "cqe->res=%d, expected=%d\n", cqe->res, expected); 679 + return 1; 680 + } 681 + io_uring_cqe_seen(&ring, cqe); 682 + 683 + io_uring_queue_exit(&ring); 684 + return ret; 685 + } 686 + 638 687 static int test_io_link(const char *file) 639 688 { 640 689 const int nr_links = 100; ··· 946 995 write, buffered, sqthread, fixed, nonvec); 947 996 goto err; 948 997 } 998 + } 999 + 1000 + ret = test_rem_buf_single(BUFFERS + 1); 1001 + if (ret) { 1002 + fprintf(stderr, "test_rem_buf_single(BUFFERS + 1) failed\n"); 1003 + goto err; 949 1004 } 950 1005 951 1006 if (fname != argv[1])
+21 -23
vendor/opam/uring/vendor/liburing/test/recv-msgall.c
··· 18 18 #define MAX_MSG 128 19 19 #define HOST "127.0.0.1" 20 20 static __be16 bind_port; 21 + struct recv_data { 22 + pthread_barrier_t barrier; 23 + int use_recvmsg; 24 + struct msghdr msg; 25 + }; 21 26 22 27 static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock, 23 - int use_recvmsg) 28 + struct recv_data *rd) 24 29 { 25 30 struct sockaddr_in saddr; 26 31 struct io_uring_sqe *sqe; 27 32 int sockfd, ret, val; 28 - struct msghdr msg = { }; 29 33 30 34 memset(&saddr, 0, sizeof(saddr)); 31 35 saddr.sin_family = AF_INET; ··· 47 51 bind_port = saddr.sin_port; 48 52 49 53 sqe = io_uring_get_sqe(ring); 50 - if (!use_recvmsg) { 54 + if (!rd->use_recvmsg) { 51 55 io_uring_prep_recv(sqe, sockfd, iov->iov_base, iov->iov_len, 52 56 MSG_WAITALL); 53 57 } else { 54 - msg.msg_namelen = sizeof(struct sockaddr_in); 55 - msg.msg_iov = iov; 56 - msg.msg_iovlen = 1; 57 - io_uring_prep_recvmsg(sqe, sockfd, &msg, MSG_WAITALL); 58 + struct msghdr *msg = &rd->msg; 59 + 60 + memset(msg, 0, sizeof(*msg)); 61 + msg->msg_namelen = sizeof(struct sockaddr_in); 62 + msg->msg_iov = iov; 63 + msg->msg_iovlen = 1; 64 + io_uring_prep_recvmsg(sqe, sockfd, msg, MSG_WAITALL); 58 65 } 59 66 60 67 sqe->user_data = 2; ··· 101 108 return 1; 102 109 } 103 110 104 - struct recv_data { 105 - pthread_mutex_t mutex; 106 - int use_recvmsg; 107 - }; 108 - 109 111 static void *recv_fn(void *data) 110 112 { 111 113 struct recv_data *rd = data; ··· 120 122 121 123 ret = t_create_ring_params(1, &ring, &p); 122 124 if (ret == T_SETUP_SKIP) { 123 - pthread_mutex_unlock(&rd->mutex); 125 + pthread_barrier_wait(&rd->barrier); 124 126 ret = 0; 125 127 goto err; 126 128 } else if (ret < 0) { 127 - pthread_mutex_unlock(&rd->mutex); 129 + pthread_barrier_wait(&rd->barrier); 128 130 goto err; 129 131 } 130 132 131 - ret = recv_prep(&ring, &iov, &sock, rd->use_recvmsg); 133 + ret = recv_prep(&ring, &iov, &sock, rd); 132 134 if (ret) { 133 135 fprintf(stderr, "recv_prep failed: %d\n", ret); 134 136 goto err; 135 137 } 136 - pthread_mutex_unlock(&rd->mutex); 138 + pthread_barrier_wait(&rd->barrier); 137 139 ret = do_recv(&ring); 138 140 close(sock); 139 141 io_uring_queue_exit(&ring); ··· 217 219 218 220 static int test(int use_recvmsg) 219 221 { 220 - pthread_mutexattr_t attr; 221 222 pthread_t recv_thread; 222 223 struct recv_data rd; 223 224 int ret; 224 225 void *retval; 225 226 226 - pthread_mutexattr_init(&attr); 227 - pthread_mutexattr_setpshared(&attr, 1); 228 - pthread_mutex_init(&rd.mutex, &attr); 229 - pthread_mutex_lock(&rd.mutex); 227 + pthread_barrier_init(&rd.barrier, NULL, 2); 230 228 rd.use_recvmsg = use_recvmsg; 231 229 232 230 ret = pthread_create(&recv_thread, NULL, recv_fn, &rd); 233 231 if (ret) { 234 232 fprintf(stderr, "Thread create failed: %d\n", ret); 235 - pthread_mutex_unlock(&rd.mutex); 236 233 return 1; 237 234 } 238 235 239 - pthread_mutex_lock(&rd.mutex); 236 + pthread_barrier_wait(&rd.barrier); 240 237 do_send(); 241 238 pthread_join(recv_thread, &retval); 239 + pthread_barrier_destroy(&rd.barrier); 242 240 return (intptr_t)retval; 243 241 } 244 242
+96 -3
vendor/opam/uring/vendor/liburing/test/recv-multishot.c
··· 9 9 #include <sys/types.h> 10 10 #include <sys/socket.h> 11 11 #include <pthread.h> 12 + #include <assert.h> 12 13 13 14 #include "liburing.h" 14 15 #include "helpers.h" ··· 264 265 265 266 bool const is_last = i == recv_cqes - 1; 266 267 268 + /* 269 + * Older kernels could terminate multishot early due to overflow, 270 + * but later ones will not. So discriminate based on the MORE flag. 271 + */ 272 + bool const early_last = args->early_error == ERROR_EARLY_OVERFLOW && 273 + !args->wait_each && 274 + i == N_CQE_OVERFLOW && 275 + !(cqe->flags & IORING_CQE_F_MORE); 276 + 267 277 bool const should_be_last = 268 278 (cqe->res <= 0) || 269 279 (args->stream && is_last) || 270 - (args->early_error == ERROR_EARLY_OVERFLOW && 271 - !args->wait_each && i == N_CQE_OVERFLOW); 280 + early_last; 272 281 int *this_recv; 273 282 int orig_payload_size = cqe->res; 274 283 ··· 328 337 case ERROR_EARLY_LAST: 329 338 fprintf(stderr, "bad error_early\n"); 330 339 goto cleanup; 331 - }; 340 + } 332 341 333 342 if (cqe->res <= 0 && cqe->flags & IORING_CQE_F_BUFFER) { 334 343 fprintf(stderr, "final BUFFER flag set\n"); ··· 461 470 return ret; 462 471 } 463 472 473 + static int test_enobuf(void) 474 + { 475 + struct io_uring ring; 476 + struct io_uring_sqe *sqe; 477 + struct io_uring_cqe *cqes[16]; 478 + char buffs[256]; 479 + int ret, i, fds[2]; 480 + 481 + if (t_create_ring(8, &ring, 0) != T_SETUP_OK) { 482 + fprintf(stderr, "ring create\n"); 483 + return -1; 484 + } 485 + 486 + ret = t_create_socket_pair(fds, false); 487 + if (ret) { 488 + fprintf(stderr, "t_create_socket_pair\n"); 489 + return ret; 490 + } 491 + 492 + sqe = io_uring_get_sqe(&ring); 493 + assert(sqe); 494 + /* deliberately only 2 provided buffers */ 495 + io_uring_prep_provide_buffers(sqe, &buffs[0], 1, 2, 0, 0); 496 + io_uring_sqe_set_data64(sqe, 0); 497 + 498 + sqe = io_uring_get_sqe(&ring); 499 + assert(sqe); 500 + io_uring_prep_recv_multishot(sqe, fds[0], NULL, 0, 0); 501 + io_uring_sqe_set_data64(sqe, 1); 502 + sqe->buf_group = 0; 503 + sqe->flags |= IOSQE_BUFFER_SELECT; 504 + 505 + ret = io_uring_submit(&ring); 506 + if (ret != 2) { 507 + fprintf(stderr, "bad submit %d\n", ret); 508 + return -1; 509 + } 510 + for (i = 0; i < 3; i++) { 511 + do { 512 + ret = write(fds[1], "?", 1); 513 + } while (ret == -1 && errno == EINTR); 514 + } 515 + 516 + ret = io_uring_wait_cqes(&ring, &cqes[0], 4, NULL, NULL); 517 + if (ret) { 518 + fprintf(stderr, "wait cqes\n"); 519 + return ret; 520 + } 521 + 522 + ret = io_uring_peek_batch_cqe(&ring, &cqes[0], 4); 523 + if (ret != 4) { 524 + fprintf(stderr, "peek batch cqes\n"); 525 + return -1; 526 + } 527 + 528 + /* provide buffers */ 529 + assert(cqes[0]->user_data == 0); 530 + assert(cqes[0]->res == 0); 531 + 532 + /* valid recv */ 533 + assert(cqes[1]->user_data == 1); 534 + assert(cqes[2]->user_data == 1); 535 + assert(cqes[1]->res == 1); 536 + assert(cqes[2]->res == 1); 537 + assert(cqes[1]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE)); 538 + assert(cqes[2]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE)); 539 + 540 + /* missing buffer */ 541 + assert(cqes[3]->user_data == 1); 542 + assert(cqes[3]->res == -ENOBUFS); 543 + assert(!(cqes[3]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE))); 544 + 545 + close(fds[0]); 546 + close(fds[1]); 547 + io_uring_queue_exit(&ring); 548 + return 0; 549 + } 550 + 464 551 int main(int argc, char *argv[]) 465 552 { 466 553 int ret; ··· 499 586 return T_EXIT_FAIL; 500 587 } 501 588 } 589 + } 590 + 591 + ret = test_enobuf(); 592 + if (ret) { 593 + fprintf(stderr, "test_enobuf() failed: %d\n", ret); 594 + return T_EXIT_FAIL; 502 595 } 503 596 504 597 return T_EXIT_PASS;
+56
vendor/opam/uring/vendor/liburing/test/reg-hint.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Test alloc hint sanity after unregistering the file table 4 + */ 5 + #include <stdio.h> 6 + #include <unistd.h> 7 + #include <sys/socket.h> 8 + 9 + #include "liburing.h" 10 + #include "helpers.h" 11 + 12 + int main(int argc, char *argv[]) 13 + { 14 + struct io_uring_sqe *sqe; 15 + struct io_uring_cqe *cqe; 16 + struct io_uring ring; 17 + int ret; 18 + 19 + if (argc > 1) 20 + return T_EXIT_SKIP; 21 + 22 + io_uring_queue_init(1, &ring, 0); 23 + 24 + ret = io_uring_register_files_sparse(&ring, 16); 25 + if (ret) { 26 + if (ret == -EINVAL) 27 + return T_EXIT_SKIP; 28 + 29 + fprintf(stderr, "Failed to register file table: %d\n", ret); 30 + return T_EXIT_FAIL; 31 + } 32 + io_uring_unregister_files(&ring); 33 + 34 + sqe = io_uring_get_sqe(&ring); 35 + io_uring_prep_socket_direct_alloc(sqe, AF_UNIX, SOCK_DGRAM, 0, 0); 36 + 37 + ret = io_uring_submit(&ring); 38 + if (ret != 1) { 39 + fprintf(stderr, "submit %d\n", ret); 40 + return T_EXIT_FAIL; 41 + } 42 + 43 + ret = io_uring_wait_cqe(&ring, &cqe); 44 + if (ret) { 45 + fprintf(stderr, "wait cqe: %d\n", ret); 46 + return T_EXIT_FAIL; 47 + } 48 + 49 + if (cqe->res != -ENFILE) { 50 + fprintf(stderr, "Bad CQE res: %d\n", cqe->res); 51 + return T_EXIT_FAIL; 52 + } 53 + 54 + io_uring_cqe_seen(&ring, cqe); 55 + return T_EXIT_PASS; 56 + }
+90
vendor/opam/uring/vendor/liburing/test/reg-reg-ring.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Test io_uring_register with a registered ring (IORING_REGISTER_USE_REGISTERED_RING) 4 + * 5 + */ 6 + #include <stdio.h> 7 + 8 + #include "helpers.h" 9 + 10 + int main(int argc, char *argv[]) 11 + { 12 + struct io_uring ring; 13 + unsigned values[2]; 14 + int ret; 15 + 16 + if (argc > 1) 17 + return T_EXIT_SKIP; 18 + 19 + ret = io_uring_queue_init(8, &ring, 0); 20 + if (ret) { 21 + fprintf(stderr, "ring setup failed\n"); 22 + return T_EXIT_FAIL; 23 + } 24 + 25 + if (!(ring.features & IORING_FEAT_REG_REG_RING)) { 26 + fprintf(stderr, "IORING_FEAT_REG_REG_RING not available in kernel\n"); 27 + io_uring_queue_exit(&ring); 28 + return T_EXIT_SKIP; 29 + } 30 + 31 + ret = io_uring_close_ring_fd(&ring); 32 + if (ret != -EINVAL) { 33 + fprintf(stderr, "closing ring fd should EINVAL before register\n"); 34 + goto err; 35 + } 36 + 37 + ret = io_uring_unregister_ring_fd(&ring); 38 + if (ret != -EINVAL) { 39 + fprintf(stderr, "unregistering not-registered ring fd should fail\n"); 40 + goto err; 41 + } 42 + 43 + ret = io_uring_register_ring_fd(&ring); 44 + if (ret != 1) { 45 + fprintf(stderr, "registering ring fd failed\n"); 46 + goto err; 47 + } 48 + 49 + ret = io_uring_register_ring_fd(&ring); 50 + if (ret != -EEXIST) { 51 + fprintf(stderr, "registering already-registered ring fd should fail\n"); 52 + goto err; 53 + } 54 + 55 + /* Test a simple io_uring_register operation expected to work. 56 + * io_uring_register_iowq_max_workers is arbitrary. 57 + */ 58 + values[0] = values[1] = 0; 59 + ret = io_uring_register_iowq_max_workers(&ring, values); 60 + if (ret || (values[0] == 0 && values[1] == 0)) { 61 + fprintf(stderr, "io_uring_register operation failed before closing ring fd\n"); 62 + goto err; 63 + } 64 + 65 + ret = io_uring_close_ring_fd(&ring); 66 + if (ret != 1) { 67 + fprintf(stderr, "closing ring fd failed\n"); 68 + goto err; 69 + } 70 + 71 + values[0] = values[1] = 0; 72 + ret = io_uring_register_iowq_max_workers(&ring, values); 73 + if (ret || (values[0] == 0 && values[1] == 0)) { 74 + fprintf(stderr, "io_uring_register operation failed after closing ring fd\n"); 75 + goto err; 76 + } 77 + 78 + ret = io_uring_close_ring_fd(&ring); 79 + if (ret != -EBADF) { 80 + fprintf(stderr, "closing already-closed ring fd should fail\n"); 81 + goto err; 82 + } 83 + 84 + io_uring_queue_exit(&ring); 85 + return T_EXIT_PASS; 86 + 87 + err: 88 + io_uring_queue_exit(&ring); 89 + return T_EXIT_FAIL; 90 + }
+91
vendor/opam/uring/vendor/liburing/test/regbuf-merge.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + // autogenerated by syzkaller (https://github.com/google/syzkaller) 3 + 4 + #include <endian.h> 5 + #include <stdint.h> 6 + #include <stdio.h> 7 + #include <stdlib.h> 8 + #include <string.h> 9 + #include <sys/mman.h> 10 + #include <sys/syscall.h> 11 + #include <sys/types.h> 12 + #include <unistd.h> 13 + 14 + #include "helpers.h" 15 + 16 + #ifndef __NR_io_uring_register 17 + #define __NR_io_uring_register 427 18 + #endif 19 + #ifndef __NR_io_uring_setup 20 + #define __NR_io_uring_setup 425 21 + #endif 22 + 23 + #define SIZEOF_IO_URING_SQE 64 24 + #define SIZEOF_IO_URING_CQE 16 25 + #define SQ_HEAD_OFFSET 0 26 + #define SQ_TAIL_OFFSET 64 27 + #define SQ_RING_MASK_OFFSET 256 28 + #define SQ_RING_ENTRIES_OFFSET 264 29 + #define SQ_FLAGS_OFFSET 276 30 + #define SQ_DROPPED_OFFSET 272 31 + #define CQ_HEAD_OFFSET 128 32 + #define CQ_TAIL_OFFSET 192 33 + #define CQ_RING_MASK_OFFSET 260 34 + #define CQ_RING_ENTRIES_OFFSET 268 35 + #define CQ_RING_OVERFLOW_OFFSET 284 36 + #define CQ_FLAGS_OFFSET 280 37 + #define CQ_CQES_OFFSET 320 38 + 39 + static long syz_io_uring_setup(volatile long a0, volatile long a1, volatile long a2, volatile long a3, volatile long a4, volatile long a5) 40 + { 41 + uint32_t entries = (uint32_t)a0; 42 + struct io_uring_params* setup_params = (struct io_uring_params*)a1; 43 + void* vma1 = (void*)a2; 44 + void* vma2 = (void*)a3; 45 + void** ring_ptr_out = (void**)a4; 46 + void** sqes_ptr_out = (void**)a5; 47 + uint32_t fd_io_uring = syscall(__NR_io_uring_setup, entries, setup_params); 48 + uint32_t sq_ring_sz = setup_params->sq_off.array + setup_params->sq_entries * sizeof(uint32_t); 49 + uint32_t cq_ring_sz = setup_params->cq_off.cqes + setup_params->cq_entries * SIZEOF_IO_URING_CQE; 50 + uint32_t ring_sz = sq_ring_sz > cq_ring_sz ? sq_ring_sz : cq_ring_sz; 51 + *ring_ptr_out = mmap(vma1, ring_sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQ_RING); 52 + uint32_t sqes_sz = setup_params->sq_entries * SIZEOF_IO_URING_SQE; 53 + *sqes_ptr_out = mmap(vma2, sqes_sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQES); 54 + return fd_io_uring; 55 + } 56 + 57 + static uint64_t r[1] = {0xffffffffffffffff}; 58 + 59 + int main(int argc, char *argv[]) 60 + { 61 + intptr_t res = 0; 62 + 63 + if (argc > 1) 64 + return T_EXIT_SKIP; 65 + 66 + mmap((void *) 0x1ffff000ul, 0x1000ul, PROT_NONE, 67 + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0ul); 68 + mmap((void *) 0x20000000ul, 0x1000000ul, PROT_READ|PROT_WRITE|PROT_EXEC, 69 + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0ul); 70 + mmap((void *) 0x21000000ul, 0x1000ul, PROT_NONE, 71 + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0ul); 72 + 73 + *(uint32_t*)0x20000684 = 0; 74 + *(uint32_t*)0x20000688 = 0; 75 + *(uint32_t*)0x2000068c = 0; 76 + *(uint32_t*)0x20000690 = 0; 77 + *(uint32_t*)0x20000698 = -1; 78 + memset((void*)0x2000069c, 0, 12); 79 + 80 + res = syz_io_uring_setup(0x2fd6, 0x20000680, 0x20ffd000, 0x20ffc000, 81 + 0x20000700, 0x20000740); 82 + if (res != -1) 83 + r[0] = res; 84 + 85 + *(uint64_t*)0x20002840 = 0; 86 + *(uint64_t*)0x20002848 = 0; 87 + *(uint64_t*)0x20002850 = 0x20000840; 88 + *(uint64_t*)0x20002858 = 0x1000; 89 + syscall(__NR_io_uring_register, r[0], 0ul, 0x20002840ul, 2ul); 90 + return T_EXIT_PASS; 91 + }
+1 -1
vendor/opam/uring/vendor/liburing/test/rename.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 2 /* 3 - * Description: run various nop tests 3 + * Description: run various rename tests 4 4 * 5 5 */ 6 6 #include <errno.h>
-1
vendor/opam/uring/vendor/liburing/test/ring-leak.c
··· 241 241 update); 242 242 return 1; 243 243 } 244 - break; 245 244 } 246 245 247 246 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) {
+1 -1
vendor/opam/uring/vendor/liburing/test/ring-leak2.c
··· 46 46 47 47 static int client_eventfd = -1; 48 48 49 - int setup_io_uring(struct io_uring *ring) 49 + static int setup_io_uring(struct io_uring *ring) 50 50 { 51 51 struct io_uring_params p = { }; 52 52 int ret;
+10 -14
vendor/opam/uring/vendor/liburing/test/ringbuf-read.c
··· 37 37 38 38 static int test(const char *filename, int dio, int async) 39 39 { 40 - struct io_uring_buf_reg reg = { }; 41 40 struct io_uring_sqe *sqe; 42 41 struct io_uring_cqe *cqe; 43 42 struct io_uring ring; ··· 52 51 return 1; 53 52 } 54 53 55 - if (dio) 54 + if (dio) { 56 55 fd = open(filename, O_DIRECT | O_RDONLY); 57 - else 56 + if (fd < 0 && errno == EINVAL) 57 + return T_EXIT_SKIP; 58 + } else { 58 59 fd = open(filename, O_RDONLY); 60 + } 59 61 if (fd < 0) { 60 62 perror("open"); 61 63 return 1; ··· 65 67 66 68 if (posix_memalign((void **) &buf, 4096, FSIZE)) 67 69 return 1; 68 - if (posix_memalign((void **) &br, 4096, 4096)) 69 - return 1; 70 70 71 - reg.ring_addr = (unsigned long) br; 72 - reg.ring_entries = NR_BUFS; 73 - reg.bgid = 1; 74 - 75 - ret = io_uring_register_buf_ring(&ring, &reg, 0); 76 - if (ret) { 71 + br = io_uring_setup_buf_ring(&ring, NR_BUFS, 1, 0, &ret); 72 + if (!br) { 77 73 if (ret == -EINVAL) { 78 74 no_buf_ring = 1; 79 75 return 0; ··· 163 159 close(fd); 164 160 165 161 ret = test(fname, 1, 0); 166 - if (ret) { 162 + if (ret == T_EXIT_FAIL) { 167 163 fprintf(stderr, "dio test failed\n"); 168 164 goto err; 169 165 } ··· 177 173 } 178 174 179 175 ret = test(fname, 1, 1); 180 - if (ret) { 176 + if (ret == T_EXIT_FAIL) { 181 177 fprintf(stderr, "dio async test failed\n"); 182 178 goto err; 183 179 } 184 180 185 181 ret = test(fname, 0, 1); 186 - if (ret) { 182 + if (ret == T_EXIT_FAIL) { 187 183 fprintf(stderr, "buffered async test failed\n"); 188 184 goto err; 189 185 }
+273 -103
vendor/opam/uring/vendor/liburing/test/send-zerocopy.c
··· 4 4 #include <stdint.h> 5 5 #include <assert.h> 6 6 #include <errno.h> 7 - #include <error.h> 8 7 #include <limits.h> 9 8 #include <fcntl.h> 10 9 #include <unistd.h> ··· 12 11 #include <string.h> 13 12 14 13 #include <arpa/inet.h> 15 - #include <linux/errqueue.h> 16 14 #include <linux/if_packet.h> 17 15 #include <linux/ipv6.h> 18 16 #include <linux/socket.h> ··· 34 32 #include <sys/time.h> 35 33 #include <sys/types.h> 36 34 #include <sys/wait.h> 35 + #include <sys/mman.h> 36 + #include <linux/mman.h> 37 37 38 38 #include "liburing.h" 39 39 #include "helpers.h" 40 40 41 41 #define MAX_MSG 128 42 42 43 - #define PORT 10200 44 43 #define HOST "127.0.0.1" 45 44 #define HOSTV6 "::1" 46 45 46 + #define MAX_IOV 32 47 47 #define CORK_REQS 5 48 48 #define RX_TAG 10000 49 49 #define BUFFER_OFFSET 41 ··· 57 57 BUF_T_SMALL, 58 58 BUF_T_NONALIGNED, 59 59 BUF_T_LARGE, 60 + BUF_T_HUGETLB, 61 + 62 + __BUF_NR, 60 63 }; 61 64 65 + /* 32MB, should be enough to trigger a short send */ 66 + #define LARGE_BUF_SIZE (1U << 25) 67 + 68 + static size_t page_sz; 62 69 static char *tx_buffer, *rx_buffer; 63 - static struct iovec buffers_iov[4]; 70 + static struct iovec buffers_iov[__BUF_NR]; 64 71 static bool has_sendmsg; 65 72 66 73 static bool check_cq_empty(struct io_uring *ring) ··· 115 122 return T_EXIT_PASS; 116 123 } 117 124 118 - static int test_send_faults(struct io_uring *ring, int sock_tx, int sock_rx) 125 + static int test_send_faults(int sock_tx, int sock_rx) 119 126 { 120 127 struct io_uring_sqe *sqe; 121 128 struct io_uring_cqe *cqe; 122 129 int msg_flags = 0; 123 130 unsigned zc_flags = 0; 124 131 int payload_size = 100; 125 - int ret, i, nr_cqes = 2; 132 + int ret, i, nr_cqes, nr_reqs = 3; 133 + struct io_uring ring; 134 + 135 + ret = io_uring_queue_init(32, &ring, IORING_SETUP_SUBMIT_ALL); 136 + if (ret) { 137 + fprintf(stderr, "queue init failed: %d\n", ret); 138 + return -1; 139 + } 126 140 127 - sqe = io_uring_get_sqe(ring); 141 + /* invalid buffer */ 142 + sqe = io_uring_get_sqe(&ring); 128 143 io_uring_prep_send_zc(sqe, sock_tx, (void *)1UL, payload_size, 129 144 msg_flags, zc_flags); 130 145 sqe->user_data = 1; 131 146 132 - sqe = io_uring_get_sqe(ring); 147 + /* invalid address */ 148 + sqe = io_uring_get_sqe(&ring); 133 149 io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, payload_size, 134 150 msg_flags, zc_flags); 135 - sqe->user_data = 2; 136 151 io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)1UL, 137 152 sizeof(struct sockaddr_in6)); 153 + sqe->user_data = 2; 138 154 139 - ret = io_uring_submit(ring); 140 - assert(ret == 2); 155 + /* invalid send/recv flags */ 156 + sqe = io_uring_get_sqe(&ring); 157 + io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, payload_size, 158 + msg_flags, ~0U); 159 + sqe->user_data = 3; 160 + 161 + ret = io_uring_submit(&ring); 162 + assert(ret == nr_reqs); 141 163 164 + nr_cqes = nr_reqs; 142 165 for (i = 0; i < nr_cqes; i++) { 143 - ret = io_uring_wait_cqe(ring, &cqe); 166 + ret = io_uring_wait_cqe(&ring, &cqe); 144 167 assert(!ret); 145 - assert(cqe->user_data <= 2); 168 + assert(cqe->user_data <= nr_reqs); 146 169 147 170 if (!(cqe->flags & IORING_CQE_F_NOTIF)) { 148 - assert(cqe->res == -EFAULT); 171 + int expected = (cqe->user_data == 3) ? -EINVAL : -EFAULT; 172 + 173 + if (cqe->res != expected) { 174 + fprintf(stderr, "invalid cqe res %i vs expected %i, " 175 + "user_data %i\n", 176 + cqe->res, expected, (int)cqe->user_data); 177 + return -1; 178 + } 149 179 if (cqe->flags & IORING_CQE_F_MORE) 150 180 nr_cqes++; 181 + } else { 182 + if (cqe->res != 0 || cqe->flags != IORING_CQE_F_NOTIF) { 183 + fprintf(stderr, "invalid notif cqe %i %i\n", 184 + cqe->res, cqe->flags); 185 + return -1; 186 + } 151 187 } 152 - io_uring_cqe_seen(ring, cqe); 188 + io_uring_cqe_seen(&ring, cqe); 153 189 } 154 - assert(check_cq_empty(ring)); 190 + assert(check_cq_empty(&ring)); 155 191 return T_EXIT_PASS; 156 192 } 157 193 ··· 160 196 bool ipv6, bool client_connect, 161 197 bool msg_zc, bool tcp) 162 198 { 163 - int family, addr_size; 164 - int ret, val; 165 - int listen_sock = -1; 166 - int sock; 199 + socklen_t addr_size; 200 + int family, sock, listen_sock = -1; 201 + int ret; 167 202 168 203 memset(addr, 0, sizeof(*addr)); 169 204 if (ipv6) { ··· 171 206 172 207 family = AF_INET6; 173 208 saddr->sin6_family = family; 174 - saddr->sin6_port = htons(PORT); 209 + saddr->sin6_port = htons(0); 175 210 addr_size = sizeof(*saddr); 176 211 } else { 177 212 struct sockaddr_in *saddr = (struct sockaddr_in *)addr; 178 213 179 214 family = AF_INET; 180 215 saddr->sin_family = family; 181 - saddr->sin_port = htons(PORT); 216 + saddr->sin_port = htons(0); 182 217 saddr->sin_addr.s_addr = htonl(INADDR_ANY); 183 218 addr_size = sizeof(*saddr); 184 219 } ··· 193 228 perror("socket"); 194 229 return 1; 195 230 } 196 - val = 1; 197 - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 198 - val = 1; 199 - setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); 200 231 201 232 ret = bind(sock, (struct sockaddr *)addr, addr_size); 202 233 if (ret < 0) { 203 234 perror("bind"); 204 235 return 1; 205 236 } 237 + 238 + ret = getsockname(sock, (struct sockaddr *)addr, &addr_size); 239 + if (ret < 0) { 240 + fprintf(stderr, "getsockname failed %i\n", errno); 241 + return 1; 242 + } 243 + 206 244 if (tcp) { 207 245 ret = listen(sock, 128); 208 246 assert(ret != -1); ··· 237 275 } 238 276 } 239 277 if (msg_zc) { 240 - val = 1; 278 + #ifdef SO_ZEROCOPY 279 + int val = 1; 280 + 241 281 if (setsockopt(*sock_client, SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val))) { 242 282 perror("setsockopt zc"); 243 283 return 1; 244 284 } 285 + #else 286 + fprintf(stderr, "no SO_ZEROCOPY\n"); 287 + return 1; 288 + #endif 245 289 } 246 290 if (tcp) { 247 291 *sock_server = accept(listen_sock, NULL, NULL); ··· 254 298 return 0; 255 299 } 256 300 301 + struct send_conf { 302 + bool fixed_buf; 303 + bool mix_register; 304 + bool cork; 305 + bool force_async; 306 + bool use_sendmsg; 307 + bool tcp; 308 + bool zc; 309 + bool iovec; 310 + bool long_iovec; 311 + bool poll_first; 312 + int buf_index; 313 + struct sockaddr_storage *addr; 314 + }; 315 + 257 316 static int do_test_inet_send(struct io_uring *ring, int sock_client, int sock_server, 258 - bool fixed_buf, struct sockaddr_storage *addr, 259 - bool cork, bool mix_register, 260 - int buf_idx, bool force_async, bool use_sendmsg) 317 + struct send_conf *conf) 261 318 { 262 - struct iovec iov[CORK_REQS]; 319 + struct iovec iov[MAX_IOV]; 263 320 struct msghdr msghdr[CORK_REQS]; 264 321 const unsigned zc_flags = 0; 265 322 struct io_uring_sqe *sqe; 266 323 struct io_uring_cqe *cqe; 267 - int nr_reqs = cork ? CORK_REQS : 1; 324 + int nr_reqs = conf->cork ? CORK_REQS : 1; 268 325 int i, ret, nr_cqes, addr_len = 0; 269 - size_t send_size = buffers_iov[buf_idx].iov_len; 326 + size_t send_size = buffers_iov[conf->buf_index].iov_len; 270 327 size_t chunk_size = send_size / nr_reqs; 271 328 size_t chunk_size_last = send_size - chunk_size * (nr_reqs - 1); 272 - char *buf = buffers_iov[buf_idx].iov_base; 329 + char *buf = buffers_iov[conf->buf_index].iov_base; 273 330 274 - if (addr) { 275 - sa_family_t fam = ((struct sockaddr_in *)addr)->sin_family; 331 + assert(MAX_IOV >= CORK_REQS); 332 + 333 + if (conf->addr) { 334 + sa_family_t fam = ((struct sockaddr_in *)conf->addr)->sin_family; 276 335 277 336 addr_len = (fam == AF_INET) ? sizeof(struct sockaddr_in) : 278 337 sizeof(struct sockaddr_in6); ··· 281 340 memset(rx_buffer, 0, send_size); 282 341 283 342 for (i = 0; i < nr_reqs; i++) { 284 - bool real_fixed_buf = fixed_buf; 343 + bool real_fixed_buf = conf->fixed_buf; 285 344 size_t cur_size = chunk_size; 286 345 int msg_flags = MSG_WAITALL; 287 346 288 - if (mix_register) 347 + if (conf->mix_register) 289 348 real_fixed_buf = rand() & 1; 290 349 291 - if (cork && i != nr_reqs - 1) 350 + if (i != nr_reqs - 1) 292 351 msg_flags |= MSG_MORE; 293 - if (i == nr_reqs - 1) 352 + else 294 353 cur_size = chunk_size_last; 295 354 296 355 sqe = io_uring_get_sqe(ring); 297 356 298 - if (!use_sendmsg) { 299 - io_uring_prep_send_zc(sqe, sock_client, buf + i * chunk_size, 300 - cur_size, msg_flags, zc_flags); 357 + if (!conf->use_sendmsg) { 358 + if (conf->zc) { 359 + io_uring_prep_send_zc(sqe, sock_client, buf + i * chunk_size, 360 + cur_size, msg_flags, zc_flags); 361 + } else { 362 + io_uring_prep_send(sqe, sock_client, buf + i * chunk_size, 363 + cur_size, msg_flags); 364 + } 365 + 301 366 if (real_fixed_buf) { 302 367 sqe->ioprio |= IORING_RECVSEND_FIXED_BUF; 303 - sqe->buf_index = buf_idx; 368 + sqe->buf_index = conf->buf_index; 304 369 } 305 - if (addr) 306 - io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)addr, 370 + if (conf->addr) 371 + io_uring_prep_send_set_addr(sqe, (const struct sockaddr *)conf->addr, 307 372 addr_len); 308 373 } else { 309 - io_uring_prep_sendmsg_zc(sqe, sock_client, &msghdr[i], msg_flags); 374 + struct iovec *io; 375 + int iov_len; 376 + 377 + if (conf->zc) 378 + io_uring_prep_sendmsg_zc(sqe, sock_client, &msghdr[i], msg_flags); 379 + else 380 + io_uring_prep_sendmsg(sqe, sock_client, &msghdr[i], msg_flags); 381 + 382 + if (!conf->iovec) { 383 + io = &iov[i]; 384 + iov_len = 1; 385 + iov[i].iov_len = cur_size; 386 + iov[i].iov_base = buf + i * chunk_size; 387 + } else { 388 + char *it = buf; 389 + int j; 390 + 391 + assert(nr_reqs == 1); 392 + iov_len = conf->long_iovec ? MAX_IOV : 4; 393 + io = iov; 394 + 395 + for (j = 0; j < iov_len; j++) 396 + io[j].iov_len = 1; 397 + /* first want to be easily advanced */ 398 + io[0].iov_base = it; 399 + it += io[0].iov_len; 400 + /* this should cause retry */ 401 + io[1].iov_len = chunk_size - iov_len + 1; 402 + io[1].iov_base = it; 403 + it += io[1].iov_len; 404 + /* fill the rest */ 405 + for (j = 2; j < iov_len; j++) { 406 + io[j].iov_base = it; 407 + it += io[j].iov_len; 408 + } 409 + } 310 410 311 411 memset(&msghdr[i], 0, sizeof(msghdr[i])); 312 - iov[i].iov_len = cur_size; 313 - iov[i].iov_base = buf + i * chunk_size; 314 - msghdr[i].msg_iov = &iov[i]; 315 - msghdr[i].msg_iovlen = 1; 316 - if (addr) { 317 - msghdr[i].msg_name = addr; 412 + msghdr[i].msg_iov = io; 413 + msghdr[i].msg_iovlen = iov_len; 414 + if (conf->addr) { 415 + msghdr[i].msg_name = conf->addr; 318 416 msghdr[i].msg_namelen = addr_len; 319 417 } 320 418 } 321 419 sqe->user_data = i; 322 - if (force_async) 420 + if (conf->force_async) 323 421 sqe->flags |= IOSQE_ASYNC; 422 + if (conf->poll_first) 423 + sqe->ioprio |= IORING_RECVSEND_POLL_FIRST; 324 424 if (i != nr_reqs - 1) 325 425 sqe->flags |= IOSQE_IO_LINK; 326 426 } ··· 335 435 return 1; 336 436 } 337 437 338 - nr_cqes = 2 * nr_reqs + 1; 438 + nr_cqes = nr_reqs + 1; 339 439 for (i = 0; i < nr_cqes; i++) { 340 440 int expected = chunk_size; 341 441 ··· 346 446 } 347 447 if (cqe->user_data == RX_TAG) { 348 448 if (cqe->res != send_size) { 349 - fprintf(stderr, "rx failed %i\n", cqe->res); 449 + fprintf(stderr, "rx failed res: %i, expected %i\n", 450 + cqe->res, (int)send_size); 350 451 return 1; 351 452 } 352 453 io_uring_cqe_seen(ring, cqe); 353 454 continue; 354 455 } 355 - 456 + if ((cqe->flags & IORING_CQE_F_MORE) && (cqe->flags & IORING_CQE_F_NOTIF)) { 457 + fprintf(stderr, "unexpected cflags %i res %i\n", 458 + cqe->flags, cqe->res); 459 + return 1; 460 + } 356 461 if (cqe->user_data >= nr_reqs) { 357 462 fprintf(stderr, "invalid user_data %lu\n", 358 463 (unsigned long)cqe->user_data); 359 464 return 1; 360 465 } 361 466 if (!(cqe->flags & IORING_CQE_F_NOTIF)) { 467 + if (cqe->flags & IORING_CQE_F_MORE) 468 + nr_cqes++; 362 469 if (cqe->user_data == nr_reqs - 1) 363 470 expected = chunk_size_last; 364 471 if (cqe->res != expected) { ··· 367 474 return 1; 368 475 } 369 476 } 370 - if ((cqe->flags & IORING_CQE_F_MORE) == 371 - (cqe->flags & IORING_CQE_F_NOTIF)) { 372 - fprintf(stderr, "unexpected cflags %i res %i\n", 373 - cqe->flags, cqe->res); 374 - return 1; 375 - } 376 477 io_uring_cqe_seen(ring, cqe); 377 478 } 378 479 ··· 388 489 389 490 static int test_inet_send(struct io_uring *ring) 390 491 { 492 + struct send_conf conf; 391 493 struct sockaddr_storage addr; 392 494 int sock_client = -1, sock_server = -1; 393 495 int ret, j, i; 496 + int buf_index; 394 497 395 - for (j = 0; j < 16; j++) { 498 + for (j = 0; j < 32; j++) { 396 499 bool ipv6 = j & 1; 397 500 bool client_connect = j & 2; 398 501 bool msg_zc_set = j & 4; 399 502 bool tcp = j & 8; 503 + bool swap_sockets = j & 16; 400 504 401 505 if (tcp && !client_connect) 402 506 continue; 403 - 507 + if (swap_sockets && !tcp) 508 + continue; 509 + #ifndef SO_ZEROCOPY 510 + if (msg_zc_set) 511 + continue; 512 + #endif 404 513 ret = create_socketpair_ip(&addr, &sock_client, &sock_server, ipv6, 405 514 client_connect, msg_zc_set, tcp); 406 515 if (ret) { 407 516 fprintf(stderr, "sock prep failed %d\n", ret); 408 517 return 1; 409 518 } 519 + if (swap_sockets) { 520 + int tmp_sock = sock_client; 410 521 411 - for (i = 0; i < 256; i++) { 412 - int buf_flavour = i & 3; 413 - bool fixed_buf = i & 4; 414 - struct sockaddr_storage *addr_arg = (i & 8) ? &addr : NULL; 415 - bool cork = i & 16; 416 - bool mix_register = i & 32; 417 - bool force_async = i & 64; 418 - bool use_sendmsg = i & 128; 522 + sock_client = sock_server; 523 + sock_server = tmp_sock; 524 + } 525 + 526 + for (i = 0; i < 1024; i++) { 527 + bool regbuf; 528 + 529 + conf.use_sendmsg = i & 1; 530 + conf.poll_first = i & 2; 531 + conf.fixed_buf = i & 4; 532 + conf.addr = (i & 8) ? &addr : NULL; 533 + conf.cork = i & 16; 534 + conf.mix_register = i & 32; 535 + conf.force_async = i & 64; 536 + conf.zc = i & 128; 537 + conf.iovec = i & 256; 538 + conf.long_iovec = i & 512; 539 + conf.tcp = tcp; 540 + regbuf = conf.mix_register || conf.fixed_buf; 419 541 420 - if (buf_flavour == BUF_T_LARGE && !tcp) 542 + if (conf.iovec && (!conf.use_sendmsg || regbuf || conf.cork)) 421 543 continue; 422 - if (!buffers_iov[buf_flavour].iov_base) 544 + if (!conf.zc) { 545 + if (regbuf) 546 + continue; 547 + /* 548 + * Non zerocopy send w/ addr was added together with sendmsg_zc, 549 + * skip if we the kernel doesn't support it. 550 + */ 551 + if (conf.addr && !has_sendmsg) 552 + continue; 553 + } 554 + if (tcp && (conf.cork || conf.addr)) 423 555 continue; 424 - if (tcp && (cork || addr_arg)) 556 + if (conf.mix_register && (!conf.cork || conf.fixed_buf)) 425 557 continue; 426 - if (mix_register && (!cork || fixed_buf)) 558 + if (!client_connect && conf.addr == NULL) 427 559 continue; 428 - if (!client_connect && addr_arg == NULL) 560 + if (conf.use_sendmsg && (regbuf || !has_sendmsg)) 429 561 continue; 430 - if (use_sendmsg && (mix_register || fixed_buf || !has_sendmsg)) 562 + if (msg_zc_set && !conf.zc) 431 563 continue; 432 564 433 - ret = do_test_inet_send(ring, sock_client, sock_server, fixed_buf, 434 - addr_arg, cork, mix_register, 435 - buf_flavour, force_async, use_sendmsg); 436 - if (ret) { 437 - fprintf(stderr, "send failed fixed buf %i, conn %i, addr %i, " 438 - "cork %i\n", 439 - fixed_buf, client_connect, !!addr_arg, 440 - cork); 441 - return 1; 565 + for (buf_index = 0; buf_index < ARRAY_SIZE(buffers_iov); buf_index++) { 566 + size_t len = buffers_iov[buf_index].iov_len; 567 + 568 + if (!buffers_iov[buf_index].iov_base) 569 + continue; 570 + if (!tcp && len > 4 * page_sz) 571 + continue; 572 + 573 + conf.buf_index = buf_index; 574 + ret = do_test_inet_send(ring, sock_client, sock_server, &conf); 575 + if (ret) { 576 + fprintf(stderr, "send failed fixed buf %i, " 577 + "conn %i, addr %i, cork %i\n", 578 + conf.fixed_buf, client_connect, 579 + !!conf.addr, conf.cork); 580 + return 1; 581 + } 442 582 } 443 583 } 444 584 ··· 588 728 if (argc > 1) 589 729 return T_EXIT_SKIP; 590 730 731 + page_sz = sysconf(_SC_PAGESIZE); 732 + 591 733 /* create TCP IPv6 pair */ 592 734 ret = create_socketpair_ip(&addr, &sp[0], &sp[1], true, true, false, true); 593 735 if (ret) { ··· 595 737 return T_EXIT_FAIL; 596 738 } 597 739 598 - len = 1U << 25; /* 32MB, should be enough to trigger a short send */ 599 - tx_buffer = aligned_alloc(4096, len); 600 - rx_buffer = aligned_alloc(4096, len); 740 + len = LARGE_BUF_SIZE; 741 + tx_buffer = aligned_alloc(page_sz, len); 742 + rx_buffer = aligned_alloc(page_sz, len); 601 743 if (tx_buffer && rx_buffer) { 602 744 buffers_iov[BUF_T_LARGE].iov_base = tx_buffer; 603 745 buffers_iov[BUF_T_LARGE].iov_len = len; 604 746 } else { 747 + if (tx_buffer) 748 + free(tx_buffer); 749 + if (rx_buffer) 750 + free(rx_buffer); 751 + 605 752 printf("skip large buffer tests, can't alloc\n"); 606 753 607 - len = 8192; 608 - tx_buffer = aligned_alloc(4096, len); 609 - rx_buffer = aligned_alloc(4096, len); 754 + len = 2 * page_sz; 755 + tx_buffer = aligned_alloc(page_sz, len); 756 + rx_buffer = aligned_alloc(page_sz, len); 610 757 } 611 758 if (!tx_buffer || !rx_buffer) { 612 759 fprintf(stderr, "can't allocate buffers\n"); 613 760 return T_EXIT_FAIL; 614 761 } 615 762 616 - buffers_iov[BUF_T_NORMAL].iov_base = tx_buffer + 4096; 617 - buffers_iov[BUF_T_NORMAL].iov_len = 4096; 763 + srand((unsigned)time(NULL)); 764 + for (i = 0; i < len; i++) 765 + tx_buffer[i] = i; 766 + memset(rx_buffer, 0, len); 767 + 768 + buffers_iov[BUF_T_NORMAL].iov_base = tx_buffer + page_sz; 769 + buffers_iov[BUF_T_NORMAL].iov_len = page_sz; 618 770 buffers_iov[BUF_T_SMALL].iov_base = tx_buffer; 619 771 buffers_iov[BUF_T_SMALL].iov_len = 137; 620 772 buffers_iov[BUF_T_NONALIGNED].iov_base = tx_buffer + BUFFER_OFFSET; 621 - buffers_iov[BUF_T_NONALIGNED].iov_len = 8192 - BUFFER_OFFSET - 13; 773 + buffers_iov[BUF_T_NONALIGNED].iov_len = 2 * page_sz - BUFFER_OFFSET - 13; 774 + 775 + if (len == LARGE_BUF_SIZE) { 776 + void *huge_page; 777 + int off = page_sz + 27; 778 + 779 + len = 1U << 22; 780 + huge_page = mmap(NULL, len, PROT_READ|PROT_WRITE, 781 + MAP_PRIVATE | MAP_HUGETLB | MAP_HUGE_2MB | MAP_ANONYMOUS, 782 + -1, 0); 783 + if (huge_page != MAP_FAILED) { 784 + buffers_iov[BUF_T_HUGETLB].iov_base = huge_page + off; 785 + buffers_iov[BUF_T_HUGETLB].iov_len = len - off; 786 + } 787 + } 622 788 623 789 ret = io_uring_queue_init(32, &ring, 0); 624 790 if (ret) { ··· 626 792 return T_EXIT_FAIL; 627 793 } 628 794 629 - srand((unsigned)time(NULL)); 630 - for (i = 0; i < len; i++) 631 - tx_buffer[i] = i; 632 - memset(rx_buffer, 0, len); 633 - 634 795 ret = test_basic_send(&ring, sp[0], sp[1]); 635 796 if (ret == T_EXIT_SKIP) 636 797 return ret; ··· 641 802 642 803 has_sendmsg = io_check_zc_sendmsg(&ring); 643 804 644 - ret = test_send_faults(&ring, sp[0], sp[1]); 805 + ret = test_send_faults(sp[0], sp[1]); 645 806 if (ret) { 646 807 fprintf(stderr, "test_send_faults() failed\n"); 647 808 return T_EXIT_FAIL; ··· 669 830 } else if (ret != T_SETUP_OK) { 670 831 fprintf(stderr, "buffer registration failed %i\n", ret); 671 832 return T_EXIT_FAIL; 833 + } 834 + 835 + if (buffers_iov[BUF_T_HUGETLB].iov_base) { 836 + buffers_iov[BUF_T_HUGETLB].iov_base += 13; 837 + buffers_iov[BUF_T_HUGETLB].iov_len -= 26; 838 + } 839 + if (buffers_iov[BUF_T_LARGE].iov_base) { 840 + buffers_iov[BUF_T_LARGE].iov_base += 13; 841 + buffers_iov[BUF_T_LARGE].iov_len -= 26; 672 842 } 673 843 674 844 ret = test_inet_send(&ring);
+7 -4
vendor/opam/uring/vendor/liburing/test/send_recv.c
··· 192 192 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 193 193 if (sockfd < 0) { 194 194 perror("socket"); 195 - return 1; 195 + goto err2; 196 196 } 197 197 198 198 ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)); 199 199 if (ret < 0) { 200 200 perror("connect"); 201 - return 1; 201 + goto err; 202 202 } 203 203 204 204 sqe = io_uring_get_sqe(&ring); ··· 214 214 ret = io_uring_wait_cqe(&ring, &cqe); 215 215 if (cqe->res == -EINVAL) { 216 216 fprintf(stdout, "send not supported, skipping\n"); 217 - close(sockfd); 218 - return 0; 217 + goto err; 219 218 } 220 219 if (cqe->res != iov.iov_len) { 221 220 fprintf(stderr, "failed cqe: %d\n", cqe->res); ··· 223 222 } 224 223 225 224 close(sockfd); 225 + io_uring_queue_exit(&ring); 226 226 return 0; 227 + 227 228 err: 228 229 close(sockfd); 230 + err2: 231 + io_uring_queue_exit(&ring); 229 232 return 1; 230 233 } 231 234
+5 -16
vendor/opam/uring/vendor/liburing/test/send_recvmsg.c
··· 184 184 185 185 if ((rd->buf_ring || rd->buf_select) && !rd->no_buf_add) { 186 186 if (rd->buf_ring) { 187 - struct io_uring_buf_reg reg = { }; 188 - void *ptr; 189 - 190 - if (posix_memalign(&ptr, 4096, 4096)) 191 - goto err; 192 - 193 - reg.ring_addr = (unsigned long) ptr; 194 - reg.ring_entries = 1; 195 - reg.bgid = BUF_BGID; 196 - if (io_uring_register_buf_ring(&ring, &reg, 0)) { 187 + br = io_uring_setup_buf_ring(&ring, 1, BUF_BGID, 0, &ret); 188 + if (!br) { 197 189 no_pbuf_ring = 1; 198 190 goto out; 199 191 } 200 - 201 - br = ptr; 202 - io_uring_buf_ring_init(br); 203 192 io_uring_buf_ring_add(br, buf, sizeof(buf), BUF_BID, 204 193 io_uring_buf_ring_mask(1), 0); 205 194 io_uring_buf_ring_advance(br, 1); ··· 246 235 ret = do_recvmsg(&ring, buf, rd); 247 236 close(sockfd); 248 237 249 - io_uring_queue_exit(&ring); 250 238 if (br) 251 - free(br); 239 + io_uring_free_buf_ring(&ring, br, 1, BUF_BGID); 240 + io_uring_queue_exit(&ring); 252 241 err: 253 242 return (void *)(intptr_t)ret; 254 243 out: ··· 256 245 out_no_ring: 257 246 pthread_mutex_unlock(mutex); 258 247 if (br) 259 - free(br); 248 + io_uring_free_buf_ring(&ring, br, 1, BUF_BGID); 260 249 return NULL; 261 250 } 262 251
+2 -2
vendor/opam/uring/vendor/liburing/test/sendmsg_fs_cve.c
··· 1 - /* SPDX-License-Identifier: MIT */ 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 2 /* 3 3 * repro-CVE-2020-29373 -- Reproducer for CVE-2020-29373. 4 4 * ··· 16 16 * GNU General Public License for more details. 17 17 * 18 18 * You should have received a copy of the GNU General Public License 19 - * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 + * along with this program; if not, see <https://www.gnu.org/licenses/>. 20 20 */ 21 21 22 22 #include <unistd.h>
+7 -9
vendor/opam/uring/vendor/liburing/test/single-issuer.c
··· 5 5 #include <stdlib.h> 6 6 #include <string.h> 7 7 #include <fcntl.h> 8 - #include <error.h> 9 8 #include <sys/types.h> 10 9 #include <sys/wait.h> 11 10 ··· 56 55 return ret; 57 56 58 57 if (ret != 1) 59 - error(1, ret, "submit %i", ret); 58 + t_error(1, ret, "submit %i", ret); 60 59 ret = io_uring_wait_cqe(ring, &cqe); 61 60 if (ret) 62 - error(1, ret, "wait fail %i", ret); 61 + t_error(1, ret, "wait fail %i", ret); 63 62 64 63 if (cqe->res || cqe->user_data != 42) 65 - error(1, ret, "invalid cqe"); 64 + t_error(1, ret, "invalid cqe"); 66 65 67 66 io_uring_cqe_seen(ring, cqe); 68 67 return 0; ··· 78 77 79 78 ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER); 80 79 if (ret == -EINVAL) { 81 - fprintf(stderr, "SETUP_SINGLE_ISSUER is not supported, skip\n"); 82 80 return T_EXIT_SKIP; 83 81 } else if (ret) { 84 82 fprintf(stderr, "io_uring_queue_init() failed %i\n", ret); ··· 106 104 ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | 107 105 IORING_SETUP_R_DISABLED); 108 106 if (ret) 109 - error(1, ret, "ring init (2) %i", ret); 107 + t_error(1, ret, "ring init (2) %i", ret); 110 108 111 109 if (!fork_t()) { 112 110 io_uring_enable_rings(&ring); ··· 122 120 ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | 123 121 IORING_SETUP_R_DISABLED); 124 122 if (ret) 125 - error(1, ret, "ring init (3) %i", ret); 123 + t_error(1, ret, "ring init (3) %i", ret); 126 124 127 125 io_uring_enable_rings(&ring); 128 126 if (!fork_t()) { ··· 137 135 /* test that anyone can submit to a SQPOLL|SINGLE_ISSUER ring */ 138 136 ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_SQPOLL); 139 137 if (ret) 140 - error(1, ret, "ring init (4) %i", ret); 138 + t_error(1, ret, "ring init (4) %i", ret); 141 139 142 140 ret = try_submit(&ring); 143 141 if (ret) { ··· 157 155 /* test that IORING_ENTER_REGISTERED_RING doesn't break anything */ 158 156 ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER); 159 157 if (ret) 160 - error(1, ret, "ring init (5) %i", ret); 158 + t_error(1, ret, "ring init (5) %i", ret); 161 159 162 160 if (!fork_t()) { 163 161 ret = try_submit(&ring);
+3 -4
vendor/opam/uring/vendor/liburing/test/skip-cqe.c
··· 8 8 #include <assert.h> 9 9 10 10 #include "liburing.h" 11 + #include "helpers.h" 11 12 12 13 #define LINK_SIZE 6 13 14 #define TIMEOUT_USER_DATA (-1) ··· 323 324 return 1; 324 325 } 325 326 326 - if (!(ring.features & IORING_FEAT_CQE_SKIP)) { 327 - printf("IOSQE_CQE_SKIP_SUCCESS is not supported, skip\n"); 328 - return 0; 329 - } 327 + if (!(ring.features & IORING_FEAT_CQE_SKIP)) 328 + return T_EXIT_SKIP; 330 329 331 330 for (i = 0; i < 4; i++) { 332 331 bool skip_last = i & 1;
-1
vendor/opam/uring/vendor/liburing/test/socket.c
··· 272 272 } 273 273 if (cqe->res < 0) { 274 274 if (cqe->res == -EINVAL) { 275 - fprintf(stdout, "No socket support, skipping\n"); 276 275 no_socket = 1; 277 276 io_uring_cqe_seen(&ring, cqe); 278 277 return fallback_send(&ring, &saddr);
+10 -3
vendor/opam/uring/vendor/liburing/test/sq-poll-dup.c
··· 171 171 vecs = t_create_buffers(BUFFERS, BS); 172 172 173 173 fd = open(fname, O_RDONLY | O_DIRECT); 174 - if (fname != argv[1]) 175 - unlink(fname); 174 + if (fd < 0) { 175 + int __e = errno; 176 + 177 + if (fname != argv[1]) 178 + unlink(fname); 176 179 177 - if (fd < 0) { 180 + if (__e == EINVAL) 181 + return T_EXIT_SKIP; 178 182 perror("open"); 179 183 return -1; 180 184 } 185 + 186 + if (fname != argv[1]) 187 + unlink(fname); 181 188 182 189 ret = test(fd, 0, 0); 183 190 if (ret) {
+1 -1
vendor/opam/uring/vendor/liburing/test/sq-poll-kthread.c
··· 117 117 return ret; 118 118 } 119 119 120 - int test_sq_poll_kthread_stopped(bool do_exit) 120 + static int test_sq_poll_kthread_stopped(bool do_exit) 121 121 { 122 122 pid_t pid; 123 123 int status = 0;
+3 -2
vendor/opam/uring/vendor/liburing/test/sq-poll-share.c
··· 89 89 vecs = t_create_buffers(BUFFERS, BS); 90 90 91 91 fd = open(fname, O_RDONLY | O_DIRECT); 92 - if (fname != argv[1]) 93 - unlink(fname); 94 92 if (fd < 0) { 95 93 perror("open"); 96 94 return -1; 97 95 } 96 + 97 + if (fname != argv[1]) 98 + unlink(fname); 98 99 99 100 for (i = 0; i < NR_RINGS; i++) { 100 101 struct io_uring_params p = { };
+17 -6
vendor/opam/uring/vendor/liburing/test/sqpoll-cancel-hang.c
··· 9 9 #include <time.h> 10 10 #include <unistd.h> 11 11 #include "liburing.h" 12 + #include "helpers.h" 12 13 #include "../src/syscall.h" 14 + 15 + /* 16 + * This syzbot test is known broken on some archs, just allow the ones that 17 + * are regularly tested. 18 + */ 19 + #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \ 20 + defined(__aarch64__) 13 21 14 22 static uint64_t current_time_ms(void) 15 23 { ··· 39 47 40 48 #define WAIT_FLAGS __WALL 41 49 42 - uint64_t r[3] = {0xffffffffffffffff, 0x0, 0x0}; 50 + static uint64_t r[3] = {0xffffffffffffffff, 0x0, 0x0}; 43 51 44 52 static long syz_io_uring_setup(volatile long a0, volatile long a1, 45 53 volatile long a2, volatile long a3, volatile long a4, volatile long ··· 92 100 } 93 101 94 102 95 - void trigger_bug(void) 103 + static void trigger_bug(void) 96 104 { 97 105 intptr_t res = 0; 98 106 *(uint32_t*)0x20000204 = 0; ··· 133 141 } 134 142 int main(void) 135 143 { 136 - mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul); 144 + mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 137 145 int pid = fork(); 138 146 if (pid < 0) 139 147 exit(1); ··· 152 160 } 153 161 return 0; 154 162 } 155 - 156 - 157 - 163 + #else 164 + int main(void) 165 + { 166 + return T_EXIT_SKIP; 167 + } 168 + #endif
+4 -4
vendor/opam/uring/vendor/liburing/test/sqpoll-disable-exit.c
··· 136 136 } 137 137 } 138 138 139 - static void setup_test() 139 + static void setup_test(void) 140 140 { 141 141 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 142 142 setpgrp(); ··· 188 188 } 189 189 int main(void) 190 190 { 191 - mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); 192 - mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul); 193 - mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul); 191 + mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 192 + mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 193 + mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul); 194 194 loop(); 195 195 return 0; 196 196 }
+2 -1
vendor/opam/uring/vendor/liburing/test/symlink.c
··· 43 43 return 1; 44 44 } 45 45 46 - int test_link_contents(const char* linkname, const char *expected_contents) 46 + static int test_link_contents(const char* linkname, 47 + const char *expected_contents) 47 48 { 48 49 char buf[128]; 49 50 int ret = readlink(linkname, buf, 127);
+2 -1
vendor/opam/uring/vendor/liburing/test/test.h
··· 14 14 const char *description; 15 15 } io_uring_test_config; 16 16 17 - io_uring_test_config io_uring_test_configs[] = { 17 + __attribute__((__unused__)) 18 + static io_uring_test_config io_uring_test_configs[] = { 18 19 { 0, "default" }, 19 20 { IORING_SETUP_SQE128, "large SQE"}, 20 21 { IORING_SETUP_CQE32, "large CQE"},
+11 -7
vendor/opam/uring/vendor/liburing/test/timeout-new.c
··· 12 12 #define TIMEOUT_MSEC 200 13 13 #define TIMEOUT_SEC 10 14 14 15 - int thread_ret0, thread_ret1; 16 - int cnt = 0; 17 - pthread_mutex_t mutex; 15 + static int thread_ret0, thread_ret1; 16 + static int cnt = 0; 17 + static pthread_mutex_t mutex; 18 18 19 19 static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec) 20 20 { ··· 111 111 return 0; 112 112 } 113 113 114 - int __reap_thread_fn(void *data) { 114 + static int __reap_thread_fn(void *data) 115 + { 115 116 struct io_uring *ring = (struct io_uring *)data; 116 117 struct io_uring_cqe *cqe; 117 118 struct __kernel_timespec ts; ··· 123 124 return io_uring_wait_cqe_timeout(ring, &cqe, &ts); 124 125 } 125 126 126 - void *reap_thread_fn0(void *data) { 127 + static void *reap_thread_fn0(void *data) 128 + { 127 129 thread_ret0 = __reap_thread_fn(data); 128 130 return NULL; 129 131 } 130 132 131 - void *reap_thread_fn1(void *data) { 133 + static void *reap_thread_fn1(void *data) 134 + { 132 135 thread_ret1 = __reap_thread_fn(data); 133 136 return NULL; 134 137 } ··· 137 140 * This is to test issuing a sqe in main thread and reaping it in two child-thread 138 141 * at the same time. To see if timeout feature works or not. 139 142 */ 140 - int test_multi_threads_timeout() { 143 + static int test_multi_threads_timeout(void) 144 + { 141 145 struct io_uring ring; 142 146 int ret; 143 147 bool both_wait = false;
-204
vendor/opam/uring/vendor/liburing/test/timeout-overflow.c
··· 1 - /* SPDX-License-Identifier: MIT */ 2 - /* 3 - * Description: run timeout overflow test 4 - * 5 - */ 6 - #include <errno.h> 7 - #include <stdio.h> 8 - #include <limits.h> 9 - #include <string.h> 10 - #include <sys/time.h> 11 - 12 - #include "liburing.h" 13 - #include "helpers.h" 14 - 15 - #define TIMEOUT_MSEC 200 16 - static int not_supported; 17 - 18 - static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec) 19 - { 20 - ts->tv_sec = msec / 1000; 21 - ts->tv_nsec = (msec % 1000) * 1000000; 22 - } 23 - 24 - static int check_timeout_support(void) 25 - { 26 - struct io_uring_sqe *sqe; 27 - struct io_uring_cqe *cqe; 28 - struct __kernel_timespec ts; 29 - struct io_uring_params p; 30 - struct io_uring ring; 31 - int ret; 32 - 33 - memset(&p, 0, sizeof(p)); 34 - ret = io_uring_queue_init_params(1, &ring, &p); 35 - if (ret) { 36 - fprintf(stderr, "ring setup failed: %d\n", ret); 37 - return T_EXIT_FAIL; 38 - } 39 - 40 - /* not really a match, but same kernel added batched completions */ 41 - if (p.features & IORING_FEAT_POLL_32BITS) { 42 - not_supported = 1; 43 - return T_EXIT_SKIP; 44 - } 45 - 46 - sqe = io_uring_get_sqe(&ring); 47 - msec_to_ts(&ts, TIMEOUT_MSEC); 48 - io_uring_prep_timeout(sqe, &ts, 1, 0); 49 - 50 - ret = io_uring_submit(&ring); 51 - if (ret < 0) { 52 - fprintf(stderr, "sqe submit failed: %d\n", ret); 53 - goto err; 54 - } 55 - 56 - ret = io_uring_wait_cqe(&ring, &cqe); 57 - if (ret < 0) { 58 - fprintf(stderr, "wait completion %d\n", ret); 59 - goto err; 60 - } 61 - 62 - if (cqe->res == -EINVAL) { 63 - not_supported = 1; 64 - fprintf(stdout, "Timeout not supported, ignored\n"); 65 - return 0; 66 - } 67 - 68 - io_uring_cqe_seen(&ring, cqe); 69 - io_uring_queue_exit(&ring); 70 - return T_EXIT_PASS; 71 - err: 72 - io_uring_queue_exit(&ring); 73 - return T_EXIT_FAIL; 74 - } 75 - 76 - /* 77 - * We first setup 4 timeout requests, which require a count value of 1, 1, 2, 78 - * UINT_MAX, so the sequence is 1, 2, 4, 2. Before really timeout, this 4 79 - * requests will not lead the change of cq_cached_tail, so as sq_dropped. 80 - * 81 - * And before this patch. The order of this four requests will be req1->req2-> 82 - * req4->req3. Actually, it should be req1->req2->req3->req4. 83 - * 84 - * Then, if there is 2 nop req. All timeout requests expect req4 will completed 85 - * successful after the patch. And req1/req2 will completed successful with 86 - * req3/req4 return -ETIME without this patch! 87 - */ 88 - static int test_timeout_overflow(void) 89 - { 90 - struct io_uring_sqe *sqe; 91 - struct io_uring_cqe *cqe; 92 - struct __kernel_timespec ts; 93 - struct io_uring ring; 94 - int i, ret; 95 - 96 - ret = io_uring_queue_init(16, &ring, 0); 97 - if (ret) { 98 - fprintf(stderr, "ring setup failed: %d\n", ret); 99 - return 1; 100 - } 101 - 102 - msec_to_ts(&ts, TIMEOUT_MSEC); 103 - for (i = 0; i < 4; i++) { 104 - unsigned num = 0; 105 - sqe = io_uring_get_sqe(&ring); 106 - switch (i) { 107 - case 0: 108 - case 1: 109 - num = 1; 110 - break; 111 - case 2: 112 - num = 2; 113 - break; 114 - case 3: 115 - num = UINT_MAX; 116 - break; 117 - } 118 - io_uring_prep_timeout(sqe, &ts, num, 0); 119 - } 120 - 121 - for (i = 0; i < 2; i++) { 122 - sqe = io_uring_get_sqe(&ring); 123 - io_uring_prep_nop(sqe); 124 - io_uring_sqe_set_data(sqe, (void *) 1); 125 - } 126 - ret = io_uring_submit(&ring); 127 - if (ret < 0) { 128 - fprintf(stderr, "sqe submit failed: %d\n", ret); 129 - goto err; 130 - } 131 - 132 - i = 0; 133 - while (i < 6) { 134 - ret = io_uring_wait_cqe(&ring, &cqe); 135 - if (ret < 0) { 136 - fprintf(stderr, "wait completion %d\n", ret); 137 - goto err; 138 - } 139 - 140 - /* 141 - * cqe1: first nop req 142 - * cqe2: first timeout req, because of cqe1 143 - * cqe3: second timeout req because of cqe1 + cqe2 144 - * cqe4: second nop req 145 - * cqe5~cqe6: the left three timeout req 146 - */ 147 - switch (i) { 148 - case 0: 149 - case 3: 150 - if (io_uring_cqe_get_data(cqe) != (void *) 1) { 151 - fprintf(stderr, "nop not seen as 1 or 2\n"); 152 - goto err; 153 - } 154 - break; 155 - case 1: 156 - case 2: 157 - case 4: 158 - if (cqe->res == -ETIME) { 159 - fprintf(stderr, "expected not return -ETIME " 160 - "for the #%d timeout req\n", i - 1); 161 - goto err; 162 - } 163 - break; 164 - case 5: 165 - if (cqe->res != -ETIME) { 166 - fprintf(stderr, "expected return -ETIME for " 167 - "the #%d timeout req\n", i - 1); 168 - goto err; 169 - } 170 - break; 171 - } 172 - io_uring_cqe_seen(&ring, cqe); 173 - i++; 174 - } 175 - 176 - return 0; 177 - err: 178 - return 1; 179 - } 180 - 181 - int main(int argc, char *argv[]) 182 - { 183 - int ret; 184 - 185 - if (argc > 1) 186 - return T_EXIT_SKIP; 187 - 188 - ret = check_timeout_support(); 189 - if (ret == T_EXIT_FAIL) { 190 - fprintf(stderr, "check_timeout_support failed: %d\n", ret); 191 - return T_EXIT_FAIL; 192 - } 193 - 194 - if (not_supported) 195 - return T_EXIT_SKIP; 196 - 197 - ret = test_timeout_overflow(); 198 - if (ret) { 199 - fprintf(stderr, "test_timeout_overflow failed\n"); 200 - return T_EXIT_FAIL; 201 - } 202 - 203 - return T_EXIT_PASS; 204 - }
+277 -2
vendor/opam/uring/vendor/liburing/test/timeout.c
··· 14 14 #include <sys/types.h> 15 15 #include <sys/stat.h> 16 16 17 + #include "helpers.h" 17 18 #include "liburing.h" 18 19 #include "../src/syscall.h" 19 20 20 21 #define TIMEOUT_MSEC 200 21 22 static int not_supported; 22 23 static int no_modify; 24 + static int no_multishot; 23 25 24 26 static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec) 25 27 { ··· 176 178 goto err; 177 179 } 178 180 i++; 179 - }; 181 + } 180 182 181 183 return 0; 182 184 err: ··· 1303 1305 fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1304 1306 return 1; 1305 1307 } else if (cqe->user_data == 1 && cqe->res == -EINVAL) { 1306 - fprintf(stderr, "ETIME_SUCCESS is not supported, skip\n"); 1307 1308 goto done; 1308 1309 } else if (cqe->res != -ETIME || cqe->user_data != 1) { 1309 1310 fprintf(stderr, "timeout failed %i %i\n", cqe->res, ··· 1328 1329 } 1329 1330 1330 1331 1332 + static int test_timeout_multishot(struct io_uring *ring) 1333 + { 1334 + struct io_uring_cqe *cqe; 1335 + struct io_uring_sqe *sqe; 1336 + struct __kernel_timespec ts; 1337 + int ret; 1338 + 1339 + sqe = io_uring_get_sqe(ring); 1340 + if (!sqe) { 1341 + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); 1342 + goto err; 1343 + } 1344 + 1345 + msec_to_ts(&ts, TIMEOUT_MSEC); 1346 + io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT); 1347 + io_uring_sqe_set_data(sqe, (void *) 1); 1348 + 1349 + ret = io_uring_submit(ring); 1350 + if (ret <= 0) { 1351 + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); 1352 + goto err; 1353 + } 1354 + 1355 + for (int i = 0; i < 2; i++) { 1356 + ret = io_uring_wait_cqe(ring, &cqe); 1357 + if (ret < 0) { 1358 + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1359 + goto err; 1360 + } 1361 + 1362 + ret = cqe->res; 1363 + if (ret == -EINVAL) { 1364 + no_multishot = 1; 1365 + return T_EXIT_SKIP; 1366 + } 1367 + 1368 + if (!(cqe->flags & IORING_CQE_F_MORE)) { 1369 + fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__); 1370 + goto err; 1371 + } 1372 + 1373 + if (ret != -ETIME) { 1374 + fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); 1375 + goto err; 1376 + } 1377 + 1378 + io_uring_cqe_seen(ring, cqe); 1379 + } 1380 + 1381 + sqe = io_uring_get_sqe(ring); 1382 + if (!sqe) { 1383 + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); 1384 + goto err; 1385 + } 1386 + 1387 + io_uring_prep_timeout_remove(sqe, 1, 0); 1388 + io_uring_sqe_set_data(sqe, (void *) 2); 1389 + 1390 + ret = io_uring_submit(ring); 1391 + if (ret <= 0) { 1392 + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); 1393 + goto err; 1394 + } 1395 + 1396 + ret = io_uring_wait_cqe(ring, &cqe); 1397 + if (ret < 0) { 1398 + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1399 + goto err; 1400 + } 1401 + 1402 + ret = cqe->res; 1403 + if (ret < 0) { 1404 + fprintf(stderr, "%s: remove failed: %s\n", __FUNCTION__, strerror(-ret)); 1405 + goto err; 1406 + } 1407 + 1408 + io_uring_cqe_seen(ring, cqe); 1409 + 1410 + ret = io_uring_wait_cqe(ring, &cqe); 1411 + if (ret < 0) { 1412 + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1413 + goto err; 1414 + } 1415 + 1416 + ret = cqe->res; 1417 + if (ret != -ECANCELED) { 1418 + fprintf(stderr, "%s: timeout canceled: %s %llu\n", __FUNCTION__, strerror(-ret), cqe->user_data); 1419 + goto err; 1420 + } 1421 + 1422 + io_uring_cqe_seen(ring, cqe); 1423 + return 0; 1424 + err: 1425 + return 1; 1426 + } 1427 + 1428 + 1429 + static int test_timeout_multishot_nr(struct io_uring *ring) 1430 + { 1431 + struct io_uring_cqe *cqe; 1432 + struct io_uring_sqe *sqe; 1433 + struct __kernel_timespec ts; 1434 + int ret; 1435 + 1436 + if (no_multishot) 1437 + return T_EXIT_SKIP; 1438 + 1439 + sqe = io_uring_get_sqe(ring); 1440 + if (!sqe) { 1441 + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); 1442 + goto err; 1443 + } 1444 + 1445 + msec_to_ts(&ts, TIMEOUT_MSEC); 1446 + io_uring_prep_timeout(sqe, &ts, 3, IORING_TIMEOUT_MULTISHOT); 1447 + io_uring_sqe_set_data(sqe, (void *) 1); 1448 + 1449 + ret = io_uring_submit(ring); 1450 + if (ret <= 0) { 1451 + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); 1452 + goto err; 1453 + } 1454 + 1455 + for (int i = 0; i < 3; i++) { 1456 + ret = io_uring_wait_cqe(ring, &cqe); 1457 + if (ret < 0) { 1458 + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1459 + goto err; 1460 + } 1461 + 1462 + if (i < 2 && !(cqe->flags & IORING_CQE_F_MORE)) { 1463 + fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__); 1464 + goto err; 1465 + } 1466 + if (i == 3 && (cqe->flags & IORING_CQE_F_MORE)) { 1467 + fprintf(stderr, "%s: flag set in cqe\n", __FUNCTION__); 1468 + goto err; 1469 + } 1470 + 1471 + ret = cqe->res; 1472 + if (ret != -ETIME) { 1473 + fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); 1474 + goto err; 1475 + } 1476 + 1477 + io_uring_cqe_seen(ring, cqe); 1478 + } 1479 + 1480 + msec_to_ts(&ts, 2 * TIMEOUT_MSEC); 1481 + ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts); 1482 + if (ret != -ETIME) { 1483 + fprintf(stderr, "%s: wait completion timeout %s\n", __FUNCTION__, strerror(-ret)); 1484 + goto err; 1485 + } 1486 + 1487 + return 0; 1488 + err: 1489 + return 1; 1490 + } 1491 + 1492 + 1493 + static int test_timeout_multishot_overflow(struct io_uring *ring) 1494 + { 1495 + struct io_uring_cqe *cqe; 1496 + struct io_uring_sqe *sqe; 1497 + struct __kernel_timespec ts; 1498 + int ret; 1499 + 1500 + if (no_multishot) 1501 + return T_EXIT_SKIP; 1502 + 1503 + sqe = io_uring_get_sqe(ring); 1504 + if (!sqe) { 1505 + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); 1506 + goto err; 1507 + } 1508 + 1509 + msec_to_ts(&ts, 10); 1510 + io_uring_prep_timeout(sqe, &ts, 0, IORING_TIMEOUT_MULTISHOT); 1511 + io_uring_sqe_set_data(sqe, (void *) 1); 1512 + 1513 + ret = io_uring_submit(ring); 1514 + if (ret <= 0) { 1515 + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); 1516 + goto err; 1517 + } 1518 + 1519 + ret = io_uring_wait_cqe(ring, &cqe); 1520 + if (ret < 0) { 1521 + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1522 + goto err; 1523 + } 1524 + 1525 + ret = cqe->res; 1526 + if (ret != -ETIME) { 1527 + fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); 1528 + goto err; 1529 + } 1530 + 1531 + io_uring_cqe_seen(ring, cqe); 1532 + sleep(1); 1533 + 1534 + if (!((*ring->sq.kflags) & IORING_SQ_CQ_OVERFLOW)) { 1535 + goto err; 1536 + } 1537 + 1538 + /* multishot timer should be gone */ 1539 + sqe = io_uring_get_sqe(ring); 1540 + if (!sqe) { 1541 + fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); 1542 + goto err; 1543 + } 1544 + 1545 + io_uring_prep_timeout_remove(sqe, 1, 0); 1546 + 1547 + ret = io_uring_submit(ring); 1548 + if (ret <= 0) { 1549 + fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); 1550 + goto err; 1551 + } 1552 + 1553 + ret = io_uring_wait_cqe(ring, &cqe); 1554 + if (ret < 0) { 1555 + fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); 1556 + goto err; 1557 + } 1558 + 1559 + ret = cqe->res; 1560 + io_uring_cqe_seen(ring, cqe); 1561 + if (ret != -ETIME) { 1562 + fprintf(stderr, "%s: remove failed: %d %s\n", __FUNCTION__, ret, strerror(-ret)); 1563 + goto err; 1564 + } 1565 + 1566 + return 0; 1567 + err: 1568 + return 1; 1569 + } 1570 + 1571 + 1331 1572 int main(int argc, char *argv[]) 1332 1573 { 1333 1574 struct io_uring ring, sqpoll_ring; ··· 1418 1659 if (ret) { 1419 1660 fprintf(stderr, "test_timeout_flags3 failed\n"); 1420 1661 return ret; 1662 + } 1663 + 1664 + ret = test_timeout_multishot(&ring); 1665 + if (ret && ret != T_EXIT_SKIP) { 1666 + fprintf(stderr, "test_timeout_multishot failed\n"); 1667 + return ret; 1668 + } 1669 + 1670 + ret = test_timeout_multishot_nr(&ring); 1671 + if (ret && ret != T_EXIT_SKIP) { 1672 + fprintf(stderr, "test_timeout_multishot_nr failed\n"); 1673 + return ret; 1674 + } 1675 + 1676 + /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */ 1677 + io_uring_queue_exit(&ring); 1678 + ret = io_uring_queue_init(8, &ring, 0); 1679 + if (ret) { 1680 + fprintf(stderr, "ring setup failed\n"); 1681 + return 1; 1682 + } 1683 + 1684 + ret = test_timeout_multishot_overflow(&ring); 1685 + if (ret && ret != T_EXIT_SKIP) { 1686 + fprintf(stderr, "test_timeout_multishot_overflow failed\n"); 1687 + return ret; 1688 + } 1689 + 1690 + /* io_uring_wait_cqe_timeout() may have left a timeout, reinit ring */ 1691 + io_uring_queue_exit(&ring); 1692 + ret = io_uring_queue_init(8, &ring, 0); 1693 + if (ret) { 1694 + fprintf(stderr, "ring setup failed\n"); 1695 + return 1; 1421 1696 } 1422 1697 1423 1698 ret = test_single_timeout_wait(&ring, &p);
+1 -1
vendor/opam/uring/vendor/liburing/test/unlink.c
··· 1 1 /* SPDX-License-Identifier: MIT */ 2 2 /* 3 - * Description: run various nop tests 3 + * Description: run various unlink tests 4 4 * 5 5 */ 6 6 #include <errno.h>
+25
vendor/opam/uring/vendor/liburing/test/version.c
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Description: check version macros and runtime checks work 4 + * 5 + */ 6 + #include "liburing.h" 7 + #include "helpers.h" 8 + 9 + int main(int argc, char *argv[]) 10 + { 11 + if (!IO_URING_CHECK_VERSION(io_uring_major_version(), io_uring_minor_version())) 12 + return T_EXIT_FAIL; 13 + 14 + if (io_uring_major_version() != IO_URING_VERSION_MAJOR) 15 + return T_EXIT_FAIL; 16 + 17 + if (io_uring_minor_version() != IO_URING_VERSION_MINOR) 18 + return T_EXIT_FAIL; 19 + 20 + #if !IO_URING_CHECK_VERSION(IO_URING_VERSION_MAJOR, IO_URING_VERSION_MINOR) 21 + return T_EXIT_FAIL; 22 + #endif 23 + 24 + return T_EXIT_PASS; 25 + }
+1 -1
vendor/opam/uring/vendor/liburing/test/wakeup-hang.c
··· 5 5 #include <stdlib.h> 6 6 #include <string.h> 7 7 #include <pthread.h> 8 - #include <liburing.h> 9 8 #include <fcntl.h> 10 9 #include <poll.h> 11 10 #include <sys/time.h> 11 + #include "liburing.h" 12 12 13 13 struct thread_data { 14 14 struct io_uring *ring;
+8 -4
vendor/opam/uring/vendor/liburing/test/xattr.c
··· 51 51 } 52 52 53 53 ret = cqe->res; 54 - if (ret == -EINVAL) 55 - no_xattr = 1; 54 + if (ret < 0) { 55 + if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) 56 + no_xattr = 1; 57 + } 56 58 io_uring_cqe_seen(ring, cqe); 57 - 58 59 return ret; 59 60 } 60 61 ··· 126 127 } 127 128 128 129 ret = cqe->res; 130 + if (ret < 0) { 131 + if (ret == -EINVAL || ret == -EOPNOTSUPP) 132 + no_xattr = 1; 133 + } 129 134 io_uring_cqe_seen(ring, cqe); 130 - 131 135 return ret; 132 136 } 133 137