[PATCH 2 of 4] Simplified sendfile_max_chunk handling

Sergey Kandaurov pluknet at nginx.com
Wed Oct 27 14:19:19 UTC 2021


> On 11 Oct 2021, at 21:58, Maxim Dounin <mdounin at mdounin.ru> wrote:
> 
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1633978587 -10800
> #      Mon Oct 11 21:56:27 2021 +0300
> # Node ID 489323e194e4c3b1a7937c51bd4e1671c70f52f8
> # Parent  d175cd09ac9d2bab7f7226eac3bfce196a296cc0
> Simplified sendfile_max_chunk handling.
> 
> Previously, it was checked that sendfile_max_chunk was enabled and
> almost whole sendfile_max_chunk was sent (see e67ef50c3176), to avoid
> delaying connections where sendfile_max_chunk wasn't reached (for example,
> when sending responses smaller than sendfile_max_chunk).  Now we instead
> check if there are unsent data, and the connection is still ready for writing.
> Additionally we also check c->write->delayed to ignore connections already
> delayed by limit_rate.
> 
> This approach is believed to be more robust, and correctly handles
> not only sendfile_max_chunk, but also internal limits of c->send_chain(),
> such as sendfile() maximum supported length (ticket #1870).
> 
> diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
> --- a/src/http/ngx_http_write_filter_module.c
> +++ b/src/http/ngx_http_write_filter_module.c
> @@ -321,16 +321,12 @@ ngx_http_write_filter(ngx_http_request_t
>         delay = (ngx_msec_t) ((nsent - sent) * 1000 / r->limit_rate);
> 
>         if (delay > 0) {
> -            limit = 0;
>             c->write->delayed = 1;
>             ngx_add_timer(c->write, delay);
>         }
>     }
> 
> -    if (limit
> -        && c->write->ready
> -        && c->sent - sent >= limit - (off_t) (2 * ngx_pagesize))
> -    {
> +    if (chain && c->write->ready && !c->write->delayed) {
>         ngx_post_event(c->write, &ngx_posted_next_events);
>     }
> 

Looks good.

Not strictly related to this change, so FYI.  I noticed a stray writev()
after Linux sendfile(), when it writes more than its internal limits.

2021/10/27 12:44:34 [debug] 1462058#0: *1 write old buf t:0 f:1 0000000000000000,
 pos 0000000000000000, size: 0 file: 416072437, size: 3878894859
2021/10/27 12:44:34 [debug] 1462058#0: *1 http write filter: l:1 f:0 s:3878894859
2021/10/27 12:44:34 [debug] 1462058#0: *1 http write filter limit 0
2021/10/27 12:44:34 [debug] 1462058#0: *1 sendfile: @416072437 2147482891
2021/10/27 12:44:34 [debug] 1462058#0: *1 sendfile: 2147479552 of 2147482891 @416072437
2021/10/27 12:44:34 [debug] 1462058#0: *1 writev: 0 of 0
2021/10/27 12:44:34 [debug] 1462058#0: *1 http write filter 0000561528695820
2021/10/27 12:44:34 [debug] 1462058#0: *1 post event 00005615289C2310

Here sendfile() partially sent 2147479552, which is above its internal
limit NGX_SENDFILE_MAXSIZE - ngx_pagesize.  On the second iteration,
due to this, it falls back to writev() with zero-size headers.
Then, with the patch applied, it posts the next write event, as designed
(previously, it would seemingly stuck instead, such as in ticket #1870).

-- 
Sergey Kandaurov



More information about the nginx-devel mailing list