app-power-metrics/stx-power-metrics-images/files/telegraf-0003-feat-intel.po...

124 lines
4.5 KiB
Diff

From 0ff7a3f8ff5c47f6bbea18f6ba4e6d981a8836de Mon Sep 17 00:00:00 2001
From: Alyson Deives Pereira <alyson.deivespereira@windriver.com>
Date: Fri, 11 Aug 2023 15:16:51 -0300
Subject: [PATCH 3/3] feat(inputs.intel_powerstat): Estimate isolated core
frequency when intel_pstate is enabled
There is an issue with intel_pstate where cur_freq is not available
when nohz_full is enabled (i.e. the core is isolated).
To overcome this issue, we provide a naive core frequency estimation
according to intel_pstate governor. If the governor is powersave, we
use the core minimum scaling frequency, otherwise we use the maximum
scaling frequency.
NOTE: This issue was reported on upstream:
https://github.com/influxdata/telegraf/issues/13830
Signed-off-by: Alyson Deives Pereira <alyson.deivespereira@windriver.com>
---
plugins/inputs/intel_powerstat/msr.go | 70 +++++++++++++++++++++++++--
1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/plugins/inputs/intel_powerstat/msr.go b/plugins/inputs/intel_powerstat/msr.go
index 2b5902f2c..ffbe0ee78 100644
--- a/plugins/inputs/intel_powerstat/msr.go
+++ b/plugins/inputs/intel_powerstat/msr.go
@@ -18,6 +18,10 @@ import (
const (
systemCPUPath = "/sys/devices/system/cpu/"
cpuCurrentFreqPartialPath = "/sys/devices/system/cpu/cpu%s/cpufreq/scaling_cur_freq"
+ cpuMinFreqPartialPath = "/sys/devices/system/cpu/cpu%s/cpufreq/scaling_min_freq"
+ cpuMaxFreqPartialPath = "/sys/devices/system/cpu/cpu%s/cpufreq/scaling_max_freq"
+ cpuDriverFreqPartialPath = "/sys/devices/system/cpu/cpu%s/cpufreq/scaling_driver"
+ cpuGovernorFreqPartialPath = "/sys/devices/system/cpu/cpu%s/cpufreq/scaling_governor"
msrPartialPath = "/dev/cpu/%s/msr"
uncoreFreqPath = "/sys/devices/system/cpu/intel_uncore_frequency/package_%s_die_%s/%s%s_freq_khz"
c3StateResidencyLocation = 0x3FC
@@ -78,19 +82,79 @@ func (m *msrServiceImpl) isMsrLoaded() bool {
}
return false
}
-func (m *msrServiceImpl) retrieveCPUFrequencyForCore(core string) (float64, error) {
- cpuFreqPath := fmt.Sprintf(cpuCurrentFreqPartialPath, core)
+
+func (m *msrServiceImpl) retrieveCPUFrequency(partialPath string, core string) (float64, error) {
+ cpuFreqPath := fmt.Sprintf(partialPath, core)
err := checkFile(cpuFreqPath)
if err != nil {
return 0, err
}
cpuFreqFile, err := os.Open(cpuFreqPath)
if err != nil {
- return 0, fmt.Errorf("error opening scaling_cur_freq file on path %q: %w", cpuFreqPath, err)
+ return 0, fmt.Errorf("error opening file on path %q: %w", cpuFreqPath, err)
}
defer cpuFreqFile.Close()
cpuFreq, _, err := m.fs.readFileToFloat64(cpuFreqFile)
+ return cpuFreq, err
+}
+
+func (m *msrServiceImpl) isUsingIntelPstateDriver(core string) (bool, error) {
+ driverFreqPath := fmt.Sprintf(cpuDriverFreqPartialPath, core)
+ err := checkFile(driverFreqPath)
+ if err != nil {
+ m.log.Errorf("error checking file on path %q: %w", driverFreqPath, err)
+ return false, err
+ }
+ driver, err := m.fs.readFile(driverFreqPath)
+ if err != nil {
+ return false, err
+ }
+ // Remove new line character
+ driverStr := strings.TrimRight(string(driver), "\n")
+
+ if driverStr == "intel_pstate" {
+ return true, nil
+ }
+ return false, nil
+}
+
+func (m *msrServiceImpl) retrieveCPUFrequencyGovernor(core string) (string, error) {
+ governorFreqPath := fmt.Sprintf(cpuGovernorFreqPartialPath, core)
+ err := checkFile(governorFreqPath)
+ if err != nil {
+ return "", err
+ }
+ governor, err := m.fs.readFile(governorFreqPath)
+ if err != nil {
+ return "", err
+ }
+ // Remove new line character
+ governorStr := strings.TrimRight(string(governor), "\n")
+ return governorStr, nil
+}
+
+func (m *msrServiceImpl) retrieveCPUFrequencyForCore(core string) (float64, error) {
+ cpuFreq, err := m.retrieveCPUFrequency(cpuCurrentFreqPartialPath, core)
+ // If intel_pstate is enabled, a frequency of 0 means that the core is isolated and/or with nohz_full enabled
+ // We estimate the core frequency according to scaling governor powersave or performance
+ if cpuFreq == 0 {
+ intelPstateDriver, err := m.isUsingIntelPstateDriver(core)
+ if err != nil {
+ return 0, err
+ }
+ if intelPstateDriver {
+ governor, err := m.retrieveCPUFrequencyGovernor(core)
+ if err != nil {
+ return 0, err
+ }
+ if governor == "powersave" {
+ cpuFreq, err = m.retrieveCPUFrequency(cpuMinFreqPartialPath, core)
+ } else {
+ cpuFreq, err = m.retrieveCPUFrequency(cpuMaxFreqPartialPath, core)
+ }
+ }
+ }
return convertKiloHertzToMegaHertz(cpuFreq), err
}
--
2.25.1