Messages in this thread Patch in this message | | | From | "Natarajan, Janakarajan" <> | Subject | [PATCH 1/2] Modify cpupower to schedule itself on cores it is reading MSRs from | Date | Wed, 18 Sep 2019 16:34:57 +0000 |
| |
Modify cpupower to schedule itself on each of the cpus in the system and then get the APERF/MPERF register values.
This is advantageous because an IPI is not generated when a read_msr() is executed on the local logical CPU thereby reducing the chance of having APERF and MPERF being out of sync.
Signed-off-by: Janakarajan Natarajan <Janakarajan.Natarajan@amd.com> --- .../utils/idle_monitor/mperf_monitor.c | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c index 44806a6dae11..8b072e39c897 100644 --- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include <limits.h> +#include <sched.h> #include <cpufreq.h> @@ -86,15 +87,33 @@ static int mperf_get_tsc(unsigned long long *tsc) return ret; } +static int get_aperf_mperf(int cpu, unsigned long long *aval, + unsigned long long *mval) +{ + cpu_set_t set; + int ret; + + CPU_ZERO(&set); + CPU_SET(cpu, &set); + if (sched_setaffinity(getpid(), sizeof(set), &set) == -1) { + dprint("Could not migrate to cpu: %d\n", cpu); + return 1; + } + + ret = read_msr(cpu, MSR_APERF, aval); + ret |= read_msr(cpu, MSR_MPERF, mval); + + return ret; +} + static int mperf_init_stats(unsigned int cpu) { - unsigned long long val; + unsigned long long aval, mval; int ret; - ret = read_msr(cpu, MSR_APERF, &val); - aperf_previous_count[cpu] = val; - ret |= read_msr(cpu, MSR_MPERF, &val); - mperf_previous_count[cpu] = val; + ret = get_aperf_mperf(cpu, &aval, &mval); + aperf_previous_count[cpu] = aval; + mperf_previous_count[cpu] = mval; is_valid[cpu] = !ret; return 0; @@ -102,13 +121,12 @@ static int mperf_init_stats(unsigned int cpu) static int mperf_measure_stats(unsigned int cpu) { - unsigned long long val; + unsigned long long aval, mval; int ret; - ret = read_msr(cpu, MSR_APERF, &val); - aperf_current_count[cpu] = val; - ret |= read_msr(cpu, MSR_MPERF, &val); - mperf_current_count[cpu] = val; + ret = get_aperf_mperf(cpu, &aval, &mval); + aperf_current_count[cpu] = aval; + mperf_current_count[cpu] = mval; is_valid[cpu] = !ret; return 0; -- 2.17.1
| |