<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:DengXian;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"\@DengXian";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Hello Nginx Developers,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This is a patch of Nginx io_uring for async io access. Would like to receive your comments.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal">Ping<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"># HG changeset patch<o:p></o:p></p>
<p class="MsoNormal"># User Ping Zhao <<a href="mailto:ping.zhao@intel.com">ping.zhao@intel.com</a>><o:p></o:p></p>
<p class="MsoNormal"># Date 1610370434 18000<o:p></o:p></p>
<p class="MsoNormal"># Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal"># Node ID 3677cf19b98b054614030b80f73728b02fdda832<o:p></o:p></p>
<p class="MsoNormal"># Parent 82228f955153527fba12211f52bf102c90f38dfb<o:p></o:p></p>
<p class="MsoNormal">Use io_uring for async io access.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Replace aio with io_uring in async disk io access.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Io_uring is a new kernel feature to async io access. Nginx can use it for legacy disk aio access(for example, disk cache file access)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Check with iostat that shows nvme disk io has 30%+ performance improvement with 1 thread.<o:p></o:p></p>
<p class="MsoNormal">Test with wrk with 100 threads 200 connections(-t 100 -c 1000) with 25000 random requests.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> iostat(B/s)<o:p></o:p></p>
<p class="MsoNormal">libaio 1.0 GB/s<o:p></o:p></p>
<p class="MsoNormal">io_uring 1.3+ GB/s<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Patch contributor: Carter Li, Ping Zhao<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b auto/unix<o:p></o:p></p>
<p class="MsoNormal">--- a/auto/unix Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/auto/unix Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -532,44 +532,23 @@<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if [ $ngx_found = no ]; then<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_feature="Linux AIO support"<o:p></o:p></p>
<p class="MsoNormal">+ ngx_feature="Linux io_uring support (liburing)"<o:p></o:p></p>
<p class="MsoNormal"> ngx_feature_name="NGX_HAVE_FILE_AIO"<o:p></o:p></p>
<p class="MsoNormal"> ngx_feature_run=no<o:p></o:p></p>
<p class="MsoNormal">- ngx_feature_incs="#include <linux/aio_abi.h><o:p></o:p></p>
<p class="MsoNormal">- #include <sys/eventfd.h>"<o:p></o:p></p>
<p class="MsoNormal">+ ngx_feature_incs="#include <liburing.h>"<o:p></o:p></p>
<p class="MsoNormal"> ngx_feature_path=<o:p></o:p></p>
<p class="MsoNormal">- ngx_feature_libs=<o:p></o:p></p>
<p class="MsoNormal">- ngx_feature_test="struct iocb iocb;<o:p></o:p></p>
<p class="MsoNormal">- iocb.aio_lio_opcode = IOCB_CMD_PREAD;<o:p></o:p></p>
<p class="MsoNormal">- iocb.aio_flags = IOCB_FLAG_RESFD;<o:p></o:p></p>
<p class="MsoNormal">- iocb.aio_resfd = -1;<o:p></o:p></p>
<p class="MsoNormal">- (void) iocb;<o:p></o:p></p>
<p class="MsoNormal">- (void) eventfd(0, 0)"<o:p></o:p></p>
<p class="MsoNormal">+ ngx_feature_libs="-luring"<o:p></o:p></p>
<p class="MsoNormal">+ ngx_feature_test="struct io_uring ring;<o:p></o:p></p>
<p class="MsoNormal">+ int ret = io_uring_queue_init(64, &ring, 0);<o:p></o:p></p>
<p class="MsoNormal">+ if (ret < 0) return 1;<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_queue_exit(&ring);"<o:p></o:p></p>
<p class="MsoNormal"> . auto/feature<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if [ $ngx_found = yes ]; then<o:p></o:p></p>
<p class="MsoNormal"> have=NGX_HAVE_EVENTFD . auto/have<o:p></o:p></p>
<p class="MsoNormal"> have=NGX_HAVE_SYS_EVENTFD_H . auto/have<o:p></o:p></p>
<p class="MsoNormal"> CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"<o:p></o:p></p>
<p class="MsoNormal">- fi<o:p></o:p></p>
<p class="MsoNormal">- fi<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if [ $ngx_found = no ]; then<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_feature="Linux AIO support (SYS_eventfd)"<o:p></o:p></p>
<p class="MsoNormal">- ngx_feature_incs="#include <linux/aio_abi.h><o:p></o:p></p>
<p class="MsoNormal">- #include <sys/syscall.h>"<o:p></o:p></p>
<p class="MsoNormal">- ngx_feature_test="struct iocb iocb;<o:p></o:p></p>
<p class="MsoNormal">- iocb.aio_lio_opcode = IOCB_CMD_PREAD;<o:p></o:p></p>
<p class="MsoNormal">- iocb.aio_flags = IOCB_FLAG_RESFD;<o:p></o:p></p>
<p class="MsoNormal">- iocb.aio_resfd = -1;<o:p></o:p></p>
<p class="MsoNormal">- (void) iocb;<o:p></o:p></p>
<p class="MsoNormal">- (void) SYS_eventfd"<o:p></o:p></p>
<p class="MsoNormal">- . auto/feature<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if [ $ngx_found = yes ]; then<o:p></o:p></p>
<p class="MsoNormal">- have=NGX_HAVE_EVENTFD . auto/have<o:p></o:p></p>
<p class="MsoNormal">- CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"<o:p></o:p></p>
<p class="MsoNormal">+ CORE_LIBS="$CORE_LIBS -luring"<o:p></o:p></p>
<p class="MsoNormal"> fi<o:p></o:p></p>
<p class="MsoNormal"> fi<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">@@ -577,7 +556,7 @@<o:p></o:p></p>
<p class="MsoNormal"> cat << END<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> $0: no supported file AIO was found<o:p></o:p></p>
<p class="MsoNormal">-Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only<o:p></o:p></p>
<p class="MsoNormal">+Currently file AIO is supported on FreeBSD 4.3+ and Linux 5.1.0+ (requires liburing) only<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> END<o:p></o:p></p>
<p class="MsoNormal"> exit 1<o:p></o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b src/core/ngx_open_file_cache.c<o:p></o:p></p>
<p class="MsoNormal">--- a/src/core/ngx_open_file_cache.c Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/core/ngx_open_file_cache.c Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -869,8 +869,8 @@<o:p></o:p></p>
<p class="MsoNormal"> if (!of->log) {<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> /*<o:p></o:p></p>
<p class="MsoNormal">- * Use non-blocking open() not to hang on FIFO files, etc.<o:p></o:p></p>
<p class="MsoNormal">- * This flag has no effect on a regular files.<o:p></o:p></p>
<p class="MsoNormal">+ * Differs from plain read, IORING_OP_READV with O_NONBLOCK<o:p></o:p></p>
<p class="MsoNormal">+ * will return -EAGAIN if the operation may block.<o:p></o:p></p>
<p class="MsoNormal"> */<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,<o:p></o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b src/core/ngx_output_chain.c<o:p></o:p></p>
<p class="MsoNormal">--- a/src/core/ngx_output_chain.c Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/core/ngx_output_chain.c Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -589,6 +589,20 @@<o:p></o:p></p>
<p class="MsoNormal"> if (ctx->aio_handler) {<o:p></o:p></p>
<p class="MsoNormal"> n = ngx_file_aio_read(src->file, dst->pos, (size_t) size,<o:p></o:p></p>
<p class="MsoNormal"> src->file_pos, ctx->pool);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (n > 0 && n < size) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_log_error(NGX_LOG_INFO, ctx->pool->log, 0,<o:p></o:p></p>
<p class="MsoNormal">+ ngx_read_file_n " Try again, read only %z of %O from \"%s\"",<o:p></o:p></p>
<p class="MsoNormal">+ n, size, src->file->name.data);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ src->file_pos += n;<o:p></o:p></p>
<p class="MsoNormal">+ dst->last += n;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ n = ngx_file_aio_read(src->file, dst->pos+n, (size_t) size-n,<o:p></o:p></p>
<p class="MsoNormal">+ src->file_pos, ctx->pool);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal"> if (n == NGX_AGAIN) {<o:p></o:p></p>
<p class="MsoNormal"> ctx->aio_handler(ctx, src->file);<o:p></o:p></p>
<p class="MsoNormal"> return NGX_AGAIN;<o:p></o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b src/event/modules/ngx_epoll_module.c<o:p></o:p></p>
<p class="MsoNormal">--- a/src/event/modules/ngx_epoll_module.c Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/event/modules/ngx_epoll_module.c Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -9,6 +9,10 @@<o:p></o:p></p>
<p class="MsoNormal">#include <ngx_core.h><o:p></o:p></p>
<p class="MsoNormal">#include <ngx_event.h><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">+#if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal">+#include <liburing.h><o:p></o:p></p>
<p class="MsoNormal">+#endif<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #if (NGX_TEST_BUILD_EPOLL)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">@@ -75,23 +79,6 @@<o:p></o:p></p>
<p class="MsoNormal">#define SYS_eventfd 323<o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-#if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-#define SYS_io_setup 245<o:p></o:p></p>
<p class="MsoNormal">-#define SYS_io_destroy 246<o:p></o:p></p>
<p class="MsoNormal">-#define SYS_io_getevents 247<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-typedef u_int aio_context_t;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-struct io_event {<o:p></o:p></p>
<p class="MsoNormal">- uint64_t data; /* the data field from the iocb */<o:p></o:p></p>
<p class="MsoNormal">- uint64_t obj; /* what iocb this event came from */<o:p></o:p></p>
<p class="MsoNormal">- int64_t res; /* result code for this event */<o:p></o:p></p>
<p class="MsoNormal">- int64_t res2; /* secondary result */<o:p></o:p></p>
<p class="MsoNormal">-};<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-#endif<o:p></o:p></p>
<p class="MsoNormal">#endif /* NGX_TEST_BUILD_EPOLL */<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">@@ -124,7 +111,7 @@<o:p></o:p></p>
<p class="MsoNormal"> ngx_uint_t flags);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal">-static void ngx_epoll_eventfd_handler(ngx_event_t *ev);<o:p></o:p></p>
<p class="MsoNormal">+static void ngx_epoll_io_uring_handler(ngx_event_t *ev);<o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> static void *ngx_epoll_create_conf(ngx_cycle_t *cycle);<o:p></o:p></p>
<p class="MsoNormal">@@ -141,13 +128,11 @@<o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-int ngx_eventfd = -1;<o:p></o:p></p>
<p class="MsoNormal">-aio_context_t ngx_aio_ctx = 0;<o:p></o:p></p>
<p class="MsoNormal">+struct io_uring ngx_ring;<o:p></o:p></p>
<p class="MsoNormal">+struct io_uring_params ngx_ring_params;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-static ngx_event_t ngx_eventfd_event;<o:p></o:p></p>
<p class="MsoNormal">-static ngx_connection_t ngx_eventfd_conn;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">+static ngx_event_t ngx_ring_event;<o:p></o:p></p>
<p class="MsoNormal">+static ngx_connection_t ngx_ring_conn;<o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #if (NGX_HAVE_EPOLLRDHUP)<o:p></o:p></p>
<p class="MsoNormal">@@ -217,102 +202,40 @@<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-/*<o:p></o:p></p>
<p class="MsoNormal">- * We call io_setup(), io_destroy() io_submit(), and io_getevents() directly<o:p></o:p></p>
<p class="MsoNormal">- * as syscalls instead of libaio usage, because the library header file<o:p></o:p></p>
<p class="MsoNormal">- * supports eventfd() since 0.3.107 version only.<o:p></o:p></p>
<p class="MsoNormal">- */<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-static int<o:p></o:p></p>
<p class="MsoNormal">-io_setup(u_int nr_reqs, aio_context_t *ctx)<o:p></o:p></p>
<p class="MsoNormal">-{<o:p></o:p></p>
<p class="MsoNormal">- return syscall(SYS_io_setup, nr_reqs, ctx);<o:p></o:p></p>
<p class="MsoNormal">-}<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-static int<o:p></o:p></p>
<p class="MsoNormal">-io_destroy(aio_context_t ctx)<o:p></o:p></p>
<p class="MsoNormal">-{<o:p></o:p></p>
<p class="MsoNormal">- return syscall(SYS_io_destroy, ctx);<o:p></o:p></p>
<p class="MsoNormal">-}<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-static int<o:p></o:p></p>
<p class="MsoNormal">-io_getevents(aio_context_t ctx, long min_nr, long nr, struct io_event *events,<o:p></o:p></p>
<p class="MsoNormal">- struct timespec *tmo)<o:p></o:p></p>
<p class="MsoNormal">-{<o:p></o:p></p>
<p class="MsoNormal">- return syscall(SYS_io_getevents, ctx, min_nr, nr, events, tmo);<o:p></o:p></p>
<p class="MsoNormal">-}<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">static void<o:p></o:p></p>
<p class="MsoNormal">ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">- int n;<o:p></o:p></p>
<p class="MsoNormal"> struct epoll_event ee;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-#if (NGX_HAVE_SYS_EVENTFD_H)<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd = eventfd(0, 0);<o:p></o:p></p>
<p class="MsoNormal">-#else<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd = syscall(SYS_eventfd, 0);<o:p></o:p></p>
<p class="MsoNormal">-#endif<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (ngx_eventfd == -1) {<o:p></o:p></p>
<p class="MsoNormal">+ if (io_uring_queue_init_params(32763, &ngx_ring, &ngx_ring_params) < 0) {<o:p></o:p></p>
<p class="MsoNormal"> ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "eventfd() failed");<o:p></o:p></p>
<p class="MsoNormal">- ngx_file_aio = 0;<o:p></o:p></p>
<p class="MsoNormal">- return;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,<o:p></o:p></p>
<p class="MsoNormal">- "eventfd: %d", ngx_eventfd);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- n = 1;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (ioctl(ngx_eventfd, FIONBIO, &n) == -1) {<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "ioctl(eventfd, FIONBIO) failed");<o:p></o:p></p>
<p class="MsoNormal">+ "io_uring_queue_init_params() failed");<o:p></o:p></p>
<p class="MsoNormal"> goto failed;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- if (io_setup(epcf->aio_requests, &ngx_aio_ctx) == -1) {<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "io_setup() failed");<o:p></o:p></p>
<p class="MsoNormal">- goto failed;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_event.data = &ngx_eventfd_conn;<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_event.handler = ngx_epoll_eventfd_handler;<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_event.log = cycle->log;<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_event.active = 1;<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_conn.fd = ngx_eventfd;<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_conn.read = &ngx_eventfd_event;<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd_conn.log = cycle->log;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_event.data = &ngx_ring_conn;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_event.handler = ngx_epoll_io_uring_handler;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_event.log = cycle->log;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_event.active = 1;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_conn.fd = ngx_ring.ring_fd;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_conn.read = &ngx_ring_event;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring_conn.log = cycle->log;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> ee.events = EPOLLIN|EPOLLET;<o:p></o:p></p>
<p class="MsoNormal">- ee.data.ptr = &ngx_eventfd_conn;<o:p></o:p></p>
<p class="MsoNormal">+ ee.data.ptr = &ngx_ring_conn;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- if (epoll_ctl(ep, EPOLL_CTL_ADD, ngx_eventfd, &ee) != -1) {<o:p></o:p></p>
<p class="MsoNormal">+ if (epoll_ctl(ep, EPOLL_CTL_ADD, ngx_ring.ring_fd, &ee) != -1) {<o:p></o:p></p>
<p class="MsoNormal"> return;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal"> "epoll_ctl(EPOLL_CTL_ADD, eventfd) failed");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- if (io_destroy(ngx_aio_ctx) == -1) {<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "io_destroy() failed");<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_queue_exit(&ngx_ring);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> failed:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- if (close(ngx_eventfd) == -1) {<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "eventfd close() failed");<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd = -1;<o:p></o:p></p>
<p class="MsoNormal">- ngx_aio_ctx = 0;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring.ring_fd = 0;<o:p></o:p></p>
<p class="MsoNormal"> ngx_file_aio = 0;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">@@ -549,23 +472,11 @@<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- if (ngx_eventfd != -1) {<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (io_destroy(ngx_aio_ctx) == -1) {<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "io_destroy() failed");<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (close(ngx_eventfd) == -1) {<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "eventfd close() failed");<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_eventfd = -1;<o:p></o:p></p>
<p class="MsoNormal">+ if (ngx_ring.ring_fd != 0) {<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_queue_exit(&ngx_ring);<o:p></o:p></p>
<p class="MsoNormal">+ ngx_ring.ring_fd = 0;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_aio_ctx = 0;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> ngx_free(event_list);<o:p></o:p></p>
<p class="MsoNormal">@@ -939,84 +850,36 @@<o:p></o:p></p>
<p class="MsoNormal">#if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> static void<o:p></o:p></p>
<p class="MsoNormal">-ngx_epoll_eventfd_handler(ngx_event_t *ev)<o:p></o:p></p>
<p class="MsoNormal">+ngx_epoll_io_uring_handler(ngx_event_t *ev)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">- int n, events;<o:p></o:p></p>
<p class="MsoNormal">- long i;<o:p></o:p></p>
<p class="MsoNormal">- uint64_t ready;<o:p></o:p></p>
<p class="MsoNormal">- ngx_err_t err;<o:p></o:p></p>
<p class="MsoNormal"> ngx_event_t *e;<o:p></o:p></p>
<p class="MsoNormal">+ struct io_uring_cqe *cqe;<o:p></o:p></p>
<p class="MsoNormal">+ unsigned head;<o:p></o:p></p>
<p class="MsoNormal">+ unsigned cqe_count = 0;<o:p></o:p></p>
<p class="MsoNormal"> ngx_event_aio_t *aio;<o:p></o:p></p>
<p class="MsoNormal">- struct io_event event[64];<o:p></o:p></p>
<p class="MsoNormal">- struct timespec ts;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd handler");<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- n = read(ngx_eventfd, &ready, 8);<o:p></o:p></p>
<p class="MsoNormal">+ ngx_log_debug(NGX_LOG_DEBUG_EVENT, ev->log, 0,<o:p></o:p></p>
<p class="MsoNormal">+ "io_uring_peek_cqe: START");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- err = ngx_errno;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd: %d", n);<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_for_each_cqe(&ngx_ring, head, cqe) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,<o:p></o:p></p>
<p class="MsoNormal">+ "io_event: %p %d %d",<o:p></o:p></p>
<p class="MsoNormal">+ cqe->user_data, cqe->res, cqe->flags);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- if (n != 8) {<o:p></o:p></p>
<p class="MsoNormal">- if (n == -1) {<o:p></o:p></p>
<p class="MsoNormal">- if (err == NGX_EAGAIN) {<o:p></o:p></p>
<p class="MsoNormal">- return;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">+ e = (ngx_event_t *) io_uring_cqe_get_data(cqe);<o:p></o:p></p>
<p class="MsoNormal">+ e->complete = 1;<o:p></o:p></p>
<p class="MsoNormal">+ e->active = 0;<o:p></o:p></p>
<p class="MsoNormal">+ e->ready = 1;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, ev->log, err, "read(eventfd) failed");<o:p></o:p></p>
<p class="MsoNormal">- return;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">+ aio = e->data;<o:p></o:p></p>
<p class="MsoNormal">+ aio->res = cqe->res;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,<o:p></o:p></p>
<p class="MsoNormal">- "read(eventfd) returned only %d bytes", n);<o:p></o:p></p>
<p class="MsoNormal">- return;<o:p></o:p></p>
<p class="MsoNormal">+ ++cqe_count;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ ngx_post_event(e, &ngx_posted_events);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ts.tv_sec = 0;<o:p></o:p></p>
<p class="MsoNormal">- ts.tv_nsec = 0;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- while (ready) {<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- events = io_getevents(ngx_aio_ctx, 1, 64, event, &ts);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,<o:p></o:p></p>
<p class="MsoNormal">- "io_getevents: %d", events);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (events > 0) {<o:p></o:p></p>
<p class="MsoNormal">- ready -= events;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- for (i = 0; i < events; i++) {<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ev->log, 0,<o:p></o:p></p>
<p class="MsoNormal">- "io_event: %XL %XL %L %L",<o:p></o:p></p>
<p class="MsoNormal">- event[i].data, event[i].obj,<o:p></o:p></p>
<p class="MsoNormal">- event[i].res, event[i].res2);<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- e = (ngx_event_t *) (uintptr_t) event[i].data;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- e->complete = 1;<o:p></o:p></p>
<p class="MsoNormal">- e->active = 0;<o:p></o:p></p>
<p class="MsoNormal">- e->ready = 1;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- aio = e->data;<o:p></o:p></p>
<p class="MsoNormal">- aio->res = event[i].res;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- ngx_post_event(e, &ngx_posted_events);<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- continue;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (events == 0) {<o:p></o:p></p>
<p class="MsoNormal">- return;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- /* events == -1 */<o:p></o:p></p>
<p class="MsoNormal">- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,<o:p></o:p></p>
<p class="MsoNormal">- "io_getevents() failed");<o:p></o:p></p>
<p class="MsoNormal">- return;<o:p></o:p></p>
<p class="MsoNormal">- }<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_cq_advance(&ngx_ring, cqe_count);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> #endif<o:p></o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b src/event/ngx_event.h<o:p></o:p></p>
<p class="MsoNormal">--- a/src/event/ngx_event.h Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/event/ngx_event.h Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -160,7 +160,9 @@<o:p></o:p></p>
<p class="MsoNormal"> size_t nbytes;<o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_aiocb_t aiocb;<o:p></o:p></p>
<p class="MsoNormal">+ /* Make sure that this iov has the same lifecycle with its associated aio event */<o:p></o:p></p>
<p class="MsoNormal">+ struct iovec iov;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal"> ngx_event_t event;<o:p></o:p></p>
<p class="MsoNormal">};<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b src/os/unix/ngx_linux_aio_read.c<o:p></o:p></p>
<p class="MsoNormal">--- a/src/os/unix/ngx_linux_aio_read.c Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/os/unix/ngx_linux_aio_read.c Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -9,20 +9,16 @@<o:p></o:p></p>
<p class="MsoNormal">#include <ngx_core.h><o:p></o:p></p>
<p class="MsoNormal">#include <ngx_event.h><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">+#include <liburing.h><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-extern int ngx_eventfd;<o:p></o:p></p>
<p class="MsoNormal">-extern aio_context_t ngx_aio_ctx;<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+extern struct io_uring ngx_ring;<o:p></o:p></p>
<p class="MsoNormal">+extern struct io_uring_params ngx_ring_params;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> static void ngx_file_aio_event_handler(ngx_event_t *ev);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">-static int<o:p></o:p></p>
<p class="MsoNormal">-io_submit(aio_context_t ctx, long n, struct iocb **paiocb)<o:p></o:p></p>
<p class="MsoNormal">-{<o:p></o:p></p>
<p class="MsoNormal">- return syscall(SYS_io_submit, ctx, n, paiocb);<o:p></o:p></p>
<p class="MsoNormal">-}<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> ngx_int_t<o:p></o:p></p>
<p class="MsoNormal">ngx_file_aio_init(ngx_file_t *file, ngx_pool_t *pool)<o:p></o:p></p>
<p class="MsoNormal">@@ -50,10 +46,10 @@<o:p></o:p></p>
<p class="MsoNormal">ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,<o:p></o:p></p>
<p class="MsoNormal"> ngx_pool_t *pool)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">- ngx_err_t err;<o:p></o:p></p>
<p class="MsoNormal">- struct iocb *piocb[1];<o:p></o:p></p>
<p class="MsoNormal">- ngx_event_t *ev;<o:p></o:p></p>
<p class="MsoNormal">- ngx_event_aio_t *aio;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_err_t err;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_event_t *ev;<o:p></o:p></p>
<p class="MsoNormal">+ ngx_event_aio_t *aio;<o:p></o:p></p>
<p class="MsoNormal">+ struct io_uring_sqe *sqe;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (!ngx_file_aio) {<o:p></o:p></p>
<p class="MsoNormal"> return ngx_read_file(file, buf, size, offset);<o:p></o:p></p>
<p class="MsoNormal">@@ -93,22 +89,41 @@<o:p></o:p></p>
<p class="MsoNormal"> return NGX_ERROR;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- ngx_memzero(&aio->aiocb, sizeof(struct iocb));<o:p></o:p></p>
<p class="MsoNormal">+ sqe = io_uring_get_sqe(&ngx_ring);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+ if (!sqe) {<o:p></o:p></p>
<p class="MsoNormal">+ ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,<o:p></o:p></p>
<p class="MsoNormal">+ "aio no sqe left:%d @%O:%uz %V",<o:p></o:p></p>
<p class="MsoNormal">+ ev->complete, offset, size, &file->name);<o:p></o:p></p>
<p class="MsoNormal">+ return ngx_read_file(file, buf, size, offset);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_fildes = file->fd;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_nbytes = size;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_offset = offset;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_flags = IOCB_FLAG_RESFD;<o:p></o:p></p>
<p class="MsoNormal">- aio->aiocb.aio_resfd = ngx_eventfd;<o:p></o:p></p>
<p class="MsoNormal">+ if (__builtin_expect(!!(ngx_ring_params.features & IORING_FEAT_CUR_PERSONALITY), 1)) {<o:p></o:p></p>
<p class="MsoNormal">+ /*<o:p></o:p></p>
<p class="MsoNormal">+ * `io_uring_prep_read` is faster than `io_uring_prep_readv`, because the kernel<o:p></o:p></p>
<p class="MsoNormal">+ * doesn't need to import iovecs in advance.<o:p></o:p></p>
<p class="MsoNormal">+ *<o:p></o:p></p>
<p class="MsoNormal">+ * If the kernel supports `IORING_FEAT_CUR_PERSONALITY`, it should support<o:p></o:p></p>
<p class="MsoNormal">+ * non-vectored read/write commands too.<o:p></o:p></p>
<p class="MsoNormal">+ *<o:p></o:p></p>
<p class="MsoNormal">+ * It's not perfect, but avoids an extra feature-test syscall.<o:p></o:p></p>
<p class="MsoNormal">+ */<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_prep_read(sqe, file->fd, buf, size, offset);<o:p></o:p></p>
<p class="MsoNormal">+ } else {<o:p></o:p></p>
<p class="MsoNormal">+ /*<o:p></o:p></p>
<p class="MsoNormal">+ * We must store iov into heap to prevent kernel from returning -EFAULT<o:p></o:p></p>
<p class="MsoNormal">+ * in case `IORING_FEAT_SUBMIT_STABLE` is not supported<o:p></o:p></p>
<p class="MsoNormal">+ */<o:p></o:p></p>
<p class="MsoNormal">+ aio->iov.iov_base = buf;<o:p></o:p></p>
<p class="MsoNormal">+ aio->iov.iov_len = size;<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_prep_readv(sqe, file->fd, &aio->iov, 1, offset);<o:p></o:p></p>
<p class="MsoNormal">+ }<o:p></o:p></p>
<p class="MsoNormal">+ io_uring_sqe_set_data(sqe, ev);<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> ev->handler = ngx_file_aio_event_handler;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">- piocb[0] = &aio->aiocb;<o:p></o:p></p>
<p class="MsoNormal">-<o:p></o:p></p>
<p class="MsoNormal">- if (io_submit(ngx_aio_ctx, 1, piocb) == 1) {<o:p></o:p></p>
<p class="MsoNormal">+ if (io_uring_submit(&ngx_ring) == 1) {<o:p></o:p></p>
<p class="MsoNormal"> ev->active = 1;<o:p></o:p></p>
<p class="MsoNormal"> ev->ready = 0;<o:p></o:p></p>
<p class="MsoNormal"> ev->complete = 0;<o:p></o:p></p>
<p class="MsoNormal">diff -r 82228f955153 -r 3677cf19b98b src/os/unix/ngx_linux_config.h<o:p></o:p></p>
<p class="MsoNormal">--- a/src/os/unix/ngx_linux_config.h Tue Dec 15 17:41:39 2020 +0300<o:p></o:p></p>
<p class="MsoNormal">+++ b/src/os/unix/ngx_linux_config.h Mon Jan 11 08:07:14 2021 -0500<o:p></o:p></p>
<p class="MsoNormal">@@ -93,10 +93,6 @@<o:p></o:p></p>
<p class="MsoNormal">#include <sys/eventfd.h><o:p></o:p></p>
<p class="MsoNormal">#endif<o:p></o:p></p>
<p class="MsoNormal">#include <sys/syscall.h><o:p></o:p></p>
<p class="MsoNormal">-#if (NGX_HAVE_FILE_AIO)<o:p></o:p></p>
<p class="MsoNormal">-#include <linux/aio_abi.h><o:p></o:p></p>
<p class="MsoNormal">-typedef struct iocb ngx_aiocb_t;<o:p></o:p></p>
<p class="MsoNormal">-#endif<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> #if (NGX_HAVE_CAPABILITIES)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>