From e15d4dfc1b1e31841fabc701c761ebb8fe78590a Mon Sep 17 00:00:00 2001 From: Galaxy Date: Mon, 29 Apr 2024 23:04:59 -0700 Subject: [PATCH] Add symbolMode in PmuAttr. Users are allowed to determine how to resolve symbols during collection. Three modes are provided: - NO_SYMBOL_RESOLVE Symbols are not resolved and stack pointer in PmuData will be set to NULL. - RESOLVE_ELF Only elf info are resolved. Symbol name and symbol address are valid in struct Symbol. - RESOLVE_ELF_DWARF Both elf and dwarf info are resolved. All fields, including source file name and line number, are valid in struct Symbol. --- include/pmu.h | 10 ++++++++++ pmu/evt.h | 6 ++++++ pmu/evt_list.cpp | 1 + pmu/evt_list.h | 5 +++-- pmu/pmu.cpp | 1 + pmu/pmu_list.cpp | 27 +++++++++++++++++++++++---- pmu/pmu_list.h | 4 ++++ pmu/sampler.cpp | 8 +++++--- 8 files changed, 53 insertions(+), 9 deletions(-) diff --git a/include/pmu.h b/include/pmu.h index f8a79ba..5c245d5 100644 --- a/include/pmu.h +++ b/include/pmu.h @@ -56,6 +56,15 @@ enum SpeEventFilter { SPE_EVENT_MISPREDICTED = 0x80, // mispredict }; +enum SymbolMode { + // in PmuData will be set to NULL. + NO_SYMBOL_RESOLVE = 0, + // Resolve elf only. Fields except lineNum and fileName in Symbol will be valid. + RESOLVE_ELF = 1, + // Resolve elf and dwarf. All fields in Symbol will be valid. + RESOLVE_ELF_DWARF = 2 +}; + struct PmuAttr { char** evtList; // event list unsigned numEvt; // length of event list @@ -71,6 +80,7 @@ struct PmuAttr { unsigned useFreq : 1; unsigned excludeUser : 1; // don't count user unsigned excludeKernel : 1; // don't count kernel + enum SymbolMode symbolMode; // refer to comments of SymbolMode // SPE related fields. enum SpeFilter dataFilter; // spe data filter diff --git a/pmu/evt.h b/pmu/evt.h index 6541136..a9e2598 100644 --- a/pmu/evt.h +++ b/pmu/evt.h @@ -48,6 +48,11 @@ public: virtual int MapPerfAttr() = 0; + void SetSymbolMode(const SymbolMode &symMode) + { + this->symMode = symMode; + } + int GetFd() const { return fd; @@ -60,6 +65,7 @@ protected: pid_t pid; struct PmuEvt* evt; ProcMap &procMap; + SymbolMode symMode = NO_SYMBOL_RESOLVE; }; int PerfEventOpen(struct perf_event_attr* attr, pid_t pid, int cpu, int groupFd, unsigned long flags); __u64 ReadOnce(__u64 *head); diff --git a/pmu/evt_list.cpp b/pmu/evt_list.cpp index 5302a14..5323fb7 100644 --- a/pmu/evt_list.cpp +++ b/pmu/evt_list.cpp @@ -95,6 +95,7 @@ int KUNPENG_PMU::EvtList::Init() if (perfEvt == nullptr) { continue; } + perfEvt->SetSymbolMode(symMode); auto err = perfEvt->Init(); if (err != SUCCESS) { return err; diff --git a/pmu/evt_list.h b/pmu/evt_list.h index a431bb7..1a54b7d 100644 --- a/pmu/evt_list.h +++ b/pmu/evt_list.h @@ -32,8 +32,8 @@ class EvtList { public: using ProcPtr = std::shared_ptr; using CpuPtr = std::shared_ptr; - EvtList(std::vector &cpuList, std::vector &pidList, std::shared_ptr pmuEvt) - : cpuList(cpuList), pidList(pidList), pmuEvt(pmuEvt) + EvtList(const SymbolMode &symbolMode, std::vector &cpuList, std::vector &pidList, std::shared_ptr pmuEvt) + : symMode(symbolMode), cpuList(cpuList), pidList(pidList), pmuEvt(pmuEvt) { this->numCpu = this->cpuList.size(); this->numPid = this->pidList.size(); @@ -80,6 +80,7 @@ private: std::set fdList; int64_t ts = 0; std::unordered_map procMap; + SymbolMode symMode = NO_SYMBOL_RESOLVE; }; } // namespace KUNPENG_PMU #endif diff --git a/pmu/pmu.cpp b/pmu/pmu.cpp index a88470f..f7016f1 100644 --- a/pmu/pmu.cpp +++ b/pmu/pmu.cpp @@ -156,6 +156,7 @@ int PmuOpen(enum PmuTaskType collectType, struct PmuAttr *attr) return -1; } + KUNPENG_PMU::PmuList::GetInstance()->SetSymbolMode(pd, attr->symbolMode); err = KUNPENG_PMU::PmuList::GetInstance()->Register(pd, taskAttr.get()); if (err != SUCCESS) { PmuList::GetInstance()->Close(pd); diff --git a/pmu/pmu_list.cpp b/pmu/pmu_list.cpp index 691ecfb..9117b75 100644 --- a/pmu/pmu_list.cpp +++ b/pmu/pmu_list.cpp @@ -40,7 +40,7 @@ namespace KUNPENG_PMU { int PmuList::Register(const int pd, PmuTaskAttr* taskParam) { - if (taskParam->pmuEvt->collectType != COUNTING) { + if (GetSymbolMode(pd) != NO_SYMBOL_RESOLVE && taskParam->pmuEvt->collectType != COUNTING) { SymResolverInit(); SymResolverRecordKernel(); } @@ -75,7 +75,7 @@ namespace KUNPENG_PMU { } fdNum += cpuTopoList.size(); + procTopoList.size(); std::shared_ptr evtList = - std::make_shared(cpuTopoList, procTopoList, pmuTaskAttrHead->pmuEvt); + std::make_shared(GetSymbolMode(pd), cpuTopoList, procTopoList, pmuTaskAttrHead->pmuEvt); InsertEvtList(pd, evtList); pmuTaskAttrHead = pmuTaskAttrHead->next; } @@ -153,6 +153,8 @@ namespace KUNPENG_PMU { // Read data from prev sampling, // and store data in . auto &evtData = GetDataList(pd); + evtData.pd = pd; + evtData.collectType = static_cast(GetTaskType(pd)); auto ts = GetCurrentTime(); auto eventList = GetEvtList(pd); for (auto item : eventList) { @@ -325,14 +327,20 @@ namespace KUNPENG_PMU { void PmuList::FillStackInfo(EventData &eventData) { + auto symMode = symModeList[eventData.pd]; + if (symMode == NO_SYMBOL_RESOLVE) { + return; + } // Parse dwarf and elf info of each pid and get stack trace for each pmu data. for (size_t i = 0; i < eventData.data.size(); ++i) { auto &pmuData = eventData.data[i]; auto &ipsData = eventData.sampleIps[i]; - if (eventData.collectType == SPE_SAMPLING) { + if (symMode == RESOLVE_ELF) { SymResolverRecordModuleNoDwarf(pmuData.pid); - } else { + } else if (symMode == RESOLVE_ELF_DWARF) { SymResolverRecordModule(pmuData.pid); + } else { + continue; } if (pmuData.stack == nullptr) { pmuData.stack = StackToHash(pmuData.pid, ipsData.ips.data(), ipsData.ips.size()); @@ -568,4 +576,15 @@ namespace KUNPENG_PMU { return SUCCESS; } + void PmuList::SetSymbolMode(const int pd, const SymbolMode &mode) + { + lock_guard lg(dataListMtx); + symModeList[pd] = mode; + } + + SymbolMode PmuList::GetSymbolMode(const unsigned pd) + { + lock_guard lg(dataListMtx); + return symModeList[pd]; + } } \ No newline at end of file diff --git a/pmu/pmu_list.h b/pmu/pmu_list.h index 67b8bd2..91994d8 100644 --- a/pmu/pmu_list.h +++ b/pmu/pmu_list.h @@ -66,6 +66,7 @@ public: int NewPd(); int GetHistoryData(const int pd, std::vector& pmuData); + void SetSymbolMode(const int pd, const SymbolMode &mode); private: using ProcPtr = std::shared_ptr; @@ -109,6 +110,7 @@ private: int CheckRlimit(const unsigned fdNum); static void AggregateData(const std::vector& evData, std::vector& newEvData); std::vector& GetPreviousData(const unsigned pd); + SymbolMode GetSymbolMode(const unsigned pd); static std::mutex pmuListMtx; static std::mutex dataListMtx; @@ -133,6 +135,8 @@ private: // Value: spe sampling cpu list. std::unordered_map> speCpuList; unsigned maxPd = 0; + + std::unordered_map symModeList; }; } // namespace KUNPENG_PMU #endif diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index bbaa991..f8ad789 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -129,9 +129,11 @@ void KUNPENG_PMU::PerfSampler::RawSampleProcess( return; } KUNPENG_PMU::PerfRawSample *sample = (KUNPENG_PMU::PerfRawSample *)event->sample.array; - // Copy ips from ring buffer and get stack info later. - for (__u64 i = 0; i < sample->nr; ++i) { - ips->ips.push_back(sample->ips[i]); + if (symMode != NO_SYMBOL_RESOLVE) { + // Copy ips from ring buffer and get stack info later. + for (__u64 i = 0; i < sample->nr; ++i) { + ips->ips.push_back(sample->ips[i]); + } } current->cpu = static_cast(sample->cpu); current->pid = static_cast(sample->pid); -- Gitee