aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2015-11-18 12:04:48 -0500
committerShuah Khan <shuahkh@osg.samsung.com>2015-11-23 15:30:59 -0500
commited2d26d7cbccb1aa719a5d3fb8e87ef6610cb530 (patch)
treebd01c870e88e65bdf0dd6e0794fcf0d1f12d7ee0 /tools
parent7e722473811a4f82a48bb2ef934ff44ca9ab8fa5 (diff)
tools, testing, add test for intel_pstate driver
This test used the cpupower utility to set the cpu frequency from the maximum turbo value to the minimum supported value in steps of 100 MHz. The results are displayed in a table which indicate the "Target" state, or the requested frequency in MHz, the Actual frequency, as read from /proc/cpuinfo, the difference between the Target and Actual frequencies, and the value of MSR 0x199 (MSR_IA32_PERF_CTL) which indicates what pstate the cpu is in, and the value of /sys/devices/system/cpu/intel_pstate/max_perf_pct X maximum turbo state Cc: Shuah Khan <shuahkh@osg.samsung.com> Cc: linux-api@vger.kernel.org Signed-off-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/intel_pstate/Makefile15
-rw-r--r--tools/testing/selftests/intel_pstate/aperf.c80
-rw-r--r--tools/testing/selftests/intel_pstate/msr.c39
-rwxr-xr-xtools/testing/selftests/intel_pstate/run.sh113
4 files changed, 247 insertions, 0 deletions
diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile
new file mode 100644
index 000000000000..f5f1a28715ff
--- /dev/null
+++ b/tools/testing/selftests/intel_pstate/Makefile
@@ -0,0 +1,15 @@
1CC := $(CROSS_COMPILE)gcc
2CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE
3LDFLAGS := $(LDFLAGS) -lm
4
5TARGETS := msr aperf
6
7TEST_PROGS := $(TARGETS) run.sh
8
9.PHONY: all clean
10all: $(TARGETS)
11
12$(TARGETS): $(HEADERS)
13
14clean:
15 rm -f $(TARGETS)
diff --git a/tools/testing/selftests/intel_pstate/aperf.c b/tools/testing/selftests/intel_pstate/aperf.c
new file mode 100644
index 000000000000..6046e183f4ad
--- /dev/null
+++ b/tools/testing/selftests/intel_pstate/aperf.c
@@ -0,0 +1,80 @@
1#include <math.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <sys/timeb.h>
9#include <sched.h>
10#include <errno.h>
11
12void usage(char *name) {
13 printf ("Usage: %s cpunum\n", name);
14}
15
16int main(int argc, char **argv) {
17 int i, cpu, fd;
18 char msr_file_name[64];
19 long long tsc, old_tsc, new_tsc;
20 long long aperf, old_aperf, new_aperf;
21 long long mperf, old_mperf, new_mperf;
22 struct timeb before, after;
23 long long int start, finish, total;
24 cpu_set_t cpuset;
25
26 if (argc != 2) {
27 usage(argv[0]);
28 return 1;
29 }
30
31 errno = 0;
32 cpu = strtol(argv[1], (char **) NULL, 10);
33
34 if (errno) {
35 usage(argv[0]);
36 return 1;
37 }
38
39 sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
40 fd = open(msr_file_name, O_RDONLY);
41
42 if (fd == -1) {
43 perror("Failed to open");
44 return 1;
45 }
46
47 CPU_ZERO(&cpuset);
48 CPU_SET(cpu, &cpuset);
49
50 if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) {
51 perror("Failed to set cpu affinity");
52 return 1;
53 }
54
55 ftime(&before);
56 pread(fd, &old_tsc, sizeof(old_tsc), 0x10);
57 pread(fd, &old_aperf, sizeof(old_mperf), 0xe7);
58 pread(fd, &old_mperf, sizeof(old_aperf), 0xe8);
59
60 for (i=0; i<0x8fffffff; i++) {
61 sqrt(i);
62 }
63
64 ftime(&after);
65 pread(fd, &new_tsc, sizeof(new_tsc), 0x10);
66 pread(fd, &new_aperf, sizeof(new_mperf), 0xe7);
67 pread(fd, &new_mperf, sizeof(new_aperf), 0xe8);
68
69 tsc = new_tsc-old_tsc;
70 aperf = new_aperf-old_aperf;
71 mperf = new_mperf-old_mperf;
72
73 start = before.time*1000 + before.millitm;
74 finish = after.time*1000 + after.millitm;
75 total = finish - start;
76
77 printf("runTime: %4.2f\n", 1.0*total/1000);
78 printf("freq: %7.0f\n", tsc / (1.0*aperf / (1.0 * mperf)) / total);
79 return 0;
80}
diff --git a/tools/testing/selftests/intel_pstate/msr.c b/tools/testing/selftests/intel_pstate/msr.c
new file mode 100644
index 000000000000..abbbfc84d359
--- /dev/null
+++ b/tools/testing/selftests/intel_pstate/msr.c
@@ -0,0 +1,39 @@
1#include <math.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <sys/timeb.h>
9#include <sched.h>
10#include <errno.h>
11
12
13int main(int argc, char **argv) {
14 int cpu, fd;
15 long long msr;
16 char msr_file_name[64];
17
18 if (argc != 2)
19 return 1;
20
21 errno = 0;
22 cpu = strtol(argv[1], (char **) NULL, 10);
23
24 if (errno)
25 return 1;
26
27 sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
28 fd = open(msr_file_name, O_RDONLY);
29
30 if (fd == -1) {
31 perror("Failed to open");
32 return 1;
33 }
34
35 pread(fd, &msr, sizeof(msr), 0x199);
36
37 printf("msr 0x199: 0x%llx\n", msr);
38 return 0;
39}
diff --git a/tools/testing/selftests/intel_pstate/run.sh b/tools/testing/selftests/intel_pstate/run.sh
new file mode 100755
index 000000000000..bdaf37e92684
--- /dev/null
+++ b/tools/testing/selftests/intel_pstate/run.sh
@@ -0,0 +1,113 @@
1#!/bin/bash
2#
3# This test runs on Intel x86 based hardware which support the intel_pstate
4# driver. The test checks the frequency settings from the maximum turbo
5# state to the minimum supported frequency, in decrements of 100MHz. The
6# test runs the aperf.c program to put load on each processor.
7#
8# The results are displayed in a table which indicate the "Target" state,
9# or the requested frequency in MHz, the Actual frequency, as read from
10# /proc/cpuinfo, the difference between the Target and Actual frequencies,
11# and the value of MSR 0x199 (MSR_IA32_PERF_CTL) which indicates what
12# pstate the cpu is in, and the value of
13# /sys/devices/system/cpu/intel_pstate/max_perf_pct X maximum turbo state
14#
15# Notes: In some cases several frequency values may be placed in the
16# /tmp/result.X files. This is done on purpose in order to catch cases
17# where the pstate driver may not be working at all. There is the case
18# where, for example, several "similar" frequencies are in the file:
19#
20#
21#/tmp/result.3100:1:cpu MHz : 2899.980
22#/tmp/result.3100:2:cpu MHz : 2900.000
23#/tmp/result.3100:3:msr 0x199: 0x1e00
24#/tmp/result.3100:4:max_perf_pct 94
25#
26# and the test will error out in those cases. The result.X file can be checked
27# for consistency and modified to remove the extra MHz values. The result.X
28# files can be re-evaluated by setting EVALUATE_ONLY to 1 below.
29
30EVALUATE_ONLY=0
31
32max_cpus=$(($(nproc)-1))
33
34# compile programs
35gcc -o aperf aperf.c -lm
36[ $? -ne 0 ] && echo "Problem compiling aperf.c." && exit 1
37gcc -o msr msr.c -lm
38[ $? -ne 0 ] && echo "Problem compiling msr.c." && exit 1
39
40function run_test () {
41
42 file_ext=$1
43 for cpu in `seq 0 $max_cpus`
44 do
45 echo "launching aperf load on $cpu"
46 ./aperf $cpu &
47 done
48
49 echo "sleeping for 5 seconds"
50 sleep 5
51 num_freqs=$(cat /proc/cpuinfo | grep MHz | sort -u | wc -l)
52 if [ $num_freqs -le 2 ]; then
53 cat /proc/cpuinfo | grep MHz | sort -u | tail -1 > /tmp/result.$1
54 else
55 cat /proc/cpuinfo | grep MHz | sort -u > /tmp/result.$1
56 fi
57 ./msr 0 >> /tmp/result.$1
58
59 max_perf_pct=$(cat /sys/devices/system/cpu/intel_pstate/max_perf_pct)
60 echo "max_perf_pct $max_perf_pct" >> /tmp/result.$1
61
62 for job in `jobs -p`
63 do
64 echo "waiting for job id $job"
65 wait $job
66 done
67}
68
69#
70# MAIN (ALL UNITS IN MHZ)
71#
72
73# Get the marketing frequency
74_mkt_freq=$(cat /proc/cpuinfo | grep -m 1 "model name" | awk '{print $NF}')
75_mkt_freq=$(echo $_mkt_freq | tr -d [:alpha:][:punct:])
76mkt_freq=${_mkt_freq}0
77
78# Get the ranges from cpupower
79_min_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $1 } ')
80min_freq=$(($_min_freq / 1000))
81_max_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $2 } ')
82max_freq=$(($_max_freq / 1000))
83
84
85for freq in `seq $max_freq -100 $min_freq`
86do
87 echo "Setting maximum frequency to $freq"
88 cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null
89 [ $EVALUATE_ONLY -eq 0 ] && run_test $freq
90done
91
92echo "=============================================================================="
93
94echo "The marketing frequency of the cpu is $mkt_freq MHz"
95echo "The maximum frequency of the cpu is $max_freq MHz"
96echo "The minimum frequency of the cpu is $min_freq MHz"
97
98cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null
99
100# make a pretty table
101echo "Target Actual Difference MSR(0x199) max_perf_pct"
102for freq in `seq $max_freq -100 $min_freq`
103do
104 result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ')
105 msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ')
106 max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' )
107 if [ $result_freq -eq $freq ]; then
108 echo " $freq $result_freq 0 $msr $(($max_perf_pct*3300))"
109 else
110 echo " $freq $result_freq $(($result_freq-$freq)) $msr $(($max_perf_pct*$max_freq))"
111 fi
112done
113exit 0