Skip to content

Commit 2292110

Browse files
committed
linux/cpukinds/freq: use acpi_cppc/nominal_freq when available
cpufreq/base_frequency is only available on Intel so far, and works well. acpi_cppc/nominal_freq is already available on AMD (and ARM or soon), so it's likely good for the future. However it reports incorrect values on Intel SPR and MTL at least. Hence try cpufreq/base_frequency first, then fallback to acpi_cppc/nominal_freq. Refs #690 Signed-off-by: Brice Goglin <[email protected]>
1 parent 5f38bbc commit 2292110

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

doc/hwloc.doxy

+3-2
Original file line numberDiff line numberDiff line change
@@ -2466,8 +2466,9 @@ These CPU kinds may be annotated with the following native attributes:
24662466
as reported by <tt>cpufreq</tt> drivers on Linux.
24672467
</dd>
24682468
<dt>FrequencyBaseMHz (Linux)</dt>
2469-
<dd>The base operating frequency of the core,
2470-
as reported by some <tt>cpufreq</tt> drivers on Linux (e.g. <tt>intel_pstate</tt>).
2469+
<dd>The base/nominal operating frequency of the core,
2470+
as reported by some <tt>cpufreq</tt> or ACPI drivers on Linux
2471+
(e.g. <tt>cpufreq_cppc</tt> or <tt>intel_pstate</tt>).
24712472
</dd>
24722473
<dt>CoreType (x86)</dt>
24732474
<dd>A string describing the kind of core,

hwloc/topology-linux.c

+21-4
Original file line numberDiff line numberDiff line change
@@ -4480,8 +4480,8 @@ look_sysfsnode(struct hwloc_topology *topology,
44804480

44814481
struct hwloc_linux_cpukinds_by_pu {
44824482
unsigned pu;
4483-
unsigned long max_freq;
4484-
unsigned long base_freq;
4483+
unsigned long max_freq; /* kHz */
4484+
unsigned long base_freq; /* kHz */
44854485
unsigned long capacity;
44864486
int done; /* temporary bit to identify PU that were processed by the current algorithm
44874487
* (only hwloc_linux_cpukinds_adjust_maxfreqs() for now)
@@ -4724,6 +4724,7 @@ look_sysfscpukinds(struct hwloc_topology *topology,
47244724
char *env;
47254725
hwloc_bitmap_t atom_pmu_set, core_pmu_set;
47264726
int maxfreq_enabled = -1; /* -1 means adjust (default), 0 means ignore, 1 means enforce */
4727+
int use_cppc_nominal_freq = -1; /* -1 means try, 0 no, 1 yes */
47274728
unsigned adjust_max = 10;
47284729
int force_homogeneous;
47294730
const char *info;
@@ -4763,10 +4764,26 @@ look_sysfscpukinds(struct hwloc_topology *topology,
47634764
sprintf(str, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);
47644765
if (hwloc_read_path_as_uint(str, &maxfreq, data->root_fd) >= 0)
47654766
by_pu[i].max_freq = maxfreq;
4766-
/* base_frequency is intel_pstate specific */
4767+
/* base_frequency is in intel_pstate and works fine */
47674768
sprintf(str, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", i);
4768-
if (hwloc_read_path_as_uint(str, &basefreq, data->root_fd) >= 0)
4769+
if (hwloc_read_path_as_uint(str, &basefreq, data->root_fd) >= 0) {
47694770
by_pu[i].base_freq = basefreq;
4771+
use_cppc_nominal_freq = 0;
4772+
}
4773+
/* try acpi_cppc/nominal_freq only if cpufreq/base_frequency failed
4774+
* acpi_cppc/nominal_freq is widely available, but it returns 0 on some Intel SPR,
4775+
* same freq for all cores on RPL,
4776+
* maxfreq for E-cores and LP-E-cores but basefreq for P-cores on MTL.
4777+
*/
4778+
if (use_cppc_nominal_freq != 0) {
4779+
sprintf(str, "/sys/devices/system/cpu/cpu%d/acpi_cppc/nominal_freq", i);
4780+
if (hwloc_read_path_as_uint(str, &basefreq, data->root_fd) >= 0 && basefreq > 0) {
4781+
by_pu[i].base_freq = basefreq * 1000; /* nominal_freq is already in MHz */
4782+
use_cppc_nominal_freq = 1;
4783+
} else {
4784+
use_cppc_nominal_freq = 0;
4785+
}
4786+
}
47704787
if (maxfreq && !basefreq)
47714788
max_without_basefreq = 1;
47724789
/* capacity */

0 commit comments

Comments
 (0)