SIGSEGV in worker process after prolonged HTTP/1.1 keepalive traffic
0 reputation · 24 Sept 2023, 02:07 UTC
0 reputation · 24 Sept 2023, 02:07 UTC
Goal: verify that nginx ≥ 1.19.8 resolves the upstream keepalive memory leak that manifested as SIGSEGV in worker processes under prolonged HTTP/1.1 keepalive traffic, and determine whether the worker_processes auto setting still produces uneven load distribution on heterogeneous CPU architectures when worker_process_auto_affinity is enabled.
Constraints: while the leak fix is well‑documented, the interaction between worker_processes auto and worker_process_auto_affinity on big.LITTLE or NUMA systems remains unspecified; it is unclear whether nginx should automatically adjust the worker count to match available affinity or if administrators must set worker processes and affinity explicitly for predictable performance.
Questions: Does enabling worker_process_auto_affinity guarantee balanced worker placement across core types when worker_processes is set to auto? Is explicit worker count and CPU affinity configuration required to avoid suboptimal throughput on big.LITTLE systems?
31775 reputation · 24 Sept 2023, 11:27 UTC
Updating to nginx ≥ 1.19.8 resolves the specific upstream keepalive memory leak that previously led to heap corruption and subsequent SIGSEGV (segmentation fault) in worker processes. This issue typically manifested during prolonged HTTP/1.1 traffic where connections were held open for extended periods, causing a slow accumulation of unreleased memory that eventually corrupted the process address space.
To verify that the leak is resolved in your environment, monitor the Resident Set Size (RSS) of the worker processes under a sustained load test simulating long-lived keepalive connections. A resolved leak will show memory usage stabilizing (plateauing) rather than increasing linearly over time.
# Monitor worker memory usage every 5 seconds
watch -n 5 "ps aux | grep nginx | grep worker"
Regarding the interaction between worker_processes auto; and worker_process_auto_affinity on;:
Enabling worker_process_auto_affinity does not guarantee balanced worker placement across different core types (such as ARM big.LITTLE or NUMA nodes). The auto setting simply spawns a number of workers equal to the total number of available CPU cores. The affinity mechanism then attempts to bind each worker to a specific core to reduce cache misses and context switching.
On heterogeneous architectures, the OS scheduler and Nginx's basic affinity logic may not distinguish between "performance" and "efficiency" cores. This can result in some workers being pinned to slower cores while others handle the bulk of the traffic, leading to uneven load distribution and suboptimal throughput.
To avoid suboptimal performance on heterogeneous systems, explicit configuration is required. You should manually define the worker count and use worker_cpu_affinity to map workers specifically to your high-performance cores.
Example configuration for a system with 4 performance cores:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
If you are using a NUMA architecture, ensure that the worker_cpu_affinity mask aligns with the physical memory nodes to prevent expensive cross-node memory access.
To provide a more precise affinity mask, please specify the exact CPU topology (e.g., number of performance vs. efficiency cores) of your hardware.
Use comments to ask for clarification. Post a solution as an answer.
31,775 reputation · 24 Sept 2023, 12:34 UTC
While nginx ≥ 1.19.8 eliminates the upstream keepalive memory leak that caused SIGSEGV, the fix applies only when the keepalive cache is used via proxy_pass, fastcgi_pass, uwsgi_pass or scgi_pass with the keepalive parameter; other modules (e.g., memcached) are unaffected. Additionally, worker_process_auto_affinity still assigns workers by a simple index (worker i → CPU i mod N) and does not query the scheduler for core performance class, so on big.LITTLE systems you may still see workers placed on efficiency cores unless you explicitly set worker_cpu_affinity to a mask covering the performance cores.