oeAware-manager/0005-modify-the-method-of-obtaining-cpu-frequency.patch
fly_1997 a6bf13bea8 fix some bugs
(cherry picked from commit 0361f09ca97a26333b5d898a6d52cc4f9da716d1)
2024-12-30 20:15:04 +08:00

263 lines
8.0 KiB
Diff

From 781dccda979b392cb6dc8f9b3e65bbf5f0b99373 Mon Sep 17 00:00:00 2001
From: zhaolichang <zhaolichang@huawei.com>
Date: Mon, 9 Dec 2024 11:53:48 +0800
Subject: [PATCH 1/7] modify the method of obtaining cpu frequency
1. use dmidecode to obtain cpu frequency when cpufreq file does not exist
2. merge duplicate code in cpu frequency
---
include/oeaware/utils.h | 2 +
src/common/utils.cpp | 51 +++++++++++++++++++
src/plugin/scenario/analysis/analysis/env.cpp | 39 ++++++--------
src/plugin/scenario/analysis/analysis/env.h | 1 +
src/plugin/tune/docker/cpu_burst.cpp | 37 ++++++--------
src/plugin/tune/docker/cpu_burst.h | 1 +
6 files changed, 87 insertions(+), 44 deletions(-)
diff --git a/include/oeaware/utils.h b/include/oeaware/utils.h
index 98e9c5c..48fc7af 100644
--- a/include/oeaware/utils.h
+++ b/include/oeaware/utils.h
@@ -32,6 +32,8 @@ std::vector<std::string> SplitString(const std::string &str, const std::string &
bool CreateDir(const std::string &path);
bool SetDataListTopic(DataList *dataList, const std::string &instanceName, const std::string &topicName,
const std::string &params);
+uint64_t GetCpuCycles(int cpu);
+uint64_t GetCpuFreqByDmi();
}
#endif
\ No newline at end of file
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
index 8f63a70..79bdc49 100644
--- a/src/common/utils.cpp
+++ b/src/common/utils.cpp
@@ -17,6 +17,8 @@
#include <curl/curl.h>
#include <sys/stat.h>
#include <grp.h>
+#include <iostream>
+#include <cctype>
namespace oeaware {
const static int ST_MODE_MASK = 0777;
@@ -201,4 +203,53 @@ bool SetDataListTopic(DataList *dataList, const std::string &instanceName, const
return true;
}
+uint64_t GetCpuCycles(int cpu)
+{
+ std::string freqPath = "/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/cpufreq/scaling_cur_freq";
+ std::ifstream freqFile(freqPath);
+
+ if (!freqFile.is_open()) {
+ return 0;
+ }
+
+ uint64_t freq;
+ freqFile >> freq;
+ freqFile.close();
+
+ if (freqFile.fail()) {
+ return 0;
+ }
+
+ return freq * 1000; // 1000: kHz to Hz
+}
+
+uint64_t GetCpuFreqByDmi()
+{
+ FILE *pipe = popen("dmidecode -t processor | grep 'Max Speed' | head -n 1 | awk '{print $3}'", "r");
+ if (!pipe) {
+ std::cout << "failed to run dmidecode" << std::endl;
+ return 0;
+ }
+
+ char buffer[128];
+ if (fgets(buffer, sizeof(buffer), pipe) == nullptr) {
+ std::cout << "failed to get cpufreq by dmidecode" << std::endl;
+ pclose(pipe);
+ return 0;
+ }
+ pclose(pipe);
+
+ std::string str(buffer);
+ str.erase(str.find_last_not_of(" \t\n\r") + 1);
+
+ for (char c : str) {
+ if (!std::isdigit(c)) {
+ std::cerr << "invalid CPU frequency format: " << str << std::endl;
+ return 0;
+ }
+ }
+
+ return std::stoull(buffer) * 1000000; // 1000000: MHz to Hz
+}
+
}
diff --git a/src/plugin/scenario/analysis/analysis/env.cpp b/src/plugin/scenario/analysis/analysis/env.cpp
index a3a5457..63d352f 100644
--- a/src/plugin/scenario/analysis/analysis/env.cpp
+++ b/src/plugin/scenario/analysis/analysis/env.cpp
@@ -13,7 +13,10 @@
#include <string>
#include <fstream>
#include <unistd.h>
+#include <iostream>
+#include "oeaware/utils.h"
#include "env.h"
+
unsigned long GetPageMask()
{
static unsigned long pageMask = 0;
@@ -29,32 +32,17 @@ unsigned long GetPageMask()
return pageMask;
}
-static uint64_t GetCpuCycles(int cpu)
-{
- std::string freqPath = "/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/cpufreq/scaling_cur_freq";
- std::ifstream freqFile(freqPath);
-
- if (!freqFile.is_open()) {
- return 0;
- }
-
- uint64_t freq;
- freqFile >> freq;
- freqFile.close();
-
- if (freqFile.fail()) {
- return 0;
- }
-
- return freq * 1000; // 1000: kHz to Hz
-}
-
-static void InitCpuCycles(std::vector<uint64_t> &maxCycles, uint64_t &sysMaxCycles)
+static void InitCpuCycles(std::vector<uint64_t> &maxCycles, uint64_t &sysMaxCycles, uint64_t &maxCpuFreqByDmi)
{
for (int cpu = 0; cpu < maxCycles.size(); cpu++) {
- maxCycles[cpu] = GetCpuCycles(cpu);
+ maxCycles[cpu] = oeaware::GetCpuCycles(cpu);
sysMaxCycles += maxCycles[cpu];
}
+
+ if (sysMaxCycles <= 0) {
+ std::cout << "use dmidecode to obtain cpu frequency" << std::endl;
+ sysMaxCycles = maxCpuFreqByDmi * maxCycles.size();
+ }
}
bool Env::Init()
@@ -64,6 +52,7 @@ bool Env::Init()
}
numaNum = numa_num_configured_nodes();
cpuNum = sysconf(_SC_NPROCESSORS_CONF);
+ maxCpuFreqByDmi = oeaware::GetCpuFreqByDmi();
cpu2Node.resize(cpuNum, -1);
struct bitmask *cpumask = numa_allocate_cpumask();
for (int nid = 0; nid < numaNum; ++nid) {
@@ -80,7 +69,11 @@ bool Env::Init()
pageMask = GetPageMask();
InitDistance();
cpuMaxCycles.resize(cpuNum, 0);
- InitCpuCycles(cpuMaxCycles, sysMaxCycles);
+ InitCpuCycles(cpuMaxCycles, sysMaxCycles, maxCpuFreqByDmi);
+ if (sysMaxCycles <= 0) {
+ std::cout << "failed to get sysMaxCycles" << std::endl;
+ return false;
+ }
initialized = true;
return true;
}
diff --git a/src/plugin/scenario/analysis/analysis/env.h b/src/plugin/scenario/analysis/analysis/env.h
index f75f035..28b21f4 100644
--- a/src/plugin/scenario/analysis/analysis/env.h
+++ b/src/plugin/scenario/analysis/analysis/env.h
@@ -36,6 +36,7 @@ public:
int cpuNum;
unsigned long pageMask = 0;
uint64_t sysMaxCycles = 0;
+ uint64_t maxCpuFreqByDmi;
std::vector<int> cpu2Node;
std::vector<std::vector<int>> distance;
std::vector<uint64_t> cpuMaxCycles; // per second
diff --git a/src/plugin/tune/docker/cpu_burst.cpp b/src/plugin/tune/docker/cpu_burst.cpp
index 58b41dd..1e60fb9 100644
--- a/src/plugin/tune/docker/cpu_burst.cpp
+++ b/src/plugin/tune/docker/cpu_burst.cpp
@@ -14,6 +14,7 @@
#include <iostream>
#include <unistd.h>
#include "oeaware/data/pmu_counting_data.h"
+#include "oeaware/utils.h"
constexpr double NINETY_PERCENT = 0.9;
constexpr int MILLISECONDS_IN_SECOND = 1000;
@@ -35,34 +36,28 @@ static void SetCfsBurstUs(const std::string &id, int cfsBurstUs)
return;
}
-static uint64_t GetCpuCycles(int cpu)
+bool CpuBurst::Init()
{
- std::string freq_path = "/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/cpufreq/scaling_cur_freq";
- std::ifstream freq_file(freq_path);
+ curSysCycles = 0;
+ maxCpuFreqByDmi = oeaware::GetCpuFreqByDmi();
- if (!freq_file.is_open()) {
- return 0;
+ cpuNum = sysconf(_SC_NPROCESSORS_CONF);
+ if (cpuNum <= 0) {
+ std::cout << "can not get cpu num" << std::endl;
+ return false;
}
- uint64_t freq;
- freq_file >> freq;
- freq_file.close();
-
- if (freq_file.fail()) {
- return 0;
+ for (unsigned int i = 0; i < cpuNum; i++) {
+ maxSysCycles += oeaware::GetCpuCycles(i);
}
- return freq * 1000; // 1000: kHz to Hz
-}
-
-bool CpuBurst::Init()
-{
- curSysCycles = 0;
- cpuNum = sysconf(_SC_NPROCESSORS_CONF);
- for (unsigned int i = 0; i < cpuNum; i++) {
- maxSysCycles += GetCpuCycles(i);
+ if (maxSysCycles <= 0) {
+ std::cout << "use dmidecode to obtain cpu frequency" << std::endl;
+ maxSysCycles = maxCpuFreqByDmi * cpuNum;
}
- if (cpuNum <= 0 || maxSysCycles <= 0) {
+
+ if (maxSysCycles <= 0) {
+ std::cout << "can not get cpu frequency" << std::endl;
return false;
}
return true;
diff --git a/src/plugin/tune/docker/cpu_burst.h b/src/plugin/tune/docker/cpu_burst.h
index b485747..8ed7fae 100644
--- a/src/plugin/tune/docker/cpu_burst.h
+++ b/src/plugin/tune/docker/cpu_burst.h
@@ -49,6 +49,7 @@ private:
unsigned int cpuNum = 0;
uint64_t maxSysCycles = 0; // per second
uint64_t curSysCycles = 0;
+ uint64_t maxCpuFreqByDmi;
std::unordered_map<std::string, ContainerTune> containers;
void UpdatePmu(const DataList &dataList);
void UpdateDocker(const DataList &dataList);
--
2.33.0