From 1c59ff16d3c24ddc5ac8f5735f352aefecb763be Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 26 Sep 2025 21:59:04 +0100 Subject: [PATCH] Better available cpu count determination. With 'worker_processes auto;' the number of worker processes to create is generally determined at runtime via sysconf(_SC_NPROCESSORS_ONLN); However this value does not take into account any restrictions that have been put in place via mechanisms like cpuset(7)'s and/or sched_setaffinity(2). So for example while a system may have 18 "cpus" available as returned via sysconf(_SC_NPROCESSORS_ONLN) the actual number of allowed to run on cpus may be much lower. E.g. On a 18 core system, with 'worker_processes auto;' nginx will create 18 worker processes (+ the master). E.g. $ pgrep -c nginx 19 If however nginx has been restricted to run on just four. We will still create 18 worker processes. E.g. $ taskset -a -c 0-3 ./sbin/nginx -c conf/minimal.conf $ pgrep -c nginx 19 This can happen for example with 'docker --cpuset-cpus=', where you may end up with many more worker processes than runnable cpus. This commit uses sched_getaffinity() (where available, at least Linux & FreeBSD) to determine the number of actual available runnable cpus. So in the above example we now get $ taskset -a -c 0-3 ./sbin/nginx -c conf/minimal.conf $ pgrep -c nginx 5 Four worker processes plus the master. Closes: https://github.com/nginx/nginx/issues/855 --- src/os/unix/ngx_posix_init.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c index 6ac931c0c..0d1ecf928 100644 --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -64,6 +64,28 @@ ngx_os_init(ngx_log_t *log) } #endif +#if (NGX_HAVE_SCHED_GETAFFINITY) + if (ngx_ncpu > 0) { + int err; + size_t sz; + cpu_set_t *mask; + + mask = CPU_ALLOC(ngx_ncpu); + if (mask == NULL) { + return NGX_ERROR; + } + + sz = CPU_ALLOC_SIZE(ngx_ncpu); + + err = sched_getaffinity(0, sz, mask); + if (err == 0) { + ngx_ncpu = CPU_COUNT_S(sz, mask); + } + + CPU_FREE(mask); + } +#endif + if (ngx_ncpu < 1) { ngx_ncpu = 1; }