From cc1255b6765cfa2f630a408dc120a3654e70fe46 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 14:56:34 -0800 Subject: [PATCH 01/15] update - ELC default mode now called power optimized Signed-off-by: Harper, Jason M --- cmd/config/flag_groups.go | 2 +- cmd/config/restore.go | 2 +- cmd/config/set.go | 2 +- internal/extract/power.go | 4 ++-- tools/Makefile | 7 ++++++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cmd/config/flag_groups.go b/cmd/config/flag_groups.go index 114286ae..b3a6ee89 100644 --- a/cmd/config/flag_groups.go +++ b/cmd/config/flag_groups.go @@ -76,7 +76,7 @@ const ( var governorOptions = []string{"performance", "powersave"} // elcOptions - list of valid elc options -var elcOptions = []string{"latency-optimized", "default"} +var elcOptions = []string{"latency-optimized", "power-optimized"} // prefetcherOptions - list of valid prefetcher options var prefetcherOptions = []string{"enable", "disable"} diff --git a/cmd/config/restore.go b/cmd/config/restore.go index c6e22b63..ca2bb330 100644 --- a/cmd/config/restore.go +++ b/cmd/config/restore.go @@ -353,7 +353,7 @@ func convertValue(flagName string, rawValue string) (string, error) { // "performance" or "powersave" return parseEnableDisableOrOption(rawValue, governorOptions) case flagELCName: - // "Default" -> "default" + // "Power-Optimized" -> "power-optimized" // "Latency-Optimized" -> "latency-optimized" rawValueLower := strings.ToLower(rawValue) if slices.Contains(elcOptions, rawValueLower) { diff --git a/cmd/config/set.go b/cmd/config/set.go index 96699308..75052bd6 100644 --- a/cmd/config/set.go +++ b/cmd/config/set.go @@ -781,7 +781,7 @@ func setELC(elc string, myTarget target.Target, localTempDir string) error { case elcOptions[0]: mode = "latency-optimized-mode" case elcOptions[1]: - mode = "default" + mode = "optimized-power-mode" default: return fmt.Errorf("invalid ELC mode: %s", elc) } diff --git a/internal/extract/power.go b/internal/extract/power.go index 7f0d9983..18fb4087 100644 --- a/internal/extract/power.go +++ b/internal/extract/power.go @@ -204,7 +204,7 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu if row[5] == "0" && row[6] == "0" && row[7] == "0" { mode = "Latency Optimized" } else if row[5] == "800" && row[6] == "10" && row[7] == "94" { - mode = "Default" + mode = "Power Optimized" } else { mode = "Custom" } @@ -213,7 +213,7 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu case "0": mode = "Latency Optimized" case "1200": - mode = "Default" + mode = "Power Optimized" default: mode = "Custom" } diff --git a/tools/Makefile b/tools/Makefile index f7b46bd0..f5a4eb51 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -41,7 +41,7 @@ tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw cp msr-tools/rdmsr bin/x86_64/ cp msr-tools/wrmsr bin/x86_64/ cp pcm/build/bin/pcm-tpmi bin/x86_64/ - cp pcm/scripts/bhs-power-mode.sh bin/x86_64/ + cp bhs-power-mode.sh bin/x86_64/ cp perf-archive/perf-archive.sh bin/x86_64/perf-archive && chmod +rx bin/x86_64/perf-archive cp spectre-meltdown-checker/spectre-meltdown-checker.sh bin/x86_64/ cp sshpass/sshpass bin/x86_64/ @@ -316,6 +316,11 @@ endif cd pcm/build && cmake -DNO_ASAN=1 .. cd pcm/build && cmake --build . +PCM_BHS_POWER_MODE_VERSION := 8fdf97bc9636792e05e4be82421efc1c9aec980f +bhs-power-mode.sh: + wget $(WGET_OPTS) https://raw.githubusercontent.com/intel/pcm/$(PCM_BHS_POWER_MODE_VERSION)/scripts/bhs-power-mode.sh + chmod +x bhs-power-mode.sh + PERF_VERSION := 6.15.3 linux-$(PERF_VERSION).tar.xz: wget $(WGET_OPTS) https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$(PERF_VERSION).tar.xz From 9b2d405f220e27d87b983eb47b5c7e7035e0c829 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 14:58:33 -0800 Subject: [PATCH 02/15] config table Signed-off-by: Harper, Jason M --- cmd/config/config_tables.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/config/config_tables.go b/cmd/config/config_tables.go index 58f06bfe..2870da2c 100644 --- a/cmd/config/config_tables.go +++ b/cmd/config/config_tables.go @@ -91,7 +91,7 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi }...) // add ELC (for SRF, CWF and GNR only) if strings.Contains(uarch, cpus.UarchSRF) || strings.Contains(uarch, cpus.UarchGNR) || strings.Contains(uarch, cpus.UarchCWF) { - fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc ", Values: []string{extract.ELCSummaryFromOutput(outputs)}}) + fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc ", Values: []string{extract.ELCSummaryFromOutput(outputs)}}) } // add prefetchers for _, pf := range extract.PrefetcherDefinitions { From 06c4273875febd67946b59849cf596fad044f5ea Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 15:34:03 -0800 Subject: [PATCH 03/15] fix: add bhs-power-mode.sh to x86_64 tools target Signed-off-by: Harper, Jason M --- tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index f5a4eb51..3fe5e9fc 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -25,7 +25,7 @@ default: tools-x86_64 .PHONY: sysstat sysstat-aarch64 sysstat-repo .PHONY: tsc turbostat -tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw lspci msr-tools pcm spectre-meltdown-checker sshpass stackcollapse-perf stress-ng sysstat tsc turbostat +tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw lspci msr-tools pcm bhs-power-mode.sh spectre-meltdown-checker sshpass stackcollapse-perf stress-ng sysstat tsc turbostat mkdir -p bin/x86_64 cp -R async-profiler bin/x86_64/ cp avx-turbo/avx-turbo bin/x86_64/ From b3b1e3e989c093c7238bb1740f105bc60a8947d6 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 16:24:14 -0800 Subject: [PATCH 04/15] fix unit test Signed-off-by: Harper, Jason M --- cmd/config/restore_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/config/restore_test.go b/cmd/config/restore_test.go index 056536fb..0f1aea13 100644 --- a/cmd/config/restore_test.go +++ b/cmd/config/restore_test.go @@ -142,8 +142,8 @@ func TestConvertValue(t *testing.T) { {"Prefetcher enabled", "pref-l2hw", "Enabled", "enable", false}, {"Prefetcher disabled", "pref-l2hw", "Disabled", "disable", false}, {"C6 enabled", "c6", "Enabled", "enable", false}, - {"ELC lowercase", "elc", "default", "default", false}, - {"ELC capitalized", "elc", "Default", "default", false}, + {"ELC lowercase", "elc", "power-optimized", "power-optimized", false}, + {"ELC capitalized", "elc", "Power-Optimized", "power-optimized", false}, {"Core SSE freq buckets", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4", "1-44/3.6, 45-52/3.5, 53-60/3.4", false}, {"Core SSE freq buckets full", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", false}, {"Core SSE freq buckets invalid", "core-max-buckets", "invalid-format", "", true}, From fde8a8b72b643c98c3aee73d5de360af9222e313 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Thu, 22 Jan 2026 07:40:00 -0800 Subject: [PATCH 05/15] fix: update recommendation for Efficiency Latency Control mode to 'Power Optimized' Signed-off-by: Harper, Jason M --- cmd/report/report_tables.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/report/report_tables.go b/cmd/report/report_tables.go index 8c1f8584..5f2f008e 100644 --- a/cmd/report/report_tables.go +++ b/cmd/report/report_tables.go @@ -862,9 +862,9 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table. } } for _, mode := range tableValues.Fields[modeFieldIndex].Values { - if mode != "" && mode != "Default" { + if mode != "" && mode != "Power Optimized" { insights = append(insights, table.Insight{ - Recommendation: "Consider setting Efficiency Latency Control mode to 'Default' to balance uncore performance and power utilization.", + Recommendation: "Consider setting Efficiency Latency Control mode to 'Power Optimized' to balance uncore performance and power utilization.", Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode), }) break From 9c7f8a24a929959ed1330fd844021a3a5d096015 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 14:56:34 -0800 Subject: [PATCH 06/15] update - ELC default mode now called power optimized Signed-off-by: Harper, Jason M --- cmd/config/flag_groups.go | 2 +- cmd/config/restore.go | 2 +- cmd/config/set.go | 2 +- internal/extract/power.go | 4 ++-- tools/Makefile | 7 ++++++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/cmd/config/flag_groups.go b/cmd/config/flag_groups.go index 114286ae..b3a6ee89 100644 --- a/cmd/config/flag_groups.go +++ b/cmd/config/flag_groups.go @@ -76,7 +76,7 @@ const ( var governorOptions = []string{"performance", "powersave"} // elcOptions - list of valid elc options -var elcOptions = []string{"latency-optimized", "default"} +var elcOptions = []string{"latency-optimized", "power-optimized"} // prefetcherOptions - list of valid prefetcher options var prefetcherOptions = []string{"enable", "disable"} diff --git a/cmd/config/restore.go b/cmd/config/restore.go index c6e22b63..ca2bb330 100644 --- a/cmd/config/restore.go +++ b/cmd/config/restore.go @@ -353,7 +353,7 @@ func convertValue(flagName string, rawValue string) (string, error) { // "performance" or "powersave" return parseEnableDisableOrOption(rawValue, governorOptions) case flagELCName: - // "Default" -> "default" + // "Power-Optimized" -> "power-optimized" // "Latency-Optimized" -> "latency-optimized" rawValueLower := strings.ToLower(rawValue) if slices.Contains(elcOptions, rawValueLower) { diff --git a/cmd/config/set.go b/cmd/config/set.go index 96699308..75052bd6 100644 --- a/cmd/config/set.go +++ b/cmd/config/set.go @@ -781,7 +781,7 @@ func setELC(elc string, myTarget target.Target, localTempDir string) error { case elcOptions[0]: mode = "latency-optimized-mode" case elcOptions[1]: - mode = "default" + mode = "optimized-power-mode" default: return fmt.Errorf("invalid ELC mode: %s", elc) } diff --git a/internal/extract/power.go b/internal/extract/power.go index 7f0d9983..18fb4087 100644 --- a/internal/extract/power.go +++ b/internal/extract/power.go @@ -204,7 +204,7 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu if row[5] == "0" && row[6] == "0" && row[7] == "0" { mode = "Latency Optimized" } else if row[5] == "800" && row[6] == "10" && row[7] == "94" { - mode = "Default" + mode = "Power Optimized" } else { mode = "Custom" } @@ -213,7 +213,7 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu case "0": mode = "Latency Optimized" case "1200": - mode = "Default" + mode = "Power Optimized" default: mode = "Custom" } diff --git a/tools/Makefile b/tools/Makefile index f7b46bd0..f5a4eb51 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -41,7 +41,7 @@ tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw cp msr-tools/rdmsr bin/x86_64/ cp msr-tools/wrmsr bin/x86_64/ cp pcm/build/bin/pcm-tpmi bin/x86_64/ - cp pcm/scripts/bhs-power-mode.sh bin/x86_64/ + cp bhs-power-mode.sh bin/x86_64/ cp perf-archive/perf-archive.sh bin/x86_64/perf-archive && chmod +rx bin/x86_64/perf-archive cp spectre-meltdown-checker/spectre-meltdown-checker.sh bin/x86_64/ cp sshpass/sshpass bin/x86_64/ @@ -316,6 +316,11 @@ endif cd pcm/build && cmake -DNO_ASAN=1 .. cd pcm/build && cmake --build . +PCM_BHS_POWER_MODE_VERSION := 8fdf97bc9636792e05e4be82421efc1c9aec980f +bhs-power-mode.sh: + wget $(WGET_OPTS) https://raw.githubusercontent.com/intel/pcm/$(PCM_BHS_POWER_MODE_VERSION)/scripts/bhs-power-mode.sh + chmod +x bhs-power-mode.sh + PERF_VERSION := 6.15.3 linux-$(PERF_VERSION).tar.xz: wget $(WGET_OPTS) https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$(PERF_VERSION).tar.xz From 73fb9b75da4fb016137ec3450b5fe12d704a3639 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 14:58:33 -0800 Subject: [PATCH 07/15] config table Signed-off-by: Harper, Jason M --- cmd/config/config_tables.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/config/config_tables.go b/cmd/config/config_tables.go index 58f06bfe..2870da2c 100644 --- a/cmd/config/config_tables.go +++ b/cmd/config/config_tables.go @@ -91,7 +91,7 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi }...) // add ELC (for SRF, CWF and GNR only) if strings.Contains(uarch, cpus.UarchSRF) || strings.Contains(uarch, cpus.UarchGNR) || strings.Contains(uarch, cpus.UarchCWF) { - fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc ", Values: []string{extract.ELCSummaryFromOutput(outputs)}}) + fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc ", Values: []string{extract.ELCSummaryFromOutput(outputs)}}) } // add prefetchers for _, pf := range extract.PrefetcherDefinitions { From 9ee27ab9421c6da38848b6c4b11a6cb03b6272a3 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 15:34:03 -0800 Subject: [PATCH 08/15] fix: add bhs-power-mode.sh to x86_64 tools target Signed-off-by: Harper, Jason M --- tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index f5a4eb51..3fe5e9fc 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -25,7 +25,7 @@ default: tools-x86_64 .PHONY: sysstat sysstat-aarch64 sysstat-repo .PHONY: tsc turbostat -tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw lspci msr-tools pcm spectre-meltdown-checker sshpass stackcollapse-perf stress-ng sysstat tsc turbostat +tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw lspci msr-tools pcm bhs-power-mode.sh spectre-meltdown-checker sshpass stackcollapse-perf stress-ng sysstat tsc turbostat mkdir -p bin/x86_64 cp -R async-profiler bin/x86_64/ cp avx-turbo/avx-turbo bin/x86_64/ From d092f8cf906abda4553b446facc025c60812ba12 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 21 Jan 2026 16:24:14 -0800 Subject: [PATCH 09/15] fix unit test Signed-off-by: Harper, Jason M --- cmd/config/restore_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/config/restore_test.go b/cmd/config/restore_test.go index 056536fb..0f1aea13 100644 --- a/cmd/config/restore_test.go +++ b/cmd/config/restore_test.go @@ -142,8 +142,8 @@ func TestConvertValue(t *testing.T) { {"Prefetcher enabled", "pref-l2hw", "Enabled", "enable", false}, {"Prefetcher disabled", "pref-l2hw", "Disabled", "disable", false}, {"C6 enabled", "c6", "Enabled", "enable", false}, - {"ELC lowercase", "elc", "default", "default", false}, - {"ELC capitalized", "elc", "Default", "default", false}, + {"ELC lowercase", "elc", "power-optimized", "power-optimized", false}, + {"ELC capitalized", "elc", "Power-Optimized", "power-optimized", false}, {"Core SSE freq buckets", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4", "1-44/3.6, 45-52/3.5, 53-60/3.4", false}, {"Core SSE freq buckets full", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", false}, {"Core SSE freq buckets invalid", "core-max-buckets", "invalid-format", "", true}, From b442e574dd1f3f9d1776ce41e5ec5c6b508de9a5 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Thu, 22 Jan 2026 07:40:00 -0800 Subject: [PATCH 10/15] fix: update recommendation for Efficiency Latency Control mode to 'Power Optimized' Signed-off-by: Harper, Jason M --- cmd/report/report_tables.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/report/report_tables.go b/cmd/report/report_tables.go index f4672898..c0ef2cbb 100644 --- a/cmd/report/report_tables.go +++ b/cmd/report/report_tables.go @@ -862,9 +862,9 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table. } } for _, mode := range tableValues.Fields[modeFieldIndex].Values { - if mode != "" && mode != "Default" { + if mode != "" && mode != "Power Optimized" { insights = append(insights, table.Insight{ - Recommendation: "Consider setting Efficiency Latency Control mode to 'Default' to balance uncore performance and power utilization.", + Recommendation: "Consider setting Efficiency Latency Control mode to 'Power Optimized' to balance uncore performance and power utilization.", Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode), }) break From 4cce9c24123f50d63c9191c6884aa72741b9b14f Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Sun, 25 Jan 2026 05:00:43 -0800 Subject: [PATCH 11/15] refactor: update ELC options and improve mode handling in configuration Signed-off-by: Harper, Jason M --- cmd/config/flag_groups.go | 2 +- cmd/config/restore.go | 9 +--- cmd/config/set.go | 87 +++++++++++++++++++++++++++++++------ cmd/report/report_tables.go | 22 +++++++--- internal/extract/power.go | 59 ++++++++++++++++--------- internal/script/scripts.go | 4 +- 6 files changed, 133 insertions(+), 50 deletions(-) diff --git a/cmd/config/flag_groups.go b/cmd/config/flag_groups.go index b3a6ee89..91a15521 100644 --- a/cmd/config/flag_groups.go +++ b/cmd/config/flag_groups.go @@ -76,7 +76,7 @@ const ( var governorOptions = []string{"performance", "powersave"} // elcOptions - list of valid elc options -var elcOptions = []string{"latency-optimized", "power-optimized"} +var elcOptions = []string{"latency", "power"} // prefetcherOptions - list of valid prefetcher options var prefetcherOptions = []string{"enable", "disable"} diff --git a/cmd/config/restore.go b/cmd/config/restore.go index ca2bb330..f12729a1 100644 --- a/cmd/config/restore.go +++ b/cmd/config/restore.go @@ -353,13 +353,8 @@ func convertValue(flagName string, rawValue string) (string, error) { // "performance" or "powersave" return parseEnableDisableOrOption(rawValue, governorOptions) case flagELCName: - // "Power-Optimized" -> "power-optimized" - // "Latency-Optimized" -> "latency-optimized" - rawValueLower := strings.ToLower(rawValue) - if slices.Contains(elcOptions, rawValueLower) { - return rawValueLower, nil - } - return "", fmt.Errorf("invalid elc value: %s", rawValue) + // "power" or "latency" + return parseEnableDisableOrOption(rawValue, elcOptions) case flagC6Name: return parseEnableDisableOrOption(rawValue, c6Options) case flagC1DemotionName: diff --git a/cmd/config/set.go b/cmd/config/set.go index 75052bd6..4b44dd41 100644 --- a/cmd/config/set.go +++ b/cmd/config/set.go @@ -775,31 +775,92 @@ func setGovernor(governor string, myTarget target.Target, localTempDir string) e return err } -func setELC(elc string, myTarget target.Target, localTempDir string) error { - var mode string - switch elc { - case elcOptions[0]: - mode = "latency-optimized-mode" - case elcOptions[1]: - mode = "optimized-power-mode" - default: - return fmt.Errorf("invalid ELC mode: %s", elc) +// setELCOPM sets ELC to Optimized Power Mode (OPM) +func setELCOPM(myTarget target.Target, localTempDir string) error { + setScript := script.ScriptDefinition{ + Name: "set elc opm", + ScriptTemplate: ` +# determine I/O and compute dies +output=$(pcm-tpmi 2 0x10 -d -b 26:26) + +# Parse the output to build lists of I/O and compute dies +io_dies=() +compute_dies=() +declare -A die_types +while read -r line; do + if [[ $line == *"instance 0"* ]]; then + die=$(echo "$line" | grep -oP 'entry \K[0-9]+') + if [[ $line == *"value 1"* ]]; then + die_types[$die]="IO" + io_dies+=("$die") + elif [[ $line == *"value 0"* ]]; then + die_types[$die]="Compute" + compute_dies+=("$die") + fi + fi +done <<< "$output" + +# Set ELC parameters for I/O and Compute dies +# set values common to both die types +pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE +pcm-tpmi 2 0x18 -d -b 46:40 -w 95 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD +pcm-tpmi 2 0x18 -d -b 38:32 -w 10 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD + +# set values for I/O Dies +for die in "${io_dies[@]}"; do + pcm-tpmi 2 0x18 -d -e $die -b 28:22 -w 8 # EFFICIENCY_LATENCY_CTRL_RATIO 0.8 GHz for I/O Dies +done + +# set values for Compute Dies +for die in "${compute_dies[@]}"; do + pcm-tpmi 2 0x18 -d -e $die -b 28:22 -w 12 # EFFICIENCY_LATENCY_CTRL_RATIO 1.2 GHz for Compute Dies +done +`, + Superuser: true, + Vendors: []string{cpus.IntelVendor}, + MicroArchitectures: []string{cpus.UarchGNR, cpus.UarchGNR_D, cpus.UarchSRF, cpus.UarchCWF}, + Depends: []string{"pcm-tpmi"}, } + _, err := runScript(myTarget, setScript, localTempDir) + if err != nil { + err = fmt.Errorf("failed to set ELC OPM mode: %w", err) + } + return err +} + +// setELCLOM sets ELC to Latency Optimized Mode (LOM) +func setELCLOM(myTarget target.Target, localTempDir string) error { setScript := script.ScriptDefinition{ - Name: "set elc", - ScriptTemplate: fmt.Sprintf("bhs-power-mode.sh --%s", mode), + Name: "set elc lom", + ScriptTemplate: ` +pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE +pcm-tpmi 2 0x18 -d -b 28:22 -w 0 # EFFICIENCY_LATENCY_CTRL_RATIO +pcm-tpmi 2 0x18 -d -b 46:40 -w 0 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD +pcm-tpmi 2 0x18 -d -b 38:32 -w 0 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD +`, Superuser: true, Vendors: []string{cpus.IntelVendor}, MicroArchitectures: []string{cpus.UarchGNR, cpus.UarchGNR_D, cpus.UarchSRF, cpus.UarchCWF}, - Depends: []string{"bhs-power-mode.sh", "pcm-tpmi"}, + Depends: []string{"pcm-tpmi"}, } _, err := runScript(myTarget, setScript, localTempDir) if err != nil { - err = fmt.Errorf("failed to set ELC mode: %w", err) + err = fmt.Errorf("failed to set ELC LOM mode: %w", err) } return err } +func setELC(elc string, myTarget target.Target, localTempDir string) error { + switch elc { + case elcOptions[0]: + return setELCLOM(myTarget, localTempDir) + case elcOptions[1]: + return setELCOPM(myTarget, localTempDir) + default: + return fmt.Errorf("invalid ELC mode: %s", elc) + } +} + func getUarch(myTarget target.Target, localTempDir string) (string, error) { scripts := []script.ScriptDefinition{} scripts = append(scripts, script.GetScriptByName(script.LscpuScriptName)) diff --git a/cmd/report/report_tables.go b/cmd/report/report_tables.go index c0ef2cbb..2ab27cbe 100644 --- a/cmd/report/report_tables.go +++ b/cmd/report/report_tables.go @@ -853,31 +853,39 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table. } // suggest setting ELC mode to 'Latency Optimized' or 'Default' based on the current setting for _, mode := range tableValues.Fields[modeFieldIndex].Values { - if mode != "" && mode != "Latency Optimized" { + if mode != "" && mode != extract.ELCModeLatencyOptimized { insights = append(insights, table.Insight{ - Recommendation: "Consider setting Efficiency Latency Control mode to 'Latency Optimized' when workload is highly sensitive to memory latency.", + Recommendation: "Consider setting Efficiency Latency Control mode to 'Latency Optimized Mode (LOM)' when workload is highly sensitive to memory latency.", Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode), }) break } } for _, mode := range tableValues.Fields[modeFieldIndex].Values { - if mode != "" && mode != "Power Optimized" { + if mode != "" && mode != extract.ELCModeOptimizedPower { insights = append(insights, table.Insight{ - Recommendation: "Consider setting Efficiency Latency Control mode to 'Power Optimized' to balance uncore performance and power utilization.", + Recommendation: "Consider setting Efficiency Latency Control mode to 'Optimized Power Mode (OPM)' to balance uncore performance and power utilization.", Justification: fmt.Sprintf("ELC mode is set to '%s' on at least one die.", mode), }) break } } - // if epb is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized', suggest setting epb to 'Performance (0)' + // if epb is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized Mode (LOM)', suggest setting epb to 'Performance (0)' epb := extract.EPBFromOutput(outputs) - if epb != "" && epb != "Performance (0)" && firstMode == "Latency Optimized" { + if epb != "" && epb != "Performance (0)" && firstMode == extract.ELCModeLatencyOptimized { insights = append(insights, table.Insight{ - Recommendation: "Consider setting Energy Performance Bias to 'Performance (0)' to allow Latency Optimized mode to operate as designed.", + Recommendation: "Consider setting Energy Performance Bias to 'Performance (0)' to allow Latency Optimized Mode (LOM) to operate as designed.", Justification: fmt.Sprintf("Energy Performance Bias is set to '%s' and ELC Mode is set to '%s'.", epb, firstMode), }) } + // if epp is not set to 'Performance (0)' and ELC mode is set to 'Latency Optimized Mode (LOM)', suggest setting epp to 'Performance (0)' + epp := extract.EPPFromOutput(outputs) + if epp != "" && epp != "Performance (0)" && firstMode == extract.ELCModeLatencyOptimized { + insights = append(insights, table.Insight{ + Recommendation: "Consider setting Energy Performance Preference to 'Performance (0)' to allow Latency Optimized Mode (LOM) to operate as designed.", + Justification: fmt.Sprintf("Energy Performance Preference is set to '%s' and ELC Mode is set to '%s'.", epp, firstMode), + }) + } } return insights } diff --git a/internal/extract/power.go b/internal/extract/power.go index 18fb4087..30ffc7c7 100644 --- a/internal/extract/power.go +++ b/internal/extract/power.go @@ -176,6 +176,25 @@ func CstatesFromOutput(outputs map[string]script.ScriptOutput) []CstateInfo { return cstatesInfo } +// enum for the column indices in the ELC CSV output +const ( + elcFieldSocketID = iota + elcFieldDie + elcFieldDieType + elcFieldMinRatio + elcFieldMaxRatio + elcFieldELCRatio + elcFieldELCLowThreshold + elcFieldELCHighThreshold + elcFieldELCHighThresholdEnable +) + +const ( + ELCModeLatencyOptimized = "Latency Optimized Mode (LOM)" + ELCModeOptimizedPower = "Optimized Power Mode (OPM)" + ELCModeCustom = "Custom Mode" +) + // ELCFieldValuesFromOutput extracts Efficiency Latency Control field values. func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValues []table.Field) { if outputs[script.ElcScriptName].Stdout == "" { @@ -189,6 +208,13 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu if len(rows) < 2 { return } + // confirm rows have expected number of columns + for _, row := range rows { + if len(row) < elcFieldELCHighThresholdEnable+1 { + slog.Warn("ELC script output has unexpected number of columns", slog.Int("expected", elcFieldELCHighThresholdEnable+1), slog.Int("actual", len(row))) + return + } + } for fieldNamesIndex, fieldName := range rows[0] { values := []string{} for _, row := range rows[1:] { @@ -197,30 +223,23 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu fieldValues = append(fieldValues, table.Field{Name: fieldName, Values: values}) } - values := []string{} + modeValues := []string{} for _, row := range rows[1:] { var mode string - if len(row) > 7 && row[2] == "IO" { - if row[5] == "0" && row[6] == "0" && row[7] == "0" { - mode = "Latency Optimized" - } else if row[5] == "800" && row[6] == "10" && row[7] == "94" { - mode = "Power Optimized" - } else { - mode = "Custom" - } - } else if len(row) > 5 { - switch row[5] { - case "0": - mode = "Latency Optimized" - case "1200": - mode = "Power Optimized" - default: - mode = "Custom" - } + if row[elcFieldELCRatio] == "0" && row[elcFieldELCLowThreshold] == "0" && row[elcFieldELCHighThreshold] == "0" && row[elcFieldELCHighThresholdEnable] == "1" { + mode = ELCModeLatencyOptimized + } else if row[elcFieldELCLowThreshold] == "10" && + row[elcFieldELCHighThreshold] == "95" && + row[elcFieldELCHighThresholdEnable] == "1" && + ((row[elcFieldDieType] == "IO" && row[elcFieldELCRatio] == "800") || + (row[elcFieldDieType] == "Compute" && row[elcFieldELCRatio] == "1200")) { + mode = ELCModeOptimizedPower + } else { + mode = ELCModeCustom } - values = append(values, mode) + modeValues = append(modeValues, mode) } - fieldValues = append(fieldValues, table.Field{Name: "Mode", Values: values}) + fieldValues = append(fieldValues, table.Field{Name: "Mode", Values: modeValues}) return } diff --git a/internal/script/scripts.go b/internal/script/scripts.go index af856e87..c87870a7 100644 --- a/internal/script/scripts.go +++ b/internal/script/scripts.go @@ -541,8 +541,8 @@ extract_and_print_metrics() { min_ratio=$(( min_ratio * 100 )) max_ratio=$(( max_ratio * 100 )) eff_latency_ctrl_ratio=$(( eff_latency_ctrl_ratio * 100 )) - eff_latency_ctrl_low_threshold=$(( (eff_latency_ctrl_low_threshold * 100) / 127 )) - eff_latency_ctrl_high_threshold=$(( (eff_latency_ctrl_high_threshold * 100) / 127 )) + eff_latency_ctrl_low_threshold=$(( (eff_latency_ctrl_low_threshold * 100) / 100 )) + eff_latency_ctrl_high_threshold=$(( (eff_latency_ctrl_high_threshold * 100) / 100 )) # Print metrics echo -n "$socket_id,$die,$die_type,$min_ratio,$max_ratio,$eff_latency_ctrl_ratio," From 583f99aa09cbf0a5fc3599b4adcabb9c882cf5b3 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Sun, 25 Jan 2026 16:58:36 -0800 Subject: [PATCH 12/15] fix: update ELC options in configuration table and adjust test cases for new values Signed-off-by: Harper, Jason M --- cmd/config/config_tables.go | 10 +++++----- cmd/config/restore_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/config/config_tables.go b/cmd/config/config_tables.go index 2870da2c..0b56b9ba 100644 --- a/cmd/config/config_tables.go +++ b/cmd/config/config_tables.go @@ -87,11 +87,11 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi fields = append(fields, []table.Field{ {Name: "Energy Performance Bias", Description: "--epb <0-15>", Values: []string{extract.EPBFromOutput(outputs)}}, {Name: "Energy Performance Preference", Description: "--epp <0-255>", Values: []string{extract.EPPFromOutput(outputs)}}, - {Name: "Scaling Governor", Description: "--gov ", Values: []string{strings.TrimSpace(outputs[script.ScalingGovernorScriptName].Stdout)}}, + {Name: "Scaling Governor", Description: "--gov <" + strings.Join(governorOptions, "|") + ">", Values: []string{strings.TrimSpace(outputs[script.ScalingGovernorScriptName].Stdout)}}, }...) // add ELC (for SRF, CWF and GNR only) if strings.Contains(uarch, cpus.UarchSRF) || strings.Contains(uarch, cpus.UarchGNR) || strings.Contains(uarch, cpus.UarchCWF) { - fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc ", Values: []string{extract.ELCSummaryFromOutput(outputs)}}) + fields = append(fields, table.Field{Name: "Efficiency Latency Control", Description: "--elc <" + strings.Join(elcOptions, "|") + ">", Values: []string{extract.ELCSummaryFromOutput(outputs)}}) } // add prefetchers for _, pf := range extract.PrefetcherDefinitions { @@ -123,7 +123,7 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi fields = append(fields, table.Field{ Name: pf.ShortName + " prefetcher", - Description: "--" + "pref-" + strings.ReplaceAll(strings.ToLower(pf.ShortName), " ", "") + " ", + Description: "--" + "pref-" + strings.ReplaceAll(strings.ToLower(pf.ShortName), " ", "") + " <" + strings.Join(prefetcherOptions, "|") + ">", Values: []string{enabledDisabled}}, ) } @@ -131,12 +131,12 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []table.Fi // add C6 c6 := extract.C6FromOutput(outputs) if c6 != "" { - fields = append(fields, table.Field{Name: "C6", Description: "--c6 ", Values: []string{c6}}) + fields = append(fields, table.Field{Name: "C6", Description: "--c6 <" + strings.Join(c6Options, "|") + ">", Values: []string{c6}}) } // add C1 Demotion c1Demotion := strings.TrimSpace(outputs[script.C1DemotionScriptName].Stdout) if c1Demotion != "" { - fields = append(fields, table.Field{Name: "C1 Demotion", Description: "--c1-demotion ", Values: []string{c1Demotion}}) + fields = append(fields, table.Field{Name: "C1 Demotion", Description: "--c1-demotion <" + strings.Join(c1DemotionOptions, "|") + ">", Values: []string{c1Demotion}}) } return fields } diff --git a/cmd/config/restore_test.go b/cmd/config/restore_test.go index 0f1aea13..fa0a9a5a 100644 --- a/cmd/config/restore_test.go +++ b/cmd/config/restore_test.go @@ -142,8 +142,8 @@ func TestConvertValue(t *testing.T) { {"Prefetcher enabled", "pref-l2hw", "Enabled", "enable", false}, {"Prefetcher disabled", "pref-l2hw", "Disabled", "disable", false}, {"C6 enabled", "c6", "Enabled", "enable", false}, - {"ELC lowercase", "elc", "power-optimized", "power-optimized", false}, - {"ELC capitalized", "elc", "Power-Optimized", "power-optimized", false}, + {"ELC lowercase", "elc", "power", "power", false}, + {"ELC capitalized", "elc", "Power", "power", false}, {"Core SSE freq buckets", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4", "1-44/3.6, 45-52/3.5, 53-60/3.4", false}, {"Core SSE freq buckets full", "core-max-buckets", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", "1-44/3.6, 45-52/3.5, 53-60/3.4, 61-72/3.2, 73-76/3.1, 77-86/3.0", false}, {"Core SSE freq buckets invalid", "core-max-buckets", "invalid-format", "", true}, From 96ce362dcab2fff908bfeca33c08d9802f7990b5 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Sun, 25 Jan 2026 17:24:03 -0800 Subject: [PATCH 13/15] feat: add additional EPP scripts to table definitions Signed-off-by: Harper, Jason M --- cmd/report/report_tables.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/report/report_tables.go b/cmd/report/report_tables.go index 2ab27cbe..527a3a68 100644 --- a/cmd/report/report_tables.go +++ b/cmd/report/report_tables.go @@ -444,6 +444,10 @@ var tableDefinitions = map[string]table.TableDefinition{ script.EtcReleaseScriptName, script.PackagePowerLimitName, script.EpbScriptName, + script.EppScriptName, + script.EppValidScriptName, + script.EppPackageControlScriptName, + script.EppPackageScriptName, script.ScalingDriverScriptName, script.ScalingGovernorScriptName, script.CstatesScriptName, From 36828abeec6afef4b158afc78bcf00d6fe924956 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Tue, 27 Jan 2026 16:40:38 -0800 Subject: [PATCH 14/15] ratio range is from 0-127 Signed-off-by: Harper, Jason M --- cmd/config/set.go | 8 +++++--- internal/extract/power.go | 2 +- internal/script/scripts.go | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/config/set.go b/cmd/config/set.go index 4b44dd41..1983be49 100644 --- a/cmd/config/set.go +++ b/cmd/config/set.go @@ -777,6 +777,7 @@ func setGovernor(governor string, myTarget target.Target, localTempDir string) e // setELCOPM sets ELC to Optimized Power Mode (OPM) func setELCOPM(myTarget target.Target, localTempDir string) error { + // The script is derived from bhs-power-mode script in the Intel PCM repository. setScript := script.ScriptDefinition{ Name: "set elc opm", ScriptTemplate: ` @@ -802,9 +803,9 @@ done <<< "$output" # Set ELC parameters for I/O and Compute dies # set values common to both die types -pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE -pcm-tpmi 2 0x18 -d -b 46:40 -w 95 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD -pcm-tpmi 2 0x18 -d -b 38:32 -w 10 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD +pcm-tpmi 2 0x18 -d -b 39:39 -w 1 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD_ENABLE +pcm-tpmi 2 0x18 -d -b 46:40 -w 120 # EFFICIENCY_LATENCY_CTRL_HIGH_THRESHOLD (120 / 127 ~= 94%) +pcm-tpmi 2 0x18 -d -b 38:32 -w 13 # EFFICIENCY_LATENCY_CTRL_LOW_THRESHOLD (13 / 127 ~= 10%) # set values for I/O Dies for die in "${io_dies[@]}"; do @@ -830,6 +831,7 @@ done // setELCLOM sets ELC to Latency Optimized Mode (LOM) func setELCLOM(myTarget target.Target, localTempDir string) error { + // The script is derived from bhs-power-mode script in the Intel PCM repository. setScript := script.ScriptDefinition{ Name: "set elc lom", ScriptTemplate: ` diff --git a/internal/extract/power.go b/internal/extract/power.go index 30ffc7c7..396a41d1 100644 --- a/internal/extract/power.go +++ b/internal/extract/power.go @@ -229,7 +229,7 @@ func ELCFieldValuesFromOutput(outputs map[string]script.ScriptOutput) (fieldValu if row[elcFieldELCRatio] == "0" && row[elcFieldELCLowThreshold] == "0" && row[elcFieldELCHighThreshold] == "0" && row[elcFieldELCHighThresholdEnable] == "1" { mode = ELCModeLatencyOptimized } else if row[elcFieldELCLowThreshold] == "10" && - row[elcFieldELCHighThreshold] == "95" && + row[elcFieldELCHighThreshold] == "94" && row[elcFieldELCHighThresholdEnable] == "1" && ((row[elcFieldDieType] == "IO" && row[elcFieldELCRatio] == "800") || (row[elcFieldDieType] == "Compute" && row[elcFieldELCRatio] == "1200")) { diff --git a/internal/script/scripts.go b/internal/script/scripts.go index c87870a7..af856e87 100644 --- a/internal/script/scripts.go +++ b/internal/script/scripts.go @@ -541,8 +541,8 @@ extract_and_print_metrics() { min_ratio=$(( min_ratio * 100 )) max_ratio=$(( max_ratio * 100 )) eff_latency_ctrl_ratio=$(( eff_latency_ctrl_ratio * 100 )) - eff_latency_ctrl_low_threshold=$(( (eff_latency_ctrl_low_threshold * 100) / 100 )) - eff_latency_ctrl_high_threshold=$(( (eff_latency_ctrl_high_threshold * 100) / 100 )) + eff_latency_ctrl_low_threshold=$(( (eff_latency_ctrl_low_threshold * 100) / 127 )) + eff_latency_ctrl_high_threshold=$(( (eff_latency_ctrl_high_threshold * 100) / 127 )) # Print metrics echo -n "$socket_id,$die,$die_type,$min_ratio,$max_ratio,$eff_latency_ctrl_ratio," From 6e751f6ac9f2a390939a5041710eb1f347482253 Mon Sep 17 00:00:00 2001 From: "Harper, Jason M" Date: Wed, 28 Jan 2026 08:01:16 -0800 Subject: [PATCH 15/15] remove pcm script --- tools/Makefile | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index 3fe5e9fc..a0252a46 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -25,7 +25,7 @@ default: tools-x86_64 .PHONY: sysstat sysstat-aarch64 sysstat-repo .PHONY: tsc turbostat -tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw lspci msr-tools pcm bhs-power-mode.sh spectre-meltdown-checker sshpass stackcollapse-perf stress-ng sysstat tsc turbostat +tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw lspci msr-tools pcm spectre-meltdown-checker sshpass stackcollapse-perf stress-ng sysstat tsc turbostat mkdir -p bin/x86_64 cp -R async-profiler bin/x86_64/ cp avx-turbo/avx-turbo bin/x86_64/ @@ -41,7 +41,6 @@ tools-x86_64: async-profiler avx-turbo cpuid dmidecode ethtool fio ipmitool lshw cp msr-tools/rdmsr bin/x86_64/ cp msr-tools/wrmsr bin/x86_64/ cp pcm/build/bin/pcm-tpmi bin/x86_64/ - cp bhs-power-mode.sh bin/x86_64/ cp perf-archive/perf-archive.sh bin/x86_64/perf-archive && chmod +rx bin/x86_64/perf-archive cp spectre-meltdown-checker/spectre-meltdown-checker.sh bin/x86_64/ cp sshpass/sshpass bin/x86_64/ @@ -316,11 +315,6 @@ endif cd pcm/build && cmake -DNO_ASAN=1 .. cd pcm/build && cmake --build . -PCM_BHS_POWER_MODE_VERSION := 8fdf97bc9636792e05e4be82421efc1c9aec980f -bhs-power-mode.sh: - wget $(WGET_OPTS) https://raw.githubusercontent.com/intel/pcm/$(PCM_BHS_POWER_MODE_VERSION)/scripts/bhs-power-mode.sh - chmod +x bhs-power-mode.sh - PERF_VERSION := 6.15.3 linux-$(PERF_VERSION).tar.xz: wget $(WGET_OPTS) https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$(PERF_VERSION).tar.xz