linux: prefer cpuinfo_cur_freq over scaling_cur_freq in uv_cpu_info()

Reading scaling_cur_freq for each CPU core triggers a slow ACPI/SMM
round-trip on some modern AMD CPUs (EPYC, Ryzen 9000 series), especially
inside Linux containers, where the latency regularly reaches ~20ms per
core. On a 32-core system this makes a single uv_cpu_info() call take
500-600ms.

cpuinfo_cur_freq reports the same current-frequency value but reads from
a hardware-cached register, avoiding the ACPI round-trip entirely. Prefer
it when available and fall back to scaling_cur_freq for systems that do
not expose cpuinfo_cur_freq (e.g. non-x86 platforms or systems without
the cpufreq driver loaded).

Fixes: https://github.com/libuv/libuv/issues/4098
This commit is contained in:
RajeshKumar11 2026-02-27 21:55:00 +05:30
parent 12d0dd48e3
commit aacfd6bfba

View File

@ -1867,10 +1867,19 @@ nocpuinfo:
continue;
n++;
/* Prefer cpuinfo_cur_freq: it reads a hardware-cached value and avoids
* slow ACPI/SMM round-trips that scaling_cur_freq triggers on some AMD
* CPUs (especially inside containers), which can take ~20ms per core.
* Fall back to scaling_cur_freq when cpuinfo_cur_freq is not available.
*/
snprintf(buf, sizeof(buf),
"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", cpu);
"/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_cur_freq", cpu);
fp = uv__open_file(buf);
if (fp == NULL) {
snprintf(buf, sizeof(buf),
"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", cpu);
fp = uv__open_file(buf);
}
if (fp == NULL)
continue;