From d470fe787f64dd24f853b91d23e8acc3bbf1c9a7 Mon Sep 17 00:00:00 2001 From: "lijindong (C)" <2220386943@qq.com> Date: Mon, 28 Jul 2025 10:06:08 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF=E9=80=82?= =?UTF-8?q?=E9=85=8D=EF=BC=8C=E5=8E=BBnumactl-devel=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pmu/CMakeLists.txt | 2 +- pmu/evt_list.cpp | 55 ++++++++++++++++-------- pmu/evt_list.h | 1 + pmu/pfm/core.cpp | 1 + pmu/pmu_analysis.cpp | 1 + pmu/pmu_metric.cpp | 45 +++---------------- pmu/pmu_trace_analysis.cpp | 1 + pmu/sampler.cpp | 4 -- util/CMakeLists.txt | 2 +- util/cpu_map.cpp | 88 +++++++++++++++++++++++++++++++++++++- util/cpu_map.h | 2 + 11 files changed, 137 insertions(+), 65 deletions(-) diff --git a/pmu/CMakeLists.txt b/pmu/CMakeLists.txt index 4af6e76..90a149f 100644 --- a/pmu/CMakeLists.txt +++ b/pmu/CMakeLists.txt @@ -33,7 +33,7 @@ include_directories(${PMU_DECODER_DIR}) ADD_LIBRARY(kperf SHARED ${PMU_SRC} ${UTIL_SRC} ${PFM_SRC} ${PMU_DECODER_SRC}) ADD_LIBRARY(kperf_static STATIC ${PMU_SRC} ${UTIL_SRC} ${PFM_SRC} ${PMU_DECODER_SRC}) set_target_properties(kperf_static PROPERTIES OUTPUT_NAME "kperf") -target_link_libraries(kperf numa sym) +target_link_libraries(kperf sym) target_compile_options(kperf PRIVATE -fPIC) install(TARGETS kperf DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) install(TARGETS kperf_static DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) diff --git a/pmu/evt_list.cpp b/pmu/evt_list.cpp index 310a95f..b96a4ad 100644 --- a/pmu/evt_list.cpp +++ b/pmu/evt_list.cpp @@ -66,6 +66,41 @@ int KUNPENG_PMU::EvtList::CollectorXYArrayDoTask(std::vectorGetEvtName() + + ", PMU Hardware or event type doesn't support branch stack sampling"); + } else { + pcerr::SetCustomErr( + err, "Invalid event:" + perfEvt->GetEvtName() + ", " + std::string{strerror(errno)}); + } + break; + case LIBPERF_ERR_NO_PERMISSION: + pcerr::SetCustomErr(LIBPERF_ERR_NO_PERMISSION, + "Current user does not have the permission to collect the event." + "Switch to the root user and run the 'echo -1 > /proc/sys/kernel/perf_event_paranoid'"); + break; + case LIBPERF_ERR_FAIL_MMAP: + if (errno == ENOMEM) { + pcerr::SetCustomErr(err, + "The number of mmap reaches the upper limit.Execute `echo {NUM} > /proc/sys/vm/max_map_count` to " + "set a bigger limit"); + } else { + pcerr::SetCustomErr(err, std::string{strerror(errno)}); + } + break; + case UNKNOWN_ERROR: + pcerr::SetCustomErr(err, std::string{strerror(errno)}); + break; + default: + break; + } +} + int KUNPENG_PMU::EvtList::Init(const bool groupEnable, const std::shared_ptr evtLeader) { // Init process map. @@ -103,24 +138,8 @@ int KUNPENG_PMU::EvtList::Init(const bool groupEnable, const std::shared_ptrGetEvtName() + ", PMU Hardware or event type doesn't support branch stack sampling"); - } else { - pcerr::SetCustomErr(err, "Invalid event:" + perfEvt->GetEvtName() + ", " + std::string{strerror(errno)}); - } - } - - if (err == LIBPERF_ERR_NO_PERMISSION) { - pcerr::SetCustomErr(LIBPERF_ERR_NO_PERMISSION, "Current user does not have the permission to collect the event." - "Switch to the root user and run the 'echo -1 > /proc/sys/kernel/perf_event_paranoid'"); - } - - if (err == UNKNOWN_ERROR) { - pcerr::SetCustomErr(err, std::string{strerror(errno)}); - } - + + this->AdaptErrInfo(err, perfEvt); return err; } fdList.insert(perfEvt->GetFd()); diff --git a/pmu/evt_list.h b/pmu/evt_list.h index 6902167..50cc522 100644 --- a/pmu/evt_list.h +++ b/pmu/evt_list.h @@ -118,6 +118,7 @@ private: int CollectorXYArrayDoTask(std::vector>& xyArray, int task); void FillFields(const size_t& start, const size_t& end, CpuTopology* cpuTopo, ProcTopology* procTopo, std::vector& pmuData); + void AdaptErrInfo(int err, PerfEvtPtr perfEvt); std::vector cpuList; std::vector pidList; diff --git a/pmu/pfm/core.cpp b/pmu/pfm/core.cpp index c177fb3..572a51d 100644 --- a/pmu/pfm/core.cpp +++ b/pmu/pfm/core.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "pmu_event.h" #include "core.h" diff --git a/pmu/pmu_analysis.cpp b/pmu/pmu_analysis.cpp index 37d8cf9..5ffd80f 100644 --- a/pmu/pmu_analysis.cpp +++ b/pmu/pmu_analysis.cpp @@ -14,6 +14,7 @@ ******************************************************************************/ #include #include +#include #include #include #include diff --git a/pmu/pmu_metric.cpp b/pmu/pmu_metric.cpp index 9d681d8..03afa42 100644 --- a/pmu/pmu_metric.cpp +++ b/pmu/pmu_metric.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,6 @@ static unsigned maxCpuNum = 0; static vector coreArray; static std::mutex pmuBdfListMtx; -static std::mutex pmuCoreListMtx; static std::mutex pmuDeviceDataMtx; static const string SYS_DEVICES = "/sys/devices/"; @@ -1788,18 +1786,6 @@ int64_t PmuGetCpuFreq(unsigned core) return cpuFreq * 1000; } -static void InitializeCoreArray() -{ - if (!coreArray.empty()) { - return; - } - maxCpuNum = sysconf(_SC_NPROCESSORS_CONF); - for (unsigned i = 0; i < maxCpuNum; ++i) { - coreArray.emplace_back(i); - } - return; -} - int PmuGetClusterCore(unsigned clusterId, unsigned **coreList) { #ifdef IS_X86 @@ -1807,8 +1793,6 @@ int PmuGetClusterCore(unsigned clusterId, unsigned **coreList) return -1; #else try { - lock_guard lg(pmuCoreListMtx); - InitializeCoreArray(); bool hyperThread = false; int err = HyperThreadEnabled(hyperThread); if (err != SUCCESS) { @@ -1828,7 +1812,7 @@ int PmuGetClusterCore(unsigned clusterId, unsigned **coreList) return -1; } - *coreList = &coreArray[startCore]; + *coreList = GetCoreList(startCore); New(SUCCESS); return coreNums; @@ -1843,31 +1827,12 @@ int PmuGetClusterCore(unsigned clusterId, unsigned **coreList) int PmuGetNumaCore(unsigned nodeId, unsigned **coreList) { try { - lock_guard lg(pmuCoreListMtx); - string nodeListFile = "/sys/devices/system/node/node" + to_string(nodeId) + "/cpulist"; - ifstream in(nodeListFile); - if (!in.is_open()) { - New(LIBPERF_ERR_KERNEL_NOT_SUPPORT); - return -1; - } - std::string cpulist; - in >> cpulist; - auto split = SplitStringByDelimiter(cpulist, '-'); - if (split.size() != 2) { - New(LIBPERF_ERR_KERNEL_NOT_SUPPORT); - return -1; - } - auto start = stoi(split[0]); - auto end = stoi(split[1]); - int coreNums = end - start + 1; - if (coreNums <= 0) { + int coreNums = GetNumaCore(nodeId, coreList); + if (coreNums == -1) { New(LIBPERF_ERR_KERNEL_NOT_SUPPORT); - return -1; + } else { + New(SUCCESS); } - InitializeCoreArray(); - *coreList = &coreArray[start]; - - New(SUCCESS); return coreNums; } catch (exception &ex) { New(UNKNOWN_ERROR, ex.what()); diff --git a/pmu/pmu_trace_analysis.cpp b/pmu/pmu_trace_analysis.cpp index c1c6834..0411f68 100644 --- a/pmu/pmu_trace_analysis.cpp +++ b/pmu/pmu_trace_analysis.cpp @@ -15,6 +15,7 @@ ******************************************************************************/ #include #include +#include #include "pmu_list.h" #include "pmu_analysis.h" #include "pcerr.h" diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index 55b3c53..2893147 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -109,10 +109,6 @@ int KUNPENG_PMU::PerfSampler::Mmap() { int mmapLen = (SAMPLE_PAGES + 1) * SAMPLE_PAGE_SIZE; auto mask = mmapLen - SAMPLE_PAGE_SIZE - 1; - if (mask < 0) { - return UNKNOWN_ERROR; - } - this->sampleMmap->prev = 0; this->sampleMmap->mask = static_cast<__u64>(mask); void *currentMap = diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index a59ba9d..c696784 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -19,4 +19,4 @@ include_directories(${THIRD_PARTY}/huawei_secure_c/include) add_library(profu STATIC ${UTIL_SRC}) target_compile_options(profu PUBLIC -fPIC) -target_link_libraries(profu numa) +target_link_libraries(profu) diff --git a/util/cpu_map.cpp b/util/cpu_map.cpp index da09c86..4dd358b 100644 --- a/util/cpu_map.cpp +++ b/util/cpu_map.cpp @@ -16,9 +16,11 @@ #include #include #include +#include #include #include #include +#include #include "common.h" #include "pcerr.h" #include "cpu_map.h" @@ -28,6 +30,7 @@ using namespace std; static const std::string CPU_TOPOLOGY_PACKAGE_ID = "/sys/bus/cpu/devices/cpu%d/topology/physical_package_id"; static const std::string MIDR_EL1 = "/sys/devices/system/cpu/cpu0/regs/identification/midr_el1"; static const std::string CPU_ONLINE_PATH = "/sys/devices/system/cpu/online"; +static const std::string NUMA_PATH = "/sys/devices/system/node"; static constexpr int PATH_LEN = 256; static constexpr int LINE_LEN = 1024; @@ -40,6 +43,9 @@ static map chipMap = {{"0x00000000481fd010", HIPA}, {"0x00000000480fd450", HIPE},}; static std::set onLineCpuIds; +static map cpuOfNumaNodeMap; +static vector coreArray; +static mutex pmuCoreListMtx; static inline bool ReadCpuPackageId(int coreId, CpuTopology* cpuTopo) { @@ -61,6 +67,86 @@ static inline bool ReadCpuPackageId(int coreId, CpuTopology* cpuTopo) return true; } +static int GetNumaNodeCount() +{ + DIR *dir = opendir(NUMA_PATH.c_str()); + if (dir == nullptr) { + return -1; + } + + int numaNodeCount = 0; + struct dirent* entry; + while((entry = readdir(dir)) != nullptr) { + if (entry->d_type == DT_DIR && strncmp(entry->d_name, "node", 4) == 0) { + ++numaNodeCount; + } + } + closedir(dir); + return numaNodeCount; +} + +unsigned* GetCoreList(int start) { + lock_guard lg(pmuCoreListMtx); + if (coreArray.empty()) { + for (unsigned i = 0; i < MAX_CPU_NUM; ++i) { + coreArray.emplace_back(i); + } + } + return &coreArray[start]; +} + +int GetNumaCore(unsigned nodeId, unsigned **coreList) +{ + string nodeListFile = "/sys/devices/system/node/node" + to_string(nodeId) + "/cpulist"; + ifstream in(nodeListFile); + if (!in.is_open()) { + return -1; + } + std::string cpulist; + in >> cpulist; + auto split = SplitStringByDelimiter(cpulist, '-'); + if (split.size() != 2) { + return -1; + } + auto start = stoi(split[0]); + auto end = stoi(split[1]); + int coreNums = end - start + 1; + if (coreNums <= 0) { + return -1; + } + *coreList = GetCoreList(start); + return coreNums; +} + +int GetNumaNodeOfCpu(int coreId) +{ + if (!cpuOfNumaNodeMap.empty()) { + if (cpuOfNumaNodeMap.find(coreId) != cpuOfNumaNodeMap.end()) { + return cpuOfNumaNodeMap[coreId]; + } else { + return -1; + } + } + + unsigned maxNode = GetNumaNodeCount(); + int nodeId = -1; + for (int i = 0; i < maxNode; i++) { + unsigned *coreList = nullptr; + int numCore = GetNumaCore(i, &coreList); + if (numCore == -1) { + continue; + } + for (int j = 0; j < numCore; j++) { + int cpuId = coreList[j]; + cpuOfNumaNodeMap[cpuId] = i; + if (coreId == cpuId) { + nodeId = i; + } + } + } + return nodeId; +} + struct CpuTopology* GetCpuTopology(int coreId) { auto cpuTopo = std::unique_ptr(new CpuTopology()); @@ -77,7 +163,7 @@ struct CpuTopology* GetCpuTopology(int coreId) pcerr::SetWarn(LIBPERF_ERR_FAIL_GET_CPU, "failed to obtain the socketdId for " + std::to_string(coreId) + " core."); } - cpuTopo->numaId = numa_node_of_cpu(coreId); + cpuTopo->numaId = GetNumaNodeOfCpu(coreId); return cpuTopo.release(); } diff --git a/util/cpu_map.h b/util/cpu_map.h index df16320..14f2b79 100644 --- a/util/cpu_map.h +++ b/util/cpu_map.h @@ -33,4 +33,6 @@ enum CHIP_TYPE { struct CpuTopology* GetCpuTopology(int coreId); CHIP_TYPE GetCpuType(); std::set GetOnLineCpuIds(); +unsigned* GetCoreList(int start); +int GetNumaCore(unsigned nodeId, unsigned** coreList); #endif -- Gitee