<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;}
span.EmailStyle19
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.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">There’s a typo in the mail:<o:p></o:p></p>
<p class="MsoNormal">Test with wrk with 100 threads 200 connections(-t 100 -c <span style="background:yellow;mso-highlight:yellow">
1000</span>) with 25000 random requests.<o:p></o:p></p>
<p class="MsoNormal">Should be “<span style="background:yellow;mso-highlight:yellow">-c 200</span>”. In fact with -c 1000, io_uring performance gain is even more significant because libaio performance drop more with 1000 connections than 200 connections.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Regards,<o:p></o:p></p>
<p class="MsoNormal">Ping<o:p></o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> nginx-devel <nginx-devel-bounces@nginx.org> <b>
On Behalf Of </b>Zhao, Ping<br>
<b>Sent:</b> Monday, January 11, 2021 3:05 PM<br>
<b>To:</b> nginx-devel@nginx.org<br>
<b>Subject:</b> [PATCH] Use io_uring for async io access<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<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>