@@ -4430,6 +4430,13 @@ look_sysfsnode(struct hwloc_topology *topology,
4430
4430
* sysfs CPU frequencies for cpukinds
4431
4431
*/
4432
4432
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
+
4433
4440
struct hwloc_linux_cpukinds {
4434
4441
struct hwloc_linux_cpukind {
4435
4442
unsigned long value ;
@@ -4620,14 +4627,16 @@ static int
4620
4627
look_sysfscpukinds (struct hwloc_topology * topology ,
4621
4628
struct hwloc_linux_backend_data_s * data )
4622
4629
{
4630
+ int nr_pus ;
4631
+ struct hwloc_linux_cpukinds_by_pu * by_pu ;
4623
4632
struct hwloc_linux_cpukinds cpufreqs_max , cpufreqs_base , cpu_capacity ;
4624
4633
int max_without_basefreq = 0 ; /* any cpu where we have maxfreq without basefreq? */
4625
4634
char str [293 ];
4626
4635
char * env ;
4627
4636
hwloc_bitmap_t atom_pmu_set , core_pmu_set ;
4628
4637
int maxfreq_enabled = -1 ; /* -1 means adjust (default), 0 means ignore, 1 means enforce */
4629
4638
unsigned adjust_max = 10 ;
4630
- int i ;
4639
+ int pu , i ;
4631
4640
4632
4641
env = getenv ("HWLOC_CPUKINDS_MAXFREQ" );
4633
4642
if (env ) {
@@ -4647,24 +4656,45 @@ look_sysfscpukinds(struct hwloc_topology *topology,
4647
4656
hwloc_debug ("linux/cpufreq: max frequency values will be adjusted by up to %u%%\n" ,
4648
4657
adjust_max );
4649
4658
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
+
4655
4671
/* cpuinfo_max_freq is the hardware max. scaling_max_freq is the software policy current max */
4656
4672
sprintf (str , "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq" , i );
4657
4673
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 ;
4660
4675
/* base_frequency is intel_pstate specific */
4661
4676
sprintf (str , "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency" , i );
4662
4677
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 ;
4665
4679
if (maxfreq && !basefreq )
4666
4680
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 ++ ;
4667
4686
} 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
+ }
4668
4698
4669
4699
if (maxfreq_enabled == -1 && cpufreqs_max .nr_sets && !max_without_basefreq )
4670
4700
/* 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,
4679
4709
4680
4710
/* look at the PU capacity */
4681
4711
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
+ }
4688
4716
hwloc_linux_cpukinds_register (& cpu_capacity , topology , "LinuxCapacity" , 1 );
4689
4717
hwloc_linux_cpukinds_destroy (& cpu_capacity );
4690
4718
4719
+ free (by_pu );
4720
+
4691
4721
/* look at Intel core/atom PMUs */
4692
4722
atom_pmu_set = hwloc__alloc_read_path_as_cpulist ("/sys/devices/cpu_atom/cpus" , data -> root_fd );
4693
4723
core_pmu_set = hwloc__alloc_read_path_as_cpulist ("/sys/devices/cpu_core/cpus" , data -> root_fd );
0 commit comments