Skip to content

Commit 9ae30cc

Browse files
committed
linux/cpukinds: separate gathering from submitting cpukind
Get all sysfs frequencies and capacities in an array and then submit cpukinds. We'll add intermediate quirks. Signed-off-by: Brice Goglin <[email protected]>
1 parent ea6be04 commit 9ae30cc

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

hwloc/topology-linux.c

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4430,6 +4430,13 @@ look_sysfsnode(struct hwloc_topology *topology,
44304430
* sysfs CPU frequencies for cpukinds
44314431
*/
44324432

4433+
struct hwloc_linux_cpukinds_by_pu {
4434+
unsigned pu;
4435+
unsigned long max_freq;
4436+
unsigned long base_freq;
4437+
unsigned long capacity;
4438+
};
4439+
44334440
struct hwloc_linux_cpukinds {
44344441
struct hwloc_linux_cpukind {
44354442
unsigned long value;
@@ -4620,14 +4627,16 @@ static int
46204627
look_sysfscpukinds(struct hwloc_topology *topology,
46214628
struct hwloc_linux_backend_data_s *data)
46224629
{
4630+
int nr_pus;
4631+
struct hwloc_linux_cpukinds_by_pu *by_pu;
46234632
struct hwloc_linux_cpukinds cpufreqs_max, cpufreqs_base, cpu_capacity;
46244633
int max_without_basefreq = 0; /* any cpu where we have maxfreq without basefreq? */
46254634
char str[293];
46264635
char *env;
46274636
hwloc_bitmap_t atom_pmu_set, core_pmu_set;
46284637
int maxfreq_enabled = -1; /* -1 means adjust (default), 0 means ignore, 1 means enforce */
46294638
unsigned adjust_max = 10;
4630-
int i;
4639+
int pu, i;
46314640

46324641
env = getenv("HWLOC_CPUKINDS_MAXFREQ");
46334642
if (env) {
@@ -4647,24 +4656,45 @@ look_sysfscpukinds(struct hwloc_topology *topology,
46474656
hwloc_debug("linux/cpufreq: max frequency values will be adjusted by up to %u%%\n",
46484657
adjust_max);
46494658

4650-
/* look at the PU base+max frequency */
4651-
hwloc_linux_cpukinds_init(&cpufreqs_max);
4652-
hwloc_linux_cpukinds_init(&cpufreqs_base);
4653-
hwloc_bitmap_foreach_begin(i, topology->levels[0][0]->cpuset) {
4654-
unsigned maxfreq = 0, basefreq = 0;
4659+
nr_pus = hwloc_bitmap_weight(topology->levels[0][0]->cpuset);
4660+
assert(nr_pus > 0);
4661+
by_pu = calloc(nr_pus, sizeof(*by_pu));
4662+
if (!by_pu)
4663+
return -1;
4664+
4665+
/* gather all sysfs info in the by_pu array */
4666+
i = 0;
4667+
hwloc_bitmap_foreach_begin(pu, topology->levels[0][0]->cpuset) {
4668+
unsigned maxfreq = 0, basefreq = 0, capacity = 0;;
4669+
by_pu[i].pu = pu;
4670+
46554671
/* cpuinfo_max_freq is the hardware max. scaling_max_freq is the software policy current max */
46564672
sprintf(str, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);
46574673
if (hwloc_read_path_as_uint(str, &maxfreq, data->root_fd) >= 0)
4658-
if (maxfreq)
4659-
hwloc_linux_cpukinds_add(&cpufreqs_max, i, maxfreq/1000);
4674+
by_pu[i].max_freq = maxfreq;
46604675
/* base_frequency is intel_pstate specific */
46614676
sprintf(str, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", i);
46624677
if (hwloc_read_path_as_uint(str, &basefreq, data->root_fd) >= 0)
4663-
if (basefreq)
4664-
hwloc_linux_cpukinds_add(&cpufreqs_base, i, basefreq/1000);
4678+
by_pu[i].base_freq = basefreq;
46654679
if (maxfreq && !basefreq)
46664680
max_without_basefreq = 1;
4681+
/* capacity */
4682+
sprintf(str, "/sys/devices/system/cpu/cpu%d/cpu_capacity", i);
4683+
if (hwloc_read_path_as_uint(str, &capacity, data->root_fd) >= 0)
4684+
by_pu[i].capacity = capacity;
4685+
i++;
46674686
} hwloc_bitmap_foreach_end();
4687+
assert(i == nr_pus);
4688+
4689+
/* now store base+max frequency */
4690+
hwloc_linux_cpukinds_init(&cpufreqs_max);
4691+
hwloc_linux_cpukinds_init(&cpufreqs_base);
4692+
for(i=0; i<nr_pus; i++) {
4693+
if (by_pu[i].max_freq)
4694+
hwloc_linux_cpukinds_add(&cpufreqs_max, by_pu[i].pu, by_pu[i].max_freq/1000);
4695+
if (by_pu[i].base_freq)
4696+
hwloc_linux_cpukinds_add(&cpufreqs_base, by_pu[i].pu, by_pu[i].base_freq/1000);
4697+
}
46684698

46694699
if (maxfreq_enabled == -1 && cpufreqs_max.nr_sets && !max_without_basefreq)
46704700
/* we have basefreq, check maxfreq and ignore/fix it if turboboost 3.0 makes the max different on different cores */
@@ -4679,15 +4709,15 @@ look_sysfscpukinds(struct hwloc_topology *topology,
46794709

46804710
/* look at the PU capacity */
46814711
hwloc_linux_cpukinds_init(&cpu_capacity);
4682-
hwloc_bitmap_foreach_begin(i, topology->levels[0][0]->cpuset) {
4683-
unsigned capacity;
4684-
sprintf(str, "/sys/devices/system/cpu/cpu%d/cpu_capacity", i);
4685-
if (hwloc_read_path_as_uint(str, &capacity, data->root_fd) >= 0)
4686-
hwloc_linux_cpukinds_add(&cpu_capacity, i, capacity);
4687-
} hwloc_bitmap_foreach_end();
4712+
for(i=0; i<nr_pus; i++) {
4713+
if (by_pu[i].capacity)
4714+
hwloc_linux_cpukinds_add(&cpu_capacity, by_pu[i].pu, by_pu[i].capacity);
4715+
}
46884716
hwloc_linux_cpukinds_register(&cpu_capacity, topology, "LinuxCapacity", 1);
46894717
hwloc_linux_cpukinds_destroy(&cpu_capacity);
46904718

4719+
free(by_pu);
4720+
46914721
/* look at Intel core/atom PMUs */
46924722
atom_pmu_set = hwloc__alloc_read_path_as_cpulist("/sys/devices/cpu_atom/cpus", data->root_fd);
46934723
core_pmu_set = hwloc__alloc_read_path_as_cpulist("/sys/devices/cpu_core/cpus", data->root_fd);

0 commit comments

Comments
 (0)