#!/bin/bash # # This test runs on Intel x86 based hardware which support the intel_pstate # driver. The test checks the frequency settings from the maximum turbo # state to the minimum supported frequency, in decrements of 100MHz. The # test runs the aperf.c program to put load on each processor. # # 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 # # Notes: In some cases several frequency values may be placed in the # /tmp/result.X files. This is done on purpose in order to catch cases # where the pstate driver may not be working at all. There is the case # where, for example, several "similar" frequencies are in the file: # # #/tmp/result.3100:1:cpu MHz : 2899.980 #/tmp/result.3100:2:cpu MHz : 2900.000 #/tmp/result.3100:3:msr 0x199: 0x1e00 #/tmp/result.3100:4:max_perf_pct 94 # # and the test will error out in those cases. The result.X file can be checked # for consistency and modified to remove the extra MHz values. The result.X # files can be re-evaluated by setting EVALUATE_ONLY to 1 below. global EVALUATE_ONLY := '0' global max_cpus := $($(nproc)-1) # compile programs gcc aperf.c -Wall -D_GNU_SOURCE -o aperf -lm test $Status -ne 0 && echo "Problem compiling aperf.c." && exit 1 gcc -o msr msr.c -lm test $Status -ne 0 && echo "Problem compiling msr.c." && exit 1 proc run_test { global file_ext := $1 for cpu in [$[seq 0 $max_cpus]] { echo "launching aperf load on $cpu" ./aperf $cpu & } echo "sleeping for 5 seconds" sleep 5 global num_freqs := $[cat /proc/cpuinfo | grep MHz | sort -u | wc -l] if test $num_freqs -le 2 { cat /proc/cpuinfo | grep MHz | sort -u | tail -1 > /tmp/result.$1 } else { cat /proc/cpuinfo | grep MHz | sort -u > /tmp/result.$1 } ./msr 0 >> /tmp/result.$1 global max_perf_pct := $[cat /sys/devices/system/cpu/intel_pstate/max_perf_pct] echo "max_perf_pct $max_perf_pct" >> /tmp/result.$1 for job in [$[jobs -p]] { echo "waiting for job id $job" wait $job } } # # MAIN (ALL UNITS IN MHZ) # # Get the marketing frequency global _mkt_freq := $[cat /proc/cpuinfo | grep -m 1 "model name" | awk '{print $NF}] global _mkt_freq := $[echo $_mkt_freq | tr -d [:alpha:][:punct:]] global mkt_freq := "$(_mkt_freq)0" # Get the ranges from cpupower global _min_freq := $[cpupower frequency-info -l | tail -1 | awk ' { print $1 } ] global min_freq := $($_min_freq / 1000) global _max_freq := $[cpupower frequency-info -l | tail -1 | awk ' { print $2 } ] global max_freq := $($_max_freq / 1000) for freq in [$[seq $max_freq -100 $min_freq]] { echo "Setting maximum frequency to $freq" cpupower frequency-set -g powersave --max=$(freq)MHz > !/dev/null test $EVALUATE_ONLY -eq 0 && run_test $freq } echo "==============================================================================" echo "The marketing frequency of the cpu is $mkt_freq MHz" echo "The maximum frequency of the cpu is $max_freq MHz" echo "The minimum frequency of the cpu is $min_freq MHz" cpupower frequency-set -g powersave --max=$(max_freq)MHz > !/dev/null # make a pretty table echo "Target Actual Difference MSR(0x199) max_perf_pct" for freq in [$[seq $max_freq -100 $min_freq]] { global result_freq := $[cat /tmp/result.$(freq) | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ] global msr := $[cat /tmp/result.$(freq) | grep "msr" | awk ' { print $3 } ] global max_perf_pct := $[cat /tmp/result.$(freq) | grep "max_perf_pct" | awk ' { print $2 } ] if test $result_freq -eq $freq { echo " $freq $result_freq 0 $msr $($max_perf_pct*3300)" } else { echo " $freq $result_freq $($result_freq-$freq) $msr $($max_perf_pct*$max_freq)" } } exit 0 (CommandList children: [ (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:EVALUATE_ONLY) op:Equal rhs:{(0)} spids:[85])] spids: [85] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:max_cpus) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithWord w: { (CommandSubPart command_list: (CommandList children:[(C {(nproc)})]) left_token: spids: [91 93] ) } ) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [90 97] ) } spids: [89] ) ] spids: [89] ) (C {(gcc)} {(aperf.c)} {(-Wall)} {(-D_GNU_SOURCE)} {(-o)} {(aperf)} {(-lm)}) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_QMark "$?")} {(-ne)} {(0)} {(Lit_Other "]")}) (AndOr children: [(C {(echo)} {(DQ ("Problem compiling aperf.c."))}) (C {(exit)} {(1)})] op_id: Op_DAmp ) ] op_id: Op_DAmp ) (C {(gcc)} {(-o)} {(msr)} {(msr.c)} {(-lm)}) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_QMark "$?")} {(-ne)} {(0)} {(Lit_Other "]")}) (AndOr children: [(C {(echo)} {(DQ ("Problem compiling msr.c."))}) (C {(exit)} {(1)})] op_id: Op_DAmp ) ] op_id: Op_DAmp ) (FuncDef name: run_test body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:file_ext) op: Equal rhs: {($ VSub_Number "$1")} spids: [187] ) ] spids: [187] ) (ForEach iter_name: cpu iter_words: [ { (CommandSubPart command_list: (CommandList children: [(C {(seq)} {(0)} {($ VSub_Name "$max_cpus")})] ) left_token: spids: [197 203] ) } ] do_arg_iter: False body: (DoGroup children: [ (C {(echo)} {(DQ ("launching aperf load on ") ($ VSub_Name "$cpu"))}) (Sentence child: (C {(./aperf)} {($ VSub_Name "$cpu")}) terminator: ) ] spids: [206 224] ) spids: [196 -1] ) (C {(echo)} {(DQ ("sleeping for 5 seconds"))}) (C {(sleep)} {(5)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:num_freqs) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cat)} {(/proc/cpuinfo)}) (C {(grep)} {(MHz)}) (C {(sort)} {(-u)}) (C {(wc)} {(-l)}) ] negated: False ) ] ) left_token: spids: [241 263] ) } spids: [240] ) ] spids: [240] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {($ VSub_Name "$num_freqs")} {(-le)} {(2)} {(Lit_Other "]")}) terminator: ) ] action: [ (Pipeline children: [ (C {(cat)} {(/proc/cpuinfo)}) (C {(grep)} {(MHz)}) (C {(sort)} {(-u)}) (SimpleCommand words: [{(tail)} {(-1)}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/tmp/result.) ($ VSub_Number "$1")} spids: [304] ) ] ) ] negated: False ) ] spids: [-1 279] ) ] else_action: [ (Pipeline children: [ (C {(cat)} {(/proc/cpuinfo)}) (C {(grep)} {(MHz)}) (SimpleCommand words: [{(sort)} {(-u)}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/tmp/result.) ($ VSub_Number "$1")} spids: [329] ) ] ) ] negated: False ) ] spids: [310 335] ) (SimpleCommand words: [{(./msr)} {(0)}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(/tmp/result.) ($ VSub_Number "$1")} spids: [342] ) ] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:max_perf_pct) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(cat)} {(/sys/devices/system/cpu/intel_pstate/max_perf_pct)}) ] ) left_token: spids: [350 354] ) } spids: [349] ) ] spids: [349] ) (SimpleCommand words: [{(echo)} {(DQ ("max_perf_pct ") ($ VSub_Name "$max_perf_pct"))}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(/tmp/result.) ($ VSub_Number "$1")} spids: [364] ) ] ) (ForEach iter_name: job iter_words: [ { (CommandSubPart command_list: (CommandList children:[(C {(jobs)} {(-p)})]) left_token: spids: [377 381] ) } ] do_arg_iter: False body: (DoGroup children: [ (C {(echo)} {(DQ ("waiting for job id ") ($ VSub_Name "$job"))}) (C {(wait)} {($ VSub_Name "$job")}) ] spids: [384 400] ) spids: [376 -1] ) ] spids: [183] ) spids: [176 182] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:_mkt_freq) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cat)} {(/proc/cpuinfo)}) (C {(grep)} {(-m)} {(1)} {(DQ ("model name"))}) (C {(awk)} {(SQ <"{print $NF}">)}) ] negated: False ) ] ) left_token: spids: [419 443] ) } spids: [418] ) ] spids: [418] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:_mkt_freq) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$_mkt_freq")}) (C {(tr)} {(-d)} {(Lit_Other "[") (Lit_Other ":") (alpha) (Lit_Other ":") (Lit_Other "]") (Lit_Other "[") (Lit_Other ":") (punct) (Lit_Other ":") (Lit_Other "]") } ) ] negated: False ) ] ) left_token: spids: [446 467] ) } spids: [445] ) ] spids: [445] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:mkt_freq) op: Equal rhs: {(${ VSub_Name _mkt_freq) (0)} spids: [469] ) ] spids: [469] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:_min_freq) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cpupower)} {(frequency-info)} {(-l)}) (C {(tail)} {(-1)}) (C {(awk)} {(SQ <" { print $1 } ">)}) ] negated: False ) ] ) left_token: spids: [480 500] ) } spids: [479] ) ] spids: [479] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:min_freq) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Slash left: (ArithWord w:{($ VSub_Name "$_min_freq")}) right: (ArithWord w:{(Lit_Digits 1000)}) ) spids: [503 510] ) } spids: [502] ) ] spids: [502] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:_max_freq) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cpupower)} {(frequency-info)} {(-l)}) (C {(tail)} {(-1)}) (C {(awk)} {(SQ <" { print $2 } ">)}) ] negated: False ) ] ) left_token: spids: [513 533] ) } spids: [512] ) ] spids: [512] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:max_freq) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Slash left: (ArithWord w:{($ VSub_Name "$_max_freq")}) right: (ArithWord w:{(Lit_Digits 1000)}) ) spids: [536 543] ) } spids: [535] ) ] spids: [535] ) (ForEach iter_name: freq iter_words: [ { (CommandSubPart command_list: (CommandList children: [(C {(seq)} {($ VSub_Name "$max_freq")} {(-100)} {($ VSub_Name "$min_freq")})] ) left_token: spids: [553 561] ) } ] do_arg_iter: False body: (DoGroup children: [ (C {(echo)} {(DQ ("Setting maximum frequency to ") ($ VSub_Name "$freq"))}) (SimpleCommand words: [ {(cpupower)} {(frequency-set)} {(-g)} {(powersave)} {(--max) (Lit_Other "=") (${ VSub_Name freq) (MHz)} ] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(/dev/null)} spids:[589])] ) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_Name "$EVALUATE_ONLY")} {(-eq)} {(0)} {(Lit_Other "]")}) (C {(run_test)} {($ VSub_Name "$freq")}) ] op_id: Op_DAmp ) ] spids: [563 610] ) spids: [552 -1] ) (C {(echo)} {(DQ ("=============================================================================="))} ) (C {(echo)} {(DQ ("The marketing frequency of the cpu is ") ($ VSub_Name "$mkt_freq") (" MHz"))}) (C {(echo)} {(DQ ("The maximum frequency of the cpu is ") ($ VSub_Name "$max_freq") (" MHz"))}) (C {(echo)} {(DQ ("The minimum frequency of the cpu is ") ($ VSub_Name "$min_freq") (" MHz"))}) (SimpleCommand words: [ {(cpupower)} {(frequency-set)} {(-g)} {(powersave)} {(--max) (Lit_Other "=") (${ VSub_Name max_freq) (MHz)} ] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(/dev/null)} spids:[660])] ) (C {(echo)} {(DQ ("Target Actual Difference MSR(0x199) max_perf_pct"))}) (ForEach iter_name: freq iter_words: [ { (CommandSubPart command_list: (CommandList children: [(C {(seq)} {($ VSub_Name "$max_freq")} {(-100)} {($ VSub_Name "$min_freq")})] ) left_token: spids: [680 688] ) } ] do_arg_iter: False body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:result_freq) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cat)} {(/tmp/result.) (${ VSub_Name freq)}) (C {(grep)} {(DQ ("cpu MHz"))}) (C {(awk)} {(SQ <" { print $4 } ">)}) (C {(awk)} {(-F)} {(DQ (.))} {(SQ <" { print $1 } ">)}) ] negated: False ) ] ) left_token: spids: [694 731] ) } spids: [693] ) ] spids: [693] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:msr) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cat)} {(/tmp/result.) (${ VSub_Name freq)}) (C {(grep)} {(DQ (msr))}) (C {(awk)} {(SQ <" { print $3 } ">)}) ] negated: False ) ] ) left_token: spids: [735 758] ) } spids: [734] ) ] spids: [734] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:max_perf_pct) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(cat)} {(/tmp/result.) (${ VSub_Name freq)}) (C {(grep)} {(DQ (max_perf_pct))}) (C {(awk)} {(SQ <" { print $2 } ">)}) ] negated: False ) ] ) left_token: spids: [762 786] ) } spids: [761] ) ] spids: [761] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {($ VSub_Name "$result_freq")} {(-eq)} {($ VSub_Name "$freq")} {(Lit_Other "]")} ) terminator: ) ] action: [ (C {(echo)} { (DQ (" ") ($ VSub_Name "$freq") (" ") ($ VSub_Name "$result_freq") (" 0 ") ($ VSub_Name "$msr") (" ") (ArithSubPart anode: (ArithBinary op_id: Arith_Star left: (ArithWord w:{($ VSub_Name "$max_perf_pct")}) right: (ArithWord w:{(Lit_Digits 3300)}) ) spids: [815 820] ) ) } ) ] spids: [-1 802] ) ] else_action: [ (C {(echo)} { (DQ (" ") ($ VSub_Name "$freq") (" ") ($ VSub_Name "$result_freq") (" ") (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithWord w:{($ VSub_Name "$result_freq")}) right: (ArithWord w:{($ VSub_Name "$freq")}) ) spids: [835 840] ) (" ") ($ VSub_Name "$msr") (" ") (ArithSubPart anode: (ArithBinary op_id: Arith_Star left: (ArithWord w:{($ VSub_Name "$max_perf_pct")}) right: (ArithWord w:{($ VSub_Name "$max_freq")}) ) spids: [844 849] ) ) } ) ] spids: [824 853] ) ] spids: [690 855] ) spids: [679 -1] ) (C {(exit)} {(0)}) ] )