cpupower improvements on AMD systems
cover cpupower improvements on AMD systems
From: Mario Limonciello <[email protected]>
cpupower shows a number of errors on AMD systems configured in 'active' mode where the hardware transitions states for the user.
Clean up those errors and add some extra information for the amd-pstate preferred core feature.
Mario Limonciello (7):
cpupower: Remove spurious return statement
cpupower: Add support for parsing 'enabled' or 'disabled' strings from
table
cpupower: Add support for amd-pstate preferred core rankings
cpupower: Don't try to read frequency from hardware when kernel uses
aperfmperf
cpupower: Add support for showing energy performance preference
cpupower: Don't fetch maximum latency when EPP is enabled
cpupower: Adjust whitespace for amd-pstate specific prints
tools/power/cpupower/lib/cpufreq.c | 18 ++++++++++++ tools/power/cpupower/lib/cpufreq.h | 8 +++++ tools/power/cpupower/utils/cpufreq-info.c | 36 +++++++++++++++++++++-- tools/power/cpupower/utils/helpers/amd.c | 18 +++++++++--- 4 files changed, 73 insertions(+), 7 deletions(-)
Signature · 1 line
2.43.0
PATCH 1/7 cpupower: Remove spurious return statement
From: Mario Limonciello <[email protected]>
print_duration() has a return; statement at the end of the function that is not necessary as it's a void function.
--- tools/power/cpupower/utils/cpufreq-info.c | 1 - 1 file changed, 1 deletion(-)
tools/power/cpupower/utils/cpufreq-info.c +0 -1
@@ -120,7 +120,6 @@ static void print_duration(unsigned long duration) }else printf ("%lu ns" , duration); } -return ; }static int get_boost_mode_x86 (unsigned int cpu)
Signature · 1 line
2.43.0
PATCH 2/7 cpupower: Add support for parsing 'enabled' or 'disabled' strings from table
In reply to Mario LimoncielloFrom: Mario Limonciello <[email protected]>
When cpufreq_get_sysfs_value_from_table() is passed a table with kernel strings that report 'enabled' or 'disabled' it always returns 0 because these can't cleanly convert to integers.
Explicitly look for enabled or disabled strings from the kernel to handle this.
--- tools/power/cpupower/lib/cpufreq.c | 4 ++++ 1 file changed, 4 insertions(+)
tools/power/cpupower/lib/cpufreq.c +4 -0
@@ -102,6 +102,10 @@ unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu,if (len ==0 )return 0 ; +if (!strcmp (linebuf,"enabled\n" )) +return 1 ; +if (!strcmp (linebuf,"disabled\n" )) +return 0 ; value =strtoul (linebuf, &endp,0 );if (endp == linebuf || errno ==ERANGE )
Signature · 1 line
2.43.0
PATCH 3/7 cpupower: Add support for amd-pstate preferred core rankings
In reply to Mario LimoncielloFrom: Mario Limonciello <[email protected]>
The rankings are useful information to determine if the scheduler is placing tasks appropriately for the hardware.
--- tools/power/cpupower/utils/helpers/amd.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/power/cpupower/utils/helpers/amd.c +8 -0
@@ -177,6 +177,8 @@ enum amd_pstate_value {AMD_PSTATE_HIGHEST_PERF ,AMD_PSTATE_MAX_FREQ ,AMD_PSTATE_LOWEST_NONLINEAR_FREQ , +AMD_PSTATE_HW_PREFCORE , +AMD_PSTATE_PREFCORE_RANKING , MAX_AMD_PSTATE_VALUE_READ_FILES, };
@@ -184,6 +186,8 @@ static const char *amd_pstate_value_files[MAX_AMD_PSTATE_VALUE_READ_FILES] = { [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf", [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq", [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq", + [AMD_PSTATE_HW_PREFCORE] = "amd_pstate_hw_prefcore", + [AMD_PSTATE_PREFCORE_RANKING] = "amd_pstate_prefcore_ranking", }; static unsigned long amd_pstate_get_data(unsigned int cpu,
@@ -240,6 +244,10 @@ void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding) acpi_cppc_get_data(cpu, LOWEST_PERF));print_speed (acpi_cppc_get_data (cpu,LOWEST_FREQ ) *1000 , no_rounding);printf (".\n" ); + +printf (_ (" Preferred Core Support: %lu. Preferred Core Ranking: %lu.\n" ), +amd_pstate_get_data (cpu,AMD_PSTATE_HW_PREFCORE ), +amd_pstate_get_data (cpu,AMD_PSTATE_PREFCORE_RANKING )); }/* AMD P-State Helper Functions ************************************/
Signature · 1 line
2.43.0
PATCH 4/7 cpupower: Don't try to read frequency from hardware when kernel uses aperfmperf
In reply to Mario LimoncielloFrom: Mario Limonciello <[email protected]>
When the amd-pstate is in use frequency is set by the hardware and measured by the kernel through using the aperf and mperf registers.
There is no direct call to the hardware to indicate current frequency.
Detect that this feature is in use and skip the check.
--- tools/power/cpupower/utils/cpufreq-info.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/power/cpupower/utils/cpufreq-info.c +6 -1
@@ -254,7 +254,12 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human)static int get_freq_hardware (unsigned int cpu,unsigned int human) { -unsigned long freq =cpufreq_get_freq_hardware (cpu); +unsigned long freq; + +if (cpupower_cpu_info.caps &CPUPOWER_CAP_APERF ) +return -EINVAL ; + + freq =cpufreq_get_freq_hardware (cpu);printf (_ (" current CPU frequency: " ));if (!freq) {printf ("Unable to call hardware\n" );
Signature · 1 line
2.43.0
PATCH 5/7 cpupower: Add support for showing energy performance preference
In reply to Mario LimoncielloFrom: Mario Limonciello <[email protected]>
The EPP value is useful for characterization of performance. Show it in cpupower frequency-info output.
--- tools/power/cpupower/lib/cpufreq.c | 14 +++++++++++++ tools/power/cpupower/lib/cpufreq.h | 8 ++++++++ tools/power/cpupower/utils/cpufreq-info.c | 25 ++++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-)
tools/power/cpupower/lib/cpufreq.c +14 -0
@@ -127,12 +127,14 @@ static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,enum cpufreq_string {SCALING_DRIVER ,SCALING_GOVERNOR , +ENERGY_PERFORMANCE_PREFERENCE ,MAX_CPUFREQ_STRING_FILES };static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES ] = { [SCALING_DRIVER ] ="scaling_driver" , [SCALING_GOVERNOR ] ="scaling_governor" , + [ENERGY_PERFORMANCE_PREFERENCE ] ="energy_performance_preference" , };
@@ -207,6 +209,18 @@ unsigned long cpufreq_get_transition_latency(unsigned int cpu)return sysfs_cpufreq_get_one_value (cpu,CPUINFO_LATENCY ); } +char *cpufreq_get_energy_performance_preference (unsigned int cpu) +{ +return sysfs_cpufreq_get_one_string (cpu,ENERGY_PERFORMANCE_PREFERENCE ); +} + +void cpufreq_put_energy_performance_preference (char *ptr) +{ +if (!ptr) +return ; +free (ptr); +} +int cpufreq_get_hardware_limits (unsigned int cpu,unsigned long *min,unsigned long *max)
tools/power/cpupower/lib/cpufreq.h +8 -0
@@ -68,6 +68,14 @@ unsigned long cpufreq_get_freq_hardware(unsigned int cpu);unsigned long cpufreq_get_transition_latency (unsigned int cpu); +/* determine energy performance preference +* +* returns NULL on failure, else the string that represents the energy performance +* preference requested. +*/ +char *cpufreq_get_energy_performance_preference (unsigned int cpu); +void cpufreq_put_energy_performance_preference (char *ptr); +/* determine hardware CPU frequency limits * * These may be limited further by thermal, energy or other
tools/power/cpupower/utils/cpufreq-info.c +24 -1
@@ -422,6 +422,23 @@ static int get_freq_stats(unsigned int cpu, unsigned int human)return 0 ; } +/* --epp / -z */ + +static int get_epp (unsigned int cpu,bool interactive) +{ +char *epp; + + epp =cpufreq_get_energy_performance_preference (cpu); +if (!epp) +return -EINVAL ; +if (interactive) +printf (_ (" energy performance preference: %s\n" ), epp); + +cpufreq_put_energy_performance_preference (epp); + +return 0 ; +} +/* --latency / -y */ static int get_latency (unsigned int cpu,unsigned int human)
@@ -461,6 +478,7 @@ static void debug_output_one(unsigned int cpu)get_related_cpus (cpu);get_affected_cpus (cpu);get_latency (cpu,1 ); +get_epp (cpu, true);get_hardware_limits (cpu,1 ); freqs =cpufreq_get_available_frequencies (cpu);
@@ -501,6 +519,7 @@ static struct option info_opts[] = { {"human", no_argument, NULL, 'm'}, {"no-rounding", no_argument, NULL, 'n'}, {"performance", no_argument, NULL, 'c'}, + {"epp", no_argument, NULL, 'z'}, { }, };
@@ -514,7 +533,7 @@ int cmd_freq_info(int argc, char **argv)int output_param =0 ; do { - ret = getopt_long(argc, argv, "oefwldpgrasmybnc", info_opts, + ret = getopt_long(argc, argv, "oefwldpgrasmybncz", info_opts, NULL); switch (ret) { case '?':
@@ -538,6 +557,7 @@ int cmd_freq_info(int argc, char **argv)case 's' :case 'y' :case 'c' : +case 'z' :if (output_param) { output_param =-1 ; cont =0 ;
@@ -647,6 +667,9 @@ int cmd_freq_info(int argc, char **argv)case 'c' : ret =get_perf_cap (cpu);break ; +case 'z' : + ret =get_epp (cpu, true); +break ; }if (ret)return ret;
Signature · 1 line
2.43.0
PATCH 6/7 cpupower: Don't fetch maximum latency when EPP is enabled
In reply to Mario LimoncielloFrom: Mario Limonciello <[email protected]>
When EPP has been enabled the hardware will autonomously change frequencies on it's own and thus there is no latency with changing from the kernel.
Avoid doing the maximum latency check when EPP is found. This will apply to both amd-pstate and intel-pstate drivers.
--- tools/power/cpupower/utils/cpufreq-info.c | 3 +++ 1 file changed, 3 insertions(+)
tools/power/cpupower/utils/cpufreq-info.c +3 -0
@@ -445,6 +445,9 @@ static int get_latency(unsigned int cpu, unsigned int human) {unsigned long latency =cpufreq_get_transition_latency (cpu); +if (!get_epp (cpu, false)) +return -EINVAL ; +printf (_ (" maximum transition latency: " ));if (!latency || latency ==UINT_MAX ) {printf (_ (" Cannot determine or is not supported.\n" ));
Signature · 1 line
2.43.0
PATCH 7/7 cpupower: Adjust whitespace for amd-pstate specific prints
In reply to Mario LimoncielloFrom: Mario Limonciello <[email protected]>
The amd-pstate section is grouped under boost, which isn't appropriate.
Adjust the indentation so that it is it's own section.
--- tools/power/cpupower/utils/helpers/amd.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
tools/power/cpupower/utils/helpers/amd.c +6 -4
@@ -219,7 +219,9 @@ void amd_pstate_boost_init(unsigned int cpu, int *support, int *active)void amd_pstate_show_perf_and_freq (unsigned int cpu,int no_rounding) { -printf (_ (" AMD PSTATE Highest Performance: %lu. Maximum Frequency: " ), + +printf (_ (" amd-pstate limits:\n" )); +printf (_ (" Highest Performance: %lu. Maximum Frequency: " ),amd_pstate_get_data (cpu,AMD_PSTATE_HIGHEST_PERF ));/* * If boost isn't active, the cpuinfo_max doesn't indicate real max
@@ -228,19 +230,19 @@ void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding)print_speed (amd_pstate_get_data (cpu,AMD_PSTATE_MAX_FREQ ), no_rounding);printf (".\n" ); -printf (_ (" AMD PSTATE Nominal Performance: %lu. Nominal Frequency: " ), +printf (_ (" Nominal Performance: %lu. Nominal Frequency: " ),acpi_cppc_get_data (cpu,NOMINAL_PERF ));print_speed (acpi_cppc_get_data (cpu,NOMINAL_FREQ ) *1000 , no_rounding);printf (".\n" ); -printf (_ (" AMD PSTATE Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: " ), +printf (_ (" Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: " ),acpi_cppc_get_data (cpu,LOWEST_NONLINEAR_PERF ));print_speed (amd_pstate_get_data (cpu,AMD_PSTATE_LOWEST_NONLINEAR_FREQ ), no_rounding);printf (".\n" ); -printf (_ (" AMD PSTATE Lowest Performance: %lu. Lowest Frequency: " ), +printf (_ (" Lowest Performance: %lu. Lowest Frequency: " ),acpi_cppc_get_data (cpu,LOWEST_PERF ));print_speed (acpi_cppc_get_data (cpu,LOWEST_FREQ ) *1000 , no_rounding);printf (".\n" );
Signature · 1 line
2.43.0
Shuah Khan
maintainerQuoted 20 lines · Mario Limonciello
From: Mario Limonciello <[email protected]>
cpupower shows a number of errors on AMD systems configured in 'active' mode where the hardware transitions states for the user.
Clean up those errors and add some extra information for the amd-pstate preferred core feature.
Mario Limonciello (7):
cpupower: Remove spurious return statement
cpupower: Add support for parsing 'enabled' or 'disabled' strings from
table
cpupower: Add support for amd-pstate preferred core rankings
cpupower: Don't try to read frequency from hardware when kernel uses
aperfmperf
cpupower: Add support for showing energy performance preference
cpupower: Don't fetch maximum latency when EPP is enabled
cpupower: Adjust whitespace for amd-pstate specific prints
Quoted 6 lines
tools/power/cpupower/lib/cpufreq.c | 18 ++++++++++++ tools/power/cpupower/lib/cpufreq.h | 8 +++++ tools/power/cpupower/utils/cpufreq-info.c | 36 +++++++++++++++++++++-- tools/power/cpupower/utils/helpers/amd.c | 18 +++++++++--- 4 files changed, 73 insertions(+), 7 deletions(-)
Thank you. The patch series is now in
https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux.git/log/?h=cpupower
I will include this in pull request to Rafael in early January.
thanks,
-- Shuah