Skip to content

Commit 8bea8be

Browse files
authored
add speed select turbo frequency tables (#211)
1 parent ef8b700 commit 8bea8be

File tree

3 files changed

+210
-6
lines changed

3 files changed

+210
-6
lines changed

cmd/report/report.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ var (
6060
flagTurbo bool
6161
flagUncore bool
6262
flagElc bool
63+
flagSST bool
6364
flagMemory bool
6465
flagDimm bool
6566
flagNic bool
@@ -99,6 +100,7 @@ const (
99100
flagTurboName = "turbo"
100101
flagUncoreName = "uncore"
101102
flagElcName = "elc"
103+
flagSSTName = "sst"
102104
flagMemoryName = "memory"
103105
flagDimmName = "dimm"
104106
flagNicName = "nic"
@@ -157,6 +159,7 @@ var categories = []common.Category{
157159
{FlagName: flagPowerName, FlagVar: &flagPower, Help: "Power Settings", TableNames: []string{report.PowerTableName}},
158160
{FlagName: flagCstatesName, FlagVar: &flagCstates, Help: "C-states", TableNames: []string{report.CstateTableName}},
159161
{FlagName: flagTurboName, FlagVar: &flagTurbo, Help: "Turbo Frequency", TableNames: []string{report.CoreTurboFrequencyTableName}},
162+
{FlagName: flagSSTName, FlagVar: &flagSST, Help: "Speed Select Technology Settings", TableNames: []string{report.SSTTFHPTableName, report.SSTTFLPTableName}},
160163
{FlagName: flagUncoreName, FlagVar: &flagUncore, Help: "Uncore Configuration", TableNames: []string{report.UncoreTableName}},
161164
{FlagName: flagElcName, FlagVar: &flagElc, Help: "Efficiency Latency Control Settings", TableNames: []string{report.ElcTableName}},
162165
{FlagName: flagMemoryName, FlagVar: &flagMemory, Help: "Memory Configuration", TableNames: []string{report.MemoryTableName}},

internal/report/table_defs.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ const (
7979
PowerTableName = "Power"
8080
CstateTableName = "C-states"
8181
CoreTurboFrequencyTableName = "Core Turbo Frequency"
82+
SSTTFHPTableName = "Speed Select Turbo Frequency - High Priority Cores"
83+
SSTTFLPTableName = "Speed Select Turbo Frequency - Low Priority Cores"
8284
UncoreTableName = "Uncore"
8385
ElcTableName = "Efficiency Latency Control"
8486
MemoryTableName = "Memory"
@@ -269,6 +271,20 @@ var tableDefinitions = map[string]TableDefinition{
269271
},
270272
FieldsFunc: elcTableValues,
271273
InsightsFunc: elcTableInsights},
274+
SSTTFHPTableName: {
275+
Name: SSTTFHPTableName,
276+
HasRows: true,
277+
ScriptNames: []string{
278+
script.SstTfHighPriorityCoreFrequenciesScriptName,
279+
},
280+
FieldsFunc: sstTFHPTableValues},
281+
SSTTFLPTableName: {
282+
Name: SSTTFLPTableName,
283+
HasRows: true,
284+
ScriptNames: []string{
285+
script.SstTfLowPriorityCoreFrequenciesScriptName,
286+
},
287+
FieldsFunc: sstTFLPTableValues},
272288
MemoryTableName: {
273289
Name: MemoryTableName,
274290
HasRows: false,
@@ -1079,6 +1095,84 @@ func coreTurboFrequencyTableValues(outputs map[string]script.ScriptOutput) []Fie
10791095
return fields
10801096
}
10811097

1098+
func sstTFHPTableValues(outputs map[string]script.ScriptOutput) []Field {
1099+
output := outputs[script.SstTfHighPriorityCoreFrequenciesScriptName].Stdout
1100+
if len(output) == 0 {
1101+
return []Field{}
1102+
}
1103+
lines := strings.Split(output, "\n")
1104+
if len(lines) >= 1 && (strings.Contains(lines[0], "not supported") || strings.Contains(lines[0], "not enabled")) {
1105+
return []Field{}
1106+
}
1107+
// lines should contain CSV formatted data
1108+
fields := []Field{}
1109+
for i, line := range lines {
1110+
// field names are in the header
1111+
if i == 0 {
1112+
fieldNames := strings.Split(line, ",")
1113+
for j, fieldName := range fieldNames {
1114+
if j > 1 {
1115+
fieldName = fieldName + " (MHz)"
1116+
}
1117+
fields = append(fields, Field{Name: fieldName})
1118+
}
1119+
continue
1120+
}
1121+
// skip empty lines
1122+
if line == "" {
1123+
continue
1124+
}
1125+
values := strings.Split(line, ",")
1126+
if len(values) != len(fields) {
1127+
slog.Warn("unexpected number of values in line", slog.String("line", line))
1128+
continue
1129+
}
1130+
for j, value := range values {
1131+
if j > 1 {
1132+
value = value + "00"
1133+
}
1134+
fields[j].Values = append(fields[j].Values, value)
1135+
}
1136+
}
1137+
return fields
1138+
}
1139+
1140+
func sstTFLPTableValues(outputs map[string]script.ScriptOutput) []Field {
1141+
output := outputs[script.SstTfLowPriorityCoreFrequenciesScriptName].Stdout
1142+
if len(output) == 0 {
1143+
return []Field{}
1144+
}
1145+
lines := strings.Split(output, "\n")
1146+
if len(lines) >= 1 && (strings.Contains(lines[0], "not supported") || strings.Contains(lines[0], "not enabled")) {
1147+
return []Field{}
1148+
}
1149+
// lines should contain CSV formatted data
1150+
fields := []Field{}
1151+
for i, line := range lines {
1152+
// field names are in the header
1153+
if i == 0 {
1154+
fieldNames := strings.Split(line, ",")
1155+
for _, fieldName := range fieldNames {
1156+
fields = append(fields, Field{Name: fieldName + " (MHz)"})
1157+
}
1158+
continue
1159+
}
1160+
// skip empty lines
1161+
if line == "" {
1162+
continue
1163+
}
1164+
values := strings.Split(line, ",")
1165+
if len(values) != len(fields) {
1166+
slog.Warn("unexpected number of values in line", slog.String("line", line))
1167+
continue
1168+
}
1169+
for j, value := range values {
1170+
fields[j].Values = append(fields[j].Values, value+"00")
1171+
}
1172+
}
1173+
return fields
1174+
}
1175+
10821176
func memoryTableValues(outputs map[string]script.ScriptOutput) []Field {
10831177
return []Field{
10841178
{Name: "Installed Memory", Values: []string{installedMemoryFromOutput(outputs)}},

internal/script/script_defs.go

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ const (
8282
UncoreMaxFromTPMIScriptName = "uncore max from tpmi"
8383
UncoreMinFromTPMIScriptName = "uncore min from tpmi"
8484
ElcScriptName = "efficiency latency control"
85+
SstTfHighPriorityCoreFrequenciesScriptName = "sst tf high priority core frequencies"
86+
SstTfLowPriorityCoreFrequenciesScriptName = "sst tf low priority core frequencies"
8587
ChaCountScriptName = "cha count"
8688
MeminfoScriptName = "meminfo"
8789
TransparentHugePagesScriptName = "transparent huge pages"
@@ -274,21 +276,41 @@ else
274276
fi`,
275277
},
276278
{
277-
Name: SpecTurboCoresScriptName,
278-
Script: "rdmsr 0x1ae", // MSR_TURBO_GROUP_CORE_CNT: Group Size of Active Cores for Turbo Mode Operation
279+
Name: SpecTurboCoresScriptName,
280+
Script: `#!/bin/bash
281+
# if SST-TF is supported and enabled, then the MSR values are not valid
282+
supported=$(pcm-tpmi 5 0xF8 -d -b 12:12 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
283+
if [ "$supported" -eq 1 ]; then
284+
enabled=$(pcm-tpmi 5 0x78 -d -b 9:9 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
285+
if [ "$enabled" -eq 1 ]; then
286+
exit 0
287+
fi
288+
fi
289+
rdmsr 0x1ae # MSR_TURBO_GROUP_CORE_CNT: Group Size of Active Cores for Turbo Mode Operation
290+
`,
279291
Architectures: []string{x86_64},
280292
Families: []string{"6"}, // Intel
281293
Lkms: []string{"msr"},
282-
Depends: []string{"rdmsr"},
294+
Depends: []string{"rdmsr", "pcm-tpmi"},
283295
Superuser: true,
284296
},
285297
{
286-
Name: SpecTurboFrequenciesScriptName,
287-
Script: "rdmsr 0x1ad", // MSR_TURBO_RATIO_LIMIT: Maximum Ratio Limit of Turbo Mode
298+
Name: SpecTurboFrequenciesScriptName,
299+
Script: `#!/bin/bash
300+
# if SST-TF is supported and enabled, then the MSR values are not valid
301+
supported=$(pcm-tpmi 5 0xF8 -d -b 12:12 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
302+
if [ "$supported" -eq 1 ]; then
303+
enabled=$(pcm-tpmi 5 0x78 -d -b 9:9 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
304+
if [ "$enabled" -eq 1 ]; then
305+
exit 0
306+
fi
307+
fi
308+
rdmsr 0x1ad # MSR_TURBO_RATIO_LIMIT: Maximum Ratio Limit of Turbo Mode
309+
`,
288310
Architectures: []string{x86_64},
289311
Families: []string{"6"}, // Intel
290312
Lkms: []string{"msr"},
291-
Depends: []string{"rdmsr"},
313+
Depends: []string{"rdmsr", "pcm-tpmi"},
292314
Superuser: true,
293315
},
294316
{
@@ -488,6 +510,91 @@ done
488510
Depends: []string{"pcm-tpmi"},
489511
Superuser: true,
490512
},
513+
{
514+
Name: SstTfHighPriorityCoreFrequenciesScriptName,
515+
Script: `#!/bin/bash
516+
# Is SST-TF supported?
517+
supported=$(pcm-tpmi 5 0xF8 -d -b 12:12 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
518+
if [ "$supported" -eq 0 ]; then
519+
echo "SST-TF is not supported"
520+
exit 0
521+
fi
522+
# Is SST-TF enabled?
523+
enabled=$(pcm-tpmi 5 0x78 -d -b 9:9 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
524+
if [ "$enabled" -eq 0 ]; then
525+
echo "SST-TF is not enabled"
526+
exit 0
527+
fi
528+
echo "bucket,cores,AVX,AVX2,AVX-512,AVX-512 heavy,AMX"
529+
# up to 5 buckets
530+
for ((i=0; i<5; i++))
531+
do
532+
# Get the # of cores in this bucket
533+
bithigh=$((i*8+7))
534+
bitlow=$((i*8))
535+
numcores=$(pcm-tpmi 5 0x100 -d -b $bithigh:$bitlow -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
536+
# if the number of cores is 0, skip this bucket
537+
if [ "$numcores" -eq 0 ]; then
538+
continue
539+
fi
540+
echo -n "$i,$numcores,"
541+
# Get the frequencies for this bucket
542+
bithigh=$((i*8+7)) # 8 bits per frequency
543+
bitlow=$((i*8))
544+
# 5 isa frequencies per bucket (AVX, AVX2, AVX-512, AVX-512 heavy, AMX)
545+
for((j=0; j<5; j++))
546+
do
547+
offset=$((j*8 + 264)) # 264 is 0x108 (SST_TF_INFO_2) AVX
548+
freq=$(pcm-tpmi 5 $offset -d -b $bithigh:$bitlow -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
549+
echo -n "$freq"
550+
if [ $j -lt 4 ]; then
551+
echo -n ","
552+
fi
553+
done
554+
echo "" # finish the line
555+
done
556+
`,
557+
Architectures: []string{x86_64},
558+
Families: []string{"6"}, // Intel
559+
Models: []string{"173"}, // GNR
560+
Depends: []string{"pcm-tpmi"},
561+
Superuser: true,
562+
},
563+
{
564+
Name: SstTfLowPriorityCoreFrequenciesScriptName,
565+
Script: `#!/bin/bash
566+
# Is SST-TF supported?
567+
supported=$(pcm-tpmi 5 0xF8 -d -b 12:12 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
568+
if [ "$supported" -eq 0 ]; then
569+
echo "SST-TF is not supported"
570+
exit 0
571+
fi
572+
# Is SST-TF enabled?
573+
enabled=$(pcm-tpmi 5 0x78 -d -b 9:9 -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
574+
if [ "$enabled" -eq 0 ]; then
575+
echo "SST-TF is not enabled"
576+
exit 0
577+
fi
578+
echo "AVX,AVX2,AVX-512,AVX-512 heavy,AMX"
579+
# Get the low priority core clip ratios (frequencies)
580+
for((j=0; j<5; j++))
581+
do
582+
bithigh=$((j*8+23))
583+
bitlow=$((j*8+16))
584+
freq=$(pcm-tpmi 5 0xF8 -d -b $bithigh:$bitlow -i 0 -e 0 | tail -n 2 | head -n 1 | awk '{print $5}')
585+
echo -n "$freq"
586+
if [ $j -ne 4 ]; then
587+
echo -n ","
588+
fi
589+
done
590+
echo "" # finish the line
591+
`,
592+
Architectures: []string{x86_64},
593+
Families: []string{"6"}, // Intel
594+
Models: []string{"173"}, // GNR
595+
Depends: []string{"pcm-tpmi"},
596+
Superuser: true,
597+
},
491598
{
492599
Name: ChaCountScriptName,
493600
Script: `rdmsr 0x396

0 commit comments

Comments
 (0)