> On 11 Nov 2021, at 07:21, Maxim Dounin <mdou...@mdounin.ru> wrote: > > # HG changeset patch > # User Maxim Dounin <mdou...@mdounin.ru> > # Date 1636603886 -10800 > # Thu Nov 11 07:11:26 2021 +0300 > # Node ID 4a954e89b1ae8539bbe08c5afc1d5c9828d82d6f > # Parent 0fb75ef9dbca698e5e855145cf6a12180a36d400 > Simplified sendfile(SF_NODISKIO) usage. > > Starting with FreeBSD 11, there is no need to use AIO operations to preload > data into cache for sendfile(SF_NODISKIO) to work. Instead, sendfile() > handles non-blocking loading data from disk by itself. It still can, however, > return EBUSY if a page is already being loaded (for example, by a different > process). If this happens, we now post an event for the next event loop > iteration, so sendfile() is retried "after a short period", as manpage > recommends. > > The limit of the number of EBUSY tolerated without any progress is preserved, > but now it does not result in an alert, since on an idle system event loop > iteration might be very short and EBUSY can happen many times in a row. > Instead, SF_NODISKIO is simply disabled for one call once the limit is > reached. > > With this change, sendfile(SF_NODISKIO) is now used automatically as long as > sendfile() is enabled, and no longer requires "aio on;". >
Updated on top of the tip (a7a77549265e). diff -r 40098a93d224 -r 1078530b0e99 auto/os/freebsd --- a/auto/os/freebsd Thu Nov 11 06:10:55 2021 +0300 +++ b/auto/os/freebsd Thu Nov 11 07:11:26 2021 +0300 @@ -44,12 +44,10 @@ CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS" fi -if [ $NGX_FILE_AIO = YES ]; then - if [ $osreldate -gt 502103 ]; then - echo " + sendfile()'s SF_NODISKIO found" +if [ $osreldate -gt 1100000 ]; then + echo " + sendfile()'s SF_NODISKIO found" - have=NGX_HAVE_AIO_SENDFILE . auto/have - fi + have=NGX_HAVE_SENDFILE_NODISKIO . auto/have fi # POSIX semaphores diff -r 40098a93d224 -r 1078530b0e99 src/core/ngx_buf.h --- a/src/core/ngx_buf.h Thu Nov 11 06:10:55 2021 +0300 +++ b/src/core/ngx_buf.h Thu Nov 11 07:11:26 2021 +0300 @@ -90,9 +90,6 @@ #if (NGX_HAVE_FILE_AIO || NGX_COMPAT) ngx_output_chain_aio_pt aio_handler; -#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) - ssize_t (*aio_preload)(ngx_buf_t *file); -#endif #endif #if (NGX_THREADS || NGX_COMPAT) diff -r 40098a93d224 -r 1078530b0e99 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Thu Nov 11 06:10:55 2021 +0300 +++ b/src/core/ngx_connection.h Thu Nov 11 07:11:26 2021 +0300 @@ -185,7 +185,7 @@ unsigned need_last_buf:1; -#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) +#if (NGX_HAVE_SENDFILE_NODISKIO || NGX_COMPAT) unsigned busy_count:2; #endif diff -r 40098a93d224 -r 1078530b0e99 src/core/ngx_module.h --- a/src/core/ngx_module.h Thu Nov 11 06:10:55 2021 +0300 +++ b/src/core/ngx_module.h Thu Nov 11 07:11:26 2021 +0300 @@ -41,7 +41,7 @@ #define NGX_MODULE_SIGNATURE_3 "0" #endif -#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) +#if (NGX_HAVE_SENDFILE_NODISKIO || NGX_COMPAT) #define NGX_MODULE_SIGNATURE_4 "1" #else #define NGX_MODULE_SIGNATURE_4 "0" diff -r 40098a93d224 -r 1078530b0e99 src/core/ngx_output_chain.c --- a/src/core/ngx_output_chain.c Thu Nov 11 06:10:55 2021 +0300 +++ b/src/core/ngx_output_chain.c Thu Nov 11 07:11:26 2021 +0300 @@ -29,10 +29,6 @@ static ngx_inline ngx_int_t ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf); -#if (NGX_HAVE_AIO_SENDFILE) -static ngx_int_t ngx_output_chain_aio_setup(ngx_output_chain_ctx_t *ctx, - ngx_file_t *file); -#endif static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in); static ngx_int_t ngx_output_chain_align_file_buf(ngx_output_chain_ctx_t *ctx, @@ -283,12 +279,6 @@ buf->in_file = 0; } -#if (NGX_HAVE_AIO_SENDFILE) - if (ctx->aio_preload && buf->in_file) { - (void) ngx_output_chain_aio_setup(ctx, buf->file); - } -#endif - if (ctx->need_in_memory && !ngx_buf_in_memory(buf)) { return 0; } @@ -301,28 +291,6 @@ } -#if (NGX_HAVE_AIO_SENDFILE) - -static ngx_int_t -ngx_output_chain_aio_setup(ngx_output_chain_ctx_t *ctx, ngx_file_t *file) -{ - ngx_event_aio_t *aio; - - if (file->aio == NULL && ngx_file_aio_init(file, ctx->pool) != NGX_OK) { - return NGX_ERROR; - } - - aio = file->aio; - - aio->data = ctx->filter_ctx; - aio->preload_handler = ctx->aio_preload; - - return NGX_OK; -} - -#endif - - static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in) diff -r 40098a93d224 -r 1078530b0e99 src/event/ngx_event.h --- a/src/event/ngx_event.h Thu Nov 11 06:10:55 2021 +0300 +++ b/src/event/ngx_event.h Thu Nov 11 07:11:26 2021 +0300 @@ -147,10 +147,6 @@ ngx_fd_t fd; -#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT) - ssize_t (*preload_handler)(ngx_buf_t *file); -#endif - #if (NGX_HAVE_EVENTFD) int64_t res; #endif diff -r 40098a93d224 -r 1078530b0e99 src/http/ngx_http_copy_filter_module.c --- a/src/http/ngx_http_copy_filter_module.c Thu Nov 11 06:10:55 2021 +0300 +++ b/src/http/ngx_http_copy_filter_module.c Thu Nov 11 07:11:26 2021 +0300 @@ -19,10 +19,6 @@ static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, ngx_file_t *file); static void ngx_http_copy_aio_event_handler(ngx_event_t *ev); -#if (NGX_HAVE_AIO_SENDFILE) -static ssize_t ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file); -static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev); -#endif #endif #if (NGX_THREADS) static ngx_int_t ngx_http_copy_thread_handler(ngx_thread_task_t *task, @@ -128,9 +124,6 @@ #if (NGX_HAVE_FILE_AIO) if (ngx_file_aio && clcf->aio == NGX_HTTP_AIO_ON) { ctx->aio_handler = ngx_http_copy_aio_handler; -#if (NGX_HAVE_AIO_SENDFILE) - ctx->aio_preload = ngx_http_copy_aio_sendfile_preload; -#endif } #endif @@ -207,81 +200,6 @@ ngx_http_run_posted_requests(c); } - -#if (NGX_HAVE_AIO_SENDFILE) - -static ssize_t -ngx_http_copy_aio_sendfile_preload(ngx_buf_t *file) -{ - ssize_t n; - static u_char buf[1]; - ngx_event_aio_t *aio; - ngx_http_request_t *r; - ngx_output_chain_ctx_t *ctx; - - aio = file->file->aio; - r = aio->data; - - if (r->aio) { - /* - * tolerate sendfile() calls if another operation is already - * running; this can happen due to subrequests, multiple calls - * of the next body filter from a filter, or in HTTP/2 due to - * a write event on the main connection - */ - - return NGX_AGAIN; - } - - n = ngx_file_aio_read(file->file, buf, 1, file->file_pos, NULL); - - if (n == NGX_AGAIN) { - aio->handler = ngx_http_copy_aio_sendfile_event_handler; - - r->main->blocked++; - r->aio = 1; - - ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); - ctx->aio = 1; - } - - return n; -} - - -static void -ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev) -{ - ngx_event_aio_t *aio; - ngx_connection_t *c; - ngx_http_request_t *r; - - aio = ev->data; - r = aio->data; - c = r->connection; - - r->main->blocked--; - r->aio = 0; - ev->complete = 0; - -#if (NGX_HTTP_V2) - - if (r->stream) { - /* - * for HTTP/2, update write event to make sure processing will - * reach the main connection to handle sendfile() preload - */ - - c->write->ready = 1; - c->write->active = 0; - } - -#endif - - c->write->handler(c->write); -} - -#endif #endif diff -r 40098a93d224 -r 1078530b0e99 src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c Thu Nov 11 06:10:55 2021 +0300 +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c Thu Nov 11 07:11:26 2021 +0300 @@ -32,22 +32,21 @@ ngx_chain_t * ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { - int rc, flags; - off_t send, prev_send, sent; - size_t file_size; - ssize_t n; - ngx_uint_t eintr, eagain; - ngx_err_t err; - ngx_buf_t *file; - ngx_event_t *wev; - ngx_chain_t *cl; - ngx_iovec_t header, trailer; - struct sf_hdtr hdtr; - struct iovec headers[NGX_IOVS_PREALLOCATE]; - struct iovec trailers[NGX_IOVS_PREALLOCATE]; -#if (NGX_HAVE_AIO_SENDFILE) - ngx_uint_t ebusy; - ngx_event_aio_t *aio; + int rc, flags; + off_t send, prev_send, sent; + size_t file_size; + ssize_t n; + ngx_uint_t eintr, eagain; + ngx_err_t err; + ngx_buf_t *file; + ngx_event_t *wev; + ngx_chain_t *cl; + ngx_iovec_t header, trailer; + struct sf_hdtr hdtr; + struct iovec headers[NGX_IOVS_PREALLOCATE]; + struct iovec trailers[NGX_IOVS_PREALLOCATE]; +#if (NGX_HAVE_SENDFILE_NODISKIO) + ngx_uint_t ebusy; #endif wev = c->write; @@ -77,11 +76,6 @@ eagain = 0; flags = 0; -#if (NGX_HAVE_AIO_SENDFILE && NGX_SUPPRESS_WARN) - aio = NULL; - file = NULL; -#endif - header.iovs = headers; header.nalloc = NGX_IOVS_PREALLOCATE; @@ -90,7 +84,7 @@ for ( ;; ) { eintr = 0; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_SENDFILE_NODISKIO) ebusy = 0; #endif prev_send = send; @@ -179,9 +173,8 @@ sent = 0; -#if (NGX_HAVE_AIO_SENDFILE) - aio = file->file->aio; - flags = (aio && aio->preload_handler) ? SF_NODISKIO : 0; +#if (NGX_HAVE_SENDFILE_NODISKIO) + flags = (c->busy_count <= 2) ? SF_NODISKIO : 0; #endif rc = sendfile(file->file->fd, c->fd, file->file_pos, @@ -199,7 +192,7 @@ eintr = 1; break; -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_SENDFILE_NODISKIO) case NGX_EBUSY: ebusy = 1; break; @@ -252,41 +245,30 @@ in = ngx_chain_update_sent(in, sent); -#if (NGX_HAVE_AIO_SENDFILE) +#if (NGX_HAVE_SENDFILE_NODISKIO) if (ebusy) { if (sent == 0) { c->busy_count++; - if (c->busy_count > 2) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, - "sendfile(%V) returned busy again", - &file->file->name); - - c->busy_count = 0; - aio->preload_handler = NULL; - - send = prev_send; - continue; - } + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "sendfile() busy, count:%d", c->busy_count); } else { c->busy_count = 0; } - n = aio->preload_handler(file); - - if (n > 0) { - send = prev_send + sent; - continue; + if (wev->posted) { + ngx_delete_posted_event(wev); } + ngx_post_event(wev, &ngx_posted_next_events); + + wev->ready = 0; return in; } - if (flags == SF_NODISKIO) { - c->busy_count = 0; - } + c->busy_count = 0; #endif -- Sergey Kandaurov _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel