diff --git a/pmu/CMakeLists.txt b/pmu/CMakeLists.txt index 4af6e76f9cdfc75afd4cdf8acaa2e4cd5b45ce64..90a149f54d8d912fdabaea6914cee4132dce0e02 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 310a95f9aff7d98adcec63bfaf1f18ecbe75570d..b96a4ad2571d445829a4e06d17f39fb438531335 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 6902167c7ff701b3542ec28623f98ee265dc6e6d..50cc52295e07b7210f581aefd8074b4121b0ef11 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 c177fb37e00cc549a720b5a25dedc9ec68a9f995..572a51d8a8e89789942d4718bbde3e9bd1352fe8 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 37d8cf9d375eed885a9d59b2df73214d63596d9e..5ffd80f48d02c92bcafad695b33360d952a84a7c 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 9d681d8d58077478bde9f9894fef55aebcfbf071..03afa42bf0a0e4f4a4dc3afd54efa2ffc6255fcf 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 c1c68346ecff8132c1802b1ae0ae7be76b6de07f..0411f682869ec0786251a2bbd17b4996595839a8 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 55b3c53ccfa00e6669711c1ae682fb583da74286..28931478500a13b2a0e88e989cb3aaf8f2fa1b22 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 a59ba9dbe5c83570e8541fd069c403eb4643e5cd..c69678468a8c37b4f23d1a0680ef62ae0d329b91 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 da09c86e4267548452e24cf5afe71a887ad1d4b1..4dd358bae8eafaadfd518ea1ddecf3670921bb58 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 df163206bcbf2e19bef2f3b4681bf71c53ee16a3..14f2b790f372073b1bec8ce92c4bd3a0ab0157bd 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