[PATCH] HTTP/2: fixed sendfile() aio handling
Sergey Kandaurov
pluknet at nginx.com
Thu Nov 25 17:42:59 UTC 2021
> On 25 Nov 2021, at 16:54, Maxim Dounin <mdounin at mdounin.ru> wrote:
>
> Hello!
>
> On Thu, Nov 25, 2021 at 04:15:09PM +0300, Sergey Kandaurov wrote:
>
[ trim ]
>> BTW, what about a similar check in ngx_freebsd_sendfile_chain()
>> used to catch duplicate calls? Both were added in 6422:768e287a6f36.
>> Anyway, it is removed in the sendfile(SF_NODISKIO) rework.
>
> Yes, thanks, missed this, fixed. Also fixed wrong return value in
> the preload handler (it is expected to be ssize_t and match
> ngx_file_aio_read() result, so using NGX_OK is misleading, replaced
> with NGX_AGAIN).
>
> Diff:
>
> diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
> --- a/src/http/ngx_http_copy_filter_module.c
> +++ b/src/http/ngx_http_copy_filter_module.c
> @@ -230,7 +230,7 @@ ngx_http_copy_aio_sendfile_preload(ngx_b
> * a write event on the main connection
> */
>
> - return NGX_OK;
> + return NGX_AGAIN;
> }
>
Indeed, nice catch.
> n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL);
> diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
> --- a/src/os/unix/ngx_freebsd_sendfile_chain.c
> +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
> @@ -255,19 +255,6 @@ ngx_freebsd_sendfile_chain(ngx_connectio
> #if (NGX_HAVE_AIO_SENDFILE)
>
> if (ebusy) {
> - if (aio->event.active) {
> - /*
> - * tolerate duplicate calls; they can happen due to subrequests
> - * or multiple calls of the next body filter from a filter
> - */
> -
> - if (sent) {
> - c->busy_count = 0;
> - }
> -
> - return in;
> - }
> -
> if (sent == 0) {
> c->busy_count++;
>
>
With the above adjustment, this part looks good.
> Full patch:
>
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1637847703 -10800
> # Thu Nov 25 16:41:43 2021 +0300
> # Node ID c960e182900a8d0b7f3041731ba416f2c7e69d14
> # Parent 3443c02ca1d183fe52bf8af66627c94be2b2f785
> HTTP/2: fixed "task already active" with sendfile in threads.
>
> With sendfile in threads, "task already active" alerts might appear in logs
> if a write event happens on the main HTTP/2 connection, triggering a sendfile
> in threads while another thread operation is already running. Observed
> with "aio threads; aio_write on; sendfile on;" and with thread event handlers
> modified to post a write event to the main HTTP/2 connection (though can
> happen without any modifications).
>
> Similarly, sendfile() with AIO preloading on FreeBSD can trigger duplicate
> aio operation, resulting in "second aio post" alerts. This is, however,
> harder to reproduce, especially on modern FreeBSD systems, since sendfile()
> usually does not return EBUSY.
>
> Fix is to avoid starting a sendfile operation if other thread operation
> is active by checking r->aio in the thread handler (and, similarly, in
> aio preload handler). The added check also makes duplicate calls protection
> redundant, so it is removed.
>
> [..]
Overall, it looks good.
--
Sergey Kandaurov
More information about the nginx-devel
mailing list