From 4a084d12ceb0129c8b901798282ef89f3df13bf2 Mon Sep 17 00:00:00 2001 From: ganlixiong Date: Fri, 11 Oct 2024 10:50:07 +0800 Subject: [PATCH 05/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=A8=E6=9F=90?= =?UTF-8?q?=E4=BA=9B=E7=8E=AF=E5=A2=83=E4=B8=8A=E6=97=A0=E6=B3=95=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=88=B0pmu=20event=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 在某些环境上调用PmuEventList,返回的事件列表为空。 原因: 该环境上的arm core设备名称为armv8_pmuv3,而在查询事件列表时,搜索了armv8_pmuv3_0设备的事件。 解决方法: 动态寻找arm core设备,而不是用硬编码。参考perf tool的实现,查询devices下面的所有设备,如果设备下面包含文件cpus,那么认为该设备为arm core设备。 --- pmu/pfm/core.cpp | 44 +++++++++++++++++++++++++++++++++++++++--- pmu/pfm/core.h | 2 ++ pmu/pmu_event_list.cpp | 10 ++++++++-- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/pmu/pfm/core.cpp b/pmu/pfm/core.cpp index 80d5e0b..0ab4607 100644 --- a/pmu/pfm/core.cpp +++ b/pmu/pfm/core.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "pmu_event.h" #include "core.h" #include "common.h" @@ -22,7 +23,7 @@ using namespace std; using PMU_PAIR = std::pair; static CHIP_TYPE g_chipType = UNDEFINED_TYPE; - +static string pmuDevice = ""; namespace SOFTWARE_EVENT { PMU_PAIR ALIGNMENT_FAULTS = { @@ -853,7 +854,11 @@ static struct PmuEvt* ConstructPmuEvtFromCore(KUNPENG_PMU::CoreConfig config, in static int64_t GetKernelCoreEventConfig(const string &name) { - string eventPath = "/sys/devices/armv8_pmuv3_0/events/" + name; + auto pmuDevicePath = GetPmuDevicePath(); + if (pmuDevicePath.empty()) { + return -1; + } + string eventPath = pmuDevicePath + "/events/" + name; string realPath = GetRealPath(eventPath); if (!IsValidPath(realPath)) { return -1; @@ -874,7 +879,11 @@ static int64_t GetKernelCoreEventConfig(const string &name) static int64_t GetKernelCoreEventType() { - string eventPath = "/sys/devices/armv8_pmuv3_0/type"; + auto pmuDevicePath = GetPmuDevicePath(); + if (pmuDevicePath.empty()) { + return -1; + } + string eventPath = pmuDevicePath + "/type"; string realPath = GetRealPath(eventPath); if (!IsValidPath(realPath)) { return -1; @@ -917,4 +926,33 @@ struct PmuEvt* GetCoreEvent(const char* pmuName, int collectType) return ConstructPmuEvtFromCore(KUNPENG_PMU::CORE_EVENT_MAP.at(g_chipType).at(pmuName), collectType); } return ConstructPmuEvtFromKernel(pmuName, collectType); +} + +std::string GetPmuDevicePath() +{ + if (!pmuDevice.empty()) { + return pmuDevice; + } + + static const string DEVICE_PATH = "/sys/bus/event_source/devices/"; + DIR *dir = opendir(DEVICE_PATH.c_str()); + if (dir == nullptr) { + return ""; + } + struct dirent *dent; + while (dent = readdir(dir)) { + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..") || !strcmp(dent->d_name, "cpu")) { + continue; + } + + // look for devices like /sys/bus/event_source/devices/armv8_pmuv3_0/cpus. + // Refer to function in kernel. + string armPmuPath = DEVICE_PATH + dent->d_name + "/cpus"; + if (ExistPath(armPmuPath)) { + pmuDevice = DEVICE_PATH + dent->d_name; + break; + } + } + + return pmuDevice; } \ No newline at end of file diff --git a/pmu/pfm/core.h b/pmu/pfm/core.h index 0df6a25..4ecf3fe 100644 --- a/pmu/pfm/core.h +++ b/pmu/pfm/core.h @@ -24,5 +24,7 @@ namespace KUNPENG_PMU { struct PmuEvt* GetCoreEvent(const char* pmuName, int collectType); +std::string GetPmuDevicePath(); + #endif diff --git a/pmu/pmu_event_list.cpp b/pmu/pmu_event_list.cpp index 2007561..c4cf226 100644 --- a/pmu/pmu_event_list.cpp +++ b/pmu/pmu_event_list.cpp @@ -127,10 +127,16 @@ const char** QueryCoreEvent(unsigned *numEvt) } DIR* dir; struct dirent* entry; - string path = "/sys/devices/armv8_pmuv3_0/events/"; + auto pmuDevPath = GetPmuDevicePath(); + if (pmuDevPath.empty()) { + *numEvt = coreEventList.size(); + return coreEventList.data(); + } + string path = pmuDevPath + "/events/"; dir = opendir(path.c_str()); if (dir == nullptr) { - return nullptr; + *numEvt = coreEventList.size(); + return coreEventList.data(); } while ((entry = readdir(dir)) != nullptr) { if (entry->d_type == DT_REG) { -- 2.43.0