Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

cpu-policy directives are ignored on FreeBSD/non-Linux platforms(?), falling back to 1 thread

Đang mở
#3,456 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
28/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
c, linux

Hướng nghiên cứu

Grep for 'cpu-policy' and 'cpu_detect' in src/ and doc/configuration.txt: Linux topology discovery reads /sys, while the generic path only fetches the total CPU count and leaves one thread. Read the global-section parser and the code that applies the policy to see where it silently no-ops when nbthread is unset. The short-term goal is a fatal config error at parse time pointing at cpu-map; done means 'haproxy -c' fails on FreeBSD or the thread count matches the topology.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

status: needs-triage type: bug
Detailed Description of the Problem

The cpu-policy directive (e.g., cpu-policy performance threads-per-core 1) does not work as expected on FreeBSD. Instead of automatically discovering the CPU topology and scaling the threads accordingly, HAProxy falls back to creating only a single thread.

Based on the core developer discussion in GitHub Discussion #2901, automatic CPU topology detection via /sys is currently implemented exclusively for Linux. On FreeBSD and macOS, HAProxy only fetches the total CPU count. However, instead of applying a reasonable thread allocation policy based on the available hardware limits, the parser silently ignores the directive or fails to scale, defaulting to 1 worker thread unless nbthread is explicitly defined.This likely affects all non-Linux platforms (FreeBSD, macOS, OpenBSD, NetBSD).

Expected Behavior
  1. Short-term mitigation (Fail-fast validation):Until a proper topology detection mechanism is implemented for this platform, HAProxy should trigger a fatal configuration error during startup or config parsing, such as:
[ALERT] (xxxx) : config : 'cpu-policy' is not implemented on this platform yet, please use 'cpu-map' instead.
  1. Ideal long-term solution:Ideally, this feature should function exactly as documented on non-Linux platforms, correctly leveraging the available operating system APIs to detect and utilize all available physical CPU cores.
Steps to Reproduce the Behavior

/usr/local/etc/haproxy.cfg sample:

global
    #nbthread 12
    cpu-policy performance threads-per-core 1
    log /var/run/log local0
    chroot /
    user nobody
    group nobody
    daemon

defaults
    log     global
    mode    http
    timeout connect 5s
    timeout client  50s
    timeout server  50s

frontend https_front
    bind 0.0.0.0:80
    default_backend echo_backend

backend echo_backend
    balance roundrobin
    server backend_server 172.16.0.1:80 id 1 check
haproxy -f /usr/local/etc/haproxy.cfg

Even when generating high multi-threaded load against the load balancer, running top -H confirms that HAProxy utilizes only a single CPU core:

h1load -d 60 -c 200 -t 24 -r 1 -P http://172.160.91:80
Do you have any idea what may have caused this?

No response

Do you have an idea how to solve the issue?

No response

What is your configuration?
Environment:

OS: FreeBSD 15.1-RELEASE-p1 (amd64)
Hardware: AMD Ryzen 9 3900X 12-Core Processor (24 threads with SMT enabled)

% sysctl hw.ncpu hw.model

hw.ncpu: 24
hw.model: AMD Ryzen 9 3900X 12-Core Processor


sysctl -qn kern.sched.topology_spec:

<groups>
 <group level="1" cache-level="0">
  <cpu count="24" mask="ffffff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23</cpu>
  <children>
   <group level="2" cache-level="3">
    <cpu count="6" mask="3f,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">0, 1, 2, 3, 4, 5</cpu>
    <children>
     <group level="3" cache-level="2">
      <cpu count="2" mask="3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">0, 1</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="c,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">2, 3</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">4, 5</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
    </children>
   </group>
   <group level="2" cache-level="3">
    <cpu count="6" mask="fc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">6, 7, 8, 9, 10, 11</cpu>
    <children>
     <group level="3" cache-level="2">
      <cpu count="2" mask="c0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">6, 7</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">8, 9</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="c00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">10, 11</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
    </children>
   </group>
   <group level="2" cache-level="3">
    <cpu count="6" mask="3f000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">12, 13, 14, 15, 16, 17</cpu>
    <children>
     <group level="3" cache-level="2">
      <cpu count="2" mask="3000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">12, 13</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="c000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">14, 15</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="30000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">16, 17</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
    </children>
   </group>
   <group level="2" cache-level="3">
    <cpu count="6" mask="fc0000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">18, 19, 20, 21, 22, 23</cpu>
    <children>
     <group level="3" cache-level="2">
      <cpu count="2" mask="c0000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">18, 19</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="300000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">20, 21</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
     <group level="3" cache-level="2">
      <cpu count="2" mask="c00000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0">22, 23</cpu>
      <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
     </group>
    </children>
   </group>
  </children>
 </group>
</groups>
Output of haproxy -vv
haproxy -vv
HAProxy version 3.4.1-3e888a769 2026/06/25 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2031.
Known bugs: http://www.haproxy.org/bugs/bugs-3.4.1.html
Running on: FreeBSD 15.1-RELEASE-p1 FreeBSD 15.1-RELEASE-p1 releng/15.1-0f691888dc56 GENERIC amd64
Build options : 
  TARGET  = freebsd
  CC      = cc
  CFLAGS  = -O2 -g -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -fwrapv -DFREEBSD_PORTS
  OPTIONS = USE_GETADDRINFO=1 USE_OPENSSL=1 USE_ACCEPT4=1 USE_ZLIB=1 USE_CPU_AFFINITY=1 USE_TFO=1 USE_THREAD_DUMP=1 USE_QUIC=1 USE_PROMEX=1 USE_PCRE2=1 USE_PCRE2_JIT=1
  DEBUG   = 

Feature list : -51DEGREES +ACCEPT4 +ACME -BACKTRACE +CLOSEFROM +CPU_AFFINITY -CRYPT_H -DEVICEATLAS -DL -ECH -ENGINE -EPOLL -EVPORTS +GETADDRINFO +KQUEUE -KTLS -LIBATOMIC +LIBCRYPT -LINUX_CAP -LINUX_SPLICE -LINUX_TPROXY -LUA -MATH -MEMORY_PROFILING -NETFILTER -NS -OBSOLETE_LINKER +OPENSSL -OPENSSL_AWSLC -OPENSSL_WOLFSSL -OT -PCRE +PCRE2 +PCRE2_JIT -PCRE_JIT +POLL -PRCTL +PROCCTL +PROMEX -PTHREAD_EMULATION +QUIC -QUIC_OPENSSL_COMPAT -RT -SHM_OPEN -SLZ +SSL -STATIC_PCRE -STATIC_PCRE2 +TFO +THREAD +THREAD_DUMP +TPROXY +TRACE -WURFL +ZLIB
Detected feature list :

Default settings :
  bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with multi-threading support (MAX_TGROUPS=32, MAX_THREADS=1024, default=24).
Built with SSL library version : OpenSSL 3.5.6 7 Apr 2026
Running on SSL library version : OpenSSL 3.5.6 7 Apr 2026
SSL library supports TLS extensions : yes
SSL library supports SNI : yes
SSL library default verify directory : /etc/ssl/certs
SSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
OpenSSL providers loaded : default
QUIC: connection sock-per-conn mode support : no
QUIC: GSO emission support : no
Built with the Prometheus exporter as a service
Built with zlib version : 1.3.1
Running on zlib version : 1.3.2
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_BINDANY IPV6_BINDANY
Built with PCRE2 version : 10.47 2025-10-21
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with clang compiler version 19.1.7 (https://github.com/llvm/llvm-project.git llvmorg-19.1.7-0-gcd708029e0b2)

Available polling systems :
     kqueue : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use kqueue.

Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
       quic : mode=HTTP  side=FE|BE  mux=QUIC  flags=HTX|NO_UPG|FRAMED
       qmux : mode=HTTP  side=FE|BE  mux=QMUX  flags=HTX|NO_UPG
         h2 : mode=HTTP  side=FE|BE  mux=H2    flags=HTX|HOL_RISK|NO_UPG
         h1 : mode=HTTP  side=FE|BE  mux=H1    flags=HTX|NO_UPG
  <default> : mode=HTTP  side=FE|BE  mux=H1    flags=HTX
       fcgi : mode=HTTP  side=BE     mux=FCGI  flags=HTX|HOL_RISK|NO_UPG
       spop : mode=SPOP  side=BE     mux=SPOP  flags=HOL_RISK|NO_UPG
  <default> : mode=SPOP  side=BE     mux=SPOP  flags=HOL_RISK|NO_UPG
       none : mode=TCP   side=FE|BE  mux=PASS  flags=NO_UPG
  <default> : mode=TCP   side=FE|BE  mux=PASS  flags=

Available services : prometheus-exporter
Available filters :
        [BWLIM] bwlim-in
        [BWLIM] bwlim-out
        [CACHE] cache
        [COMP] comp-req
        [COMP] comp-res
        [COMP] compression
        [FCGI] fcgi-app
        [SPOE] spoe
        [TRACE] trace
Last Outputs and Backtraces

Additional Information

No response

Ngôn ngữ chính
C
Star
6.9k
Fork
976
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của haproxy/haproxy

Tất cả issue của haproxy/haproxy

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.