diff --git a/pmu/bpf/evt_list_bpf.h b/pmu/bpf/evt_list_bpf.h index 00afaad932874105fccb016eec013660b97e35db..47ff1f9a8c8badd797fd142cdb14cab3cf1914b5 100644 --- a/pmu/bpf/evt_list_bpf.h +++ b/pmu/bpf/evt_list_bpf.h @@ -49,7 +49,9 @@ public: void SetGroupInfo(const EventGroupInfo &grpInfo) override {}; void AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) override {}; - + void ClearExitFd(std::set noProcList) override {}; + void RemoveInitErr() override {}; + private: std::vector> cpuCounterArray; std::vector> pidCounterArray; diff --git a/pmu/dummy_event.cpp b/pmu/dummy_event.cpp index 9137db89afa8c9af634139b94b5da5c2b357be97..89b955466f70fc4b66e88063e970d1063661e34c 100644 --- a/pmu/dummy_event.cpp +++ b/pmu/dummy_event.cpp @@ -24,9 +24,7 @@ static const int PAGE_SIZE = sysconf(_SC_PAGESIZE); static const int MAP_LEN = 69632; namespace KUNPENG_PMU { - - ProcessForkStrategy forkStrategy; - + DummyEvent::~DummyEvent() { dummyFlag = false; @@ -37,29 +35,14 @@ namespace KUNPENG_PMU { close(it->second.first); munmap(it->second.second, MAP_LEN); } + + hasDataCond.notify_all(); + if (consumeThread.joinable()) { consumeThread.join(); } } - std::pair> DummyEvent::GetEvtGroupState(const int groupId, std::shared_ptr evtList, groupMapPtr eventGroupInfoMap) - { - if (groupId == -1 || eventGroupInfoMap == nullptr) { - return std::make_pair(false, nullptr); - } - // if the event is the event group leader, initialize it in the default way. - if (evtList == (*eventGroupInfoMap)[groupId].evtLeader) { - return std::make_pair(false, nullptr); - } else { - // In this case, the event group contains only some uncore events or all other events. - if ((*eventGroupInfoMap)[groupId].uncoreState == static_cast(UncoreState::HasUncore)) { - return std::make_pair(false, nullptr); - } else { - return std::make_pair(true, (*eventGroupInfoMap)[groupId].evtLeader); - } - } - } - void DummyEvent::ObserverForkThread() { dummyThread = std::thread([this]() { @@ -73,18 +56,7 @@ namespace KUNPENG_PMU { consumeThread = std::thread([this]() { while (dummyFlag) { - if (forkPidQueue.empty()) { - continue; - } - std::lock_guard lg(dummyMutex); - auto& pid = forkPidQueue.front(); - for (const auto& evtList: evtLists) { - auto groupId = evtList->GetGroupId(); - auto evtGroupInfo = GetEvtGroupState(groupId, evtList, eventGroupInfoMap); - DummyContext ctx = {evtList, static_cast(pid), evtGroupInfo.first, evtGroupInfo.second}; - forkStrategy.DoHandler(ctx, evtGroupInfo.first, evtGroupInfo.second); - } - forkPidQueue.pop(); + ConsumeForkQueue(); } }); } @@ -123,6 +95,16 @@ namespace KUNPENG_PMU { dummyMap.insert({pid, std::make_pair(fd, fdMap)}); } + void DummyEvent::ConsumeForkQueue() { + std::unique_lock lg(dummyMutex); + if (forkPidQueue.empty()) { + hasDataCond.wait(lg); + } + auto &pid = forkPidQueue.front(); + PmuList::GetInstance()->AddNewProcess(pd, pid); + forkPidQueue.pop(); + } + void DummyEvent::HandleDummyData() { if (dummyMap.empty()) { @@ -148,6 +130,7 @@ namespace KUNPENG_PMU { std::lock_guard lg(dummyMutex); if((uint8_t*)page + MAP_LEN > ringBuf + off + sizeof(KUNPENG_PMU::PerfRecordFork)) { forkPidQueue.push(sample->tid); + hasDataCond.notify_all(); } } if (header->type == PERF_RECORD_EXIT) { diff --git a/pmu/dummy_event.h b/pmu/dummy_event.h index dc25970c37ea255644e1790d94a279d7c0313e16..6a8e6d8920d0ddf2ce4fba81d64e551dfebf3103 100644 --- a/pmu/dummy_event.h +++ b/pmu/dummy_event.h @@ -19,43 +19,20 @@ #include #include #include +#include #include "pcerr.h" -#include "evt_list.h" +#include "pmu_list.h" namespace KUNPENG_PMU { - struct DummyContext { - std::shared_ptr evtList; - pid_t pid; - bool groupEnable; - std::shared_ptr evtLeader; - }; - - class DummyEventStrategy { - public: - virtual void DoHandler(DummyContext& ctx, const bool groupEnable, const std::shared_ptr evtLeader) = 0; - }; - - class ProcessForkStrategy : public DummyEventStrategy { - public: - void DoHandler(DummyContext& ctx, const bool groupEnable, const std::shared_ptr evtLeader) - { - ctx.evtList->AddNewProcess(ctx.pid, groupEnable, evtLeader); - } - }; - class DummyEvent { public: - DummyEvent(std::vector>& evtLists, std::vector& ppids, groupMapPtr& eventGroupInfoMap) : - evtLists(evtLists), + DummyEvent(const unsigned &pd, std::vector& ppids) : + pd(pd), ppids(ppids), - eventGroupInfoMap(eventGroupInfoMap), dummyFlag(true) {}; ~DummyEvent(); - - std::pair> GetEvtGroupState(const int groupId, std::shared_ptr evtList, groupMapPtr eventGroupInfoMap); - /** * @brief start a thread to observe fork thread. */ @@ -64,19 +41,18 @@ namespace KUNPENG_PMU { private: std::thread dummyThread; std::thread consumeThread; - volatile std::atomic dummyFlag; - - std::vector>& evtLists; std::vector ppids; - groupMapPtr eventGroupInfoMap; + unsigned pd; std::vector exitPids; std::unordered_map> dummyMap; + std::condition_variable hasDataCond; std::mutex dummyMutex; std::queue forkPidQueue; std::vector childThreads; + void ConsumeForkQueue(); void InitDummy(pid_t pid); void ParseDummyData(void* page, pid_t pid); void HandleDummyData(); diff --git a/pmu/evt.h b/pmu/evt.h index a268d00e102744e5db34485a775e01205bb29bcc..f4b0264b82e12055577175ec973da86168c09033 100644 --- a/pmu/evt.h +++ b/pmu/evt.h @@ -30,7 +30,7 @@ public: using ProcPtr = std::shared_ptr; using ProcMap = std::unordered_map; - PerfEvt(int cpu, int pid, struct PmuEvt *evt, ProcMap &procMap) : cpu(cpu), pid(pid), evt(evt), procMap(procMap), needTryExcludeKernel(false) {} + PerfEvt(int cpu, int pid, struct PmuEvt *evt, ProcMap &procMap) : cpu(cpu), pid(pid), evt(evt), procMap(procMap), needTryExcludeKernel(false), initErr(false) {} ~PerfEvt() {} virtual int Start(); virtual int Pause(); @@ -61,6 +61,10 @@ public: this->needTryExcludeKernel = needTryExcludeKernel; } + void SetInitErr(const bool initErr) { + this->initErr = initErr; + } + int GetFd() const { return fd; @@ -74,6 +78,10 @@ public: return evt->cgroupFd; } + bool GetInitErr() const { + return initErr; + } + virtual bool IsMainPid() const { if (procMap.find(pid) != procMap.end()) { @@ -90,6 +98,7 @@ public: } protected: + bool initErr; int fd; int cpu; pid_t pid; diff --git a/pmu/evt_list.h b/pmu/evt_list.h index 4fb9de3d2b5e2b80f1e8387923dd38d8d376da9d..550ae7ec122b40fc6f750bcb75d672bc41c6db76 100644 --- a/pmu/evt_list.h +++ b/pmu/evt_list.h @@ -110,6 +110,8 @@ public: virtual void SetGroupInfo(const EventGroupInfo &grpInfo) = 0; virtual void AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) = 0; + virtual void ClearExitFd(std::set noProcList) = 0; + virtual void RemoveInitErr() = 0; protected: using PerfEvtPtr = std::shared_ptr; diff --git a/pmu/evt_list_default.cpp b/pmu/evt_list_default.cpp index f19f2349375cf438ccd0a874936491daab7a8f65..ba43d9b12965b0d78b3b8aaa552e62f011b44a09 100644 --- a/pmu/evt_list_default.cpp +++ b/pmu/evt_list_default.cpp @@ -92,11 +92,8 @@ int KUNPENG_PMU::EvtListDefault::Init(const bool groupEnable, const std::shared_ { // Init process map. for (auto& proc: pidList) { - if (proc->tid >= 0) { - procMap[proc->tid] = proc; - } + procMap[proc->tid] = proc; } - bool hasHappenedErr = false; for (unsigned int row = 0; row < numCpu; row++) { int resetOutPutFd = -1; std::vector evtVec{}; @@ -112,21 +109,26 @@ int KUNPENG_PMU::EvtListDefault::Init(const bool groupEnable, const std::shared_ perfEvt->SetSymbolMode(symMode); perfEvt->SetBranchSampleFilter(branchSampleFilter); auto evtleaderDefault = std::dynamic_pointer_cast(evtLeader); - int groupFd = groupEnable && evtleaderDefault ? evtleaderDefault->xyCounterArray[row][col]->GetFd():-1; + int groupFd = -1; + if (groupEnable && evtleaderDefault) { + // if leader initErr should skip; + if (evtleaderDefault->xyCounterArray[row][col]->GetInitErr()) { + continue; + } + groupFd = evtleaderDefault->xyCounterArray[row][col]->GetFd(); + } int err = perfEvt->Init(groupEnable, groupFd, resetOutPutFd); if (err == LIBPERF_ERR_NO_PERMISSION && !this->pmuEvt->excludeKernel && !this->pmuEvt->excludeUser && GetParanoidVal() > 1) { perfEvt->SetNeedTryExcludeKernel(true); err = perfEvt->Init(groupEnable, groupFd, resetOutPutFd); } if (err != SUCCESS) { - hasHappenedErr = true; if (!perfEvt->IsMainPid()) { - if (err == LIBPERF_ERR_NO_PROC) { - noProcList.emplace(this->pidList[col]->tid); - } + // child pid init err + perfEvt->SetInitErr(true); + evtVec.emplace_back(perfEvt); continue; } - this->AdaptErrInfo(err, perfEvt); return err; } @@ -135,10 +137,7 @@ int KUNPENG_PMU::EvtListDefault::Init(const bool groupEnable, const std::shared_ } this->xyCounterArray.emplace_back(evtVec); } - // if an exception occurs due to exited threads, clear the exited fds. - if (hasHappenedErr) { - this->ClearExitFd(); - } + return SUCCESS; } @@ -202,9 +201,9 @@ int KUNPENG_PMU::EvtListDefault::Read(EventData &eventData) std::unique_lock lg(mutex); - for (unsigned int row = 0; row < numCpu; row++) { - for (unsigned int col = 0; col < numPid; col++) { - int err = this->xyCounterArray[row][col]->BeginRead(); + for (auto rowList : this->xyCounterArray) { + for (auto evt : rowList) { + int err = evt->BeginRead(); if (err != SUCCESS) { return err; } @@ -214,31 +213,31 @@ int KUNPENG_PMU::EvtListDefault::Read(EventData &eventData) struct PmuEvtData* head = nullptr; for (unsigned int row = 0; row < numCpu; row++) { auto cpuTopo = this->cpuList[row].get(); - for (unsigned int col = 0; col < numPid; col++) { + auto rowList = this->xyCounterArray[row]; + for (auto evt : rowList) { auto cnt = eventData.data.size(); - int err = this->xyCounterArray[row][col]->Read(eventData); + int err = evt->Read(eventData); if (err != SUCCESS) { return err; } if (eventData.data.size() - cnt) { - DBG_PRINT("evt: %s pid: %d cpu: %d samples num: %d\n", pmuEvt->name.c_str(), pidList[col]->pid, + DBG_PRINT("evt: %s pid: %d cpu: %d samples num: %d\n", pmuEvt->name.c_str(), evt->GetPid(), cpuTopo->coreId, eventData.data.size() - cnt); } // Fill event name and cpu topology. - FillFields(cnt, eventData.data.size(), cpuTopo, pidList[col].get(), eventData.data); + FillFields(cnt, eventData.data.size(), cpuTopo, procMap[evt->GetPid()].get(), eventData.data); } } - for (unsigned int row = 0; row < numCpu; row++) { - for (unsigned int col = 0; col < numPid; col++) { - int err = this->xyCounterArray[row][col]->EndRead(); + for (auto rowList : this->xyCounterArray) { + for (auto evt : rowList) { + int err = evt->EndRead(); if (err != SUCCESS) { return err; } } } - this->ClearExitFd(); return SUCCESS; } @@ -263,15 +262,10 @@ std::shared_ptr KUNPENG_PMU::EvtListDefault::MapPmuAttr(in void KUNPENG_PMU::EvtListDefault::AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) { - if (pid <= 0 || evtStat == CLOSE || evtStat == STOP) { - return; - } - ProcTopology* topology = GetProcTopology(pid); - if (topology == nullptr) { + if (evtStat == CLOSE || evtStat == STOP) { return; } std::unique_lock lock(mutex); - this->pidList.emplace_back(shared_ptr(topology, FreeProcTopo)); bool hasInitErr = false; std::map perfEvtMap; for (unsigned int row = 0; row < numCpu; row++) { @@ -285,9 +279,8 @@ void KUNPENG_PMU::EvtListDefault::AddNewProcess(pid_t pid, const bool groupEnabl perfEvt->SetBranchSampleFilter(branchSampleFilter); int err = 0; if (groupEnable) { - int sz = this->pidList.size(); std::shared_ptr evtLeaderDefault = std::dynamic_pointer_cast(evtLeader); - auto groupFd = evtLeaderDefault?evtLeaderDefault->xyCounterArray[row][sz - 1]->GetFd():-1; + auto groupFd = evtLeaderDefault?evtLeaderDefault->xyCounterArray[row].back()->GetFd():-1; err = perfEvt->Init(groupEnable, groupFd, -1); } else { err = perfEvt->Init(groupEnable, -1, -1); @@ -322,38 +315,36 @@ void KUNPENG_PMU::EvtListDefault::AddNewProcess(pid_t pid, const bool groupEnabl for (const auto& evtPtr : perfEvtMap) { close(evtPtr.second->GetFd()); } - this->pidList.erase(this->pidList.end() - 1); } } -void KUNPENG_PMU::EvtListDefault::ClearExitFd() -{ - if (this->pidList.size() == 1 && this->pidList[0]->tid == -1) { - return; - } - for (const auto& it: this->pidList) { - if (it->isMain) { - continue; - } - std::string path = "/proc/" + std::to_string(it->tid); - if (!ExistPath(path)) { - noProcList.insert(it->tid); +void KUNPENG_PMU::EvtListDefault::RemoveInitErr() +{ + for (auto &perfVet : xyCounterArray) { + for (auto it = perfVet.begin(); it != perfVet.end();) { + if (it->get()->GetInitErr()) { + it = perfVet.erase(it); + continue; + } + ++it; } } +} - if (noProcList.empty()) { - return; - } +void KUNPENG_PMU::EvtListDefault::ClearExitFd(std::set noProcList) +{ + std::unique_lock lock(mutex); // erase the exit perfVet - for (int row = 0; row < numCpu; row++) { - auto& perfVet = xyCounterArray[row]; - for (auto it = perfVet.begin(); it != perfVet.end();) { + for (auto& perfVet : xyCounterArray) { + for (auto it = perfVet.begin(); it != perfVet.end();) { int pid = it->get()->GetPid(); if (noProcList.find(pid) != noProcList.end()) { int fd = it->get()->GetFd(); - this->fdList.erase(this->fdList.find(fd)); - close(fd); + if (this->fdList.find(fd) != this->fdList.end()) { + this->fdList.erase(fd); + close(fd); + } it = perfVet.erase(it); continue; } @@ -362,19 +353,9 @@ void KUNPENG_PMU::EvtListDefault::ClearExitFd() } for (const auto& exitPid: noProcList) { - for (auto it = this->pidList.begin(); it != this->pidList.end();) { - if (it->get()->tid == exitPid) { - this->unUsedPidList.push_back(it.operator*()); - it = this->pidList.erase(it); - continue; - } - ++it; - } procMap.erase(exitPid); numPid--; } - - noProcList.clear(); } void KUNPENG_PMU::EvtListDefault::SetGroupInfo(const EventGroupInfo &grpInfo) diff --git a/pmu/evt_list_default.h b/pmu/evt_list_default.h index bc4d5d21ac1fcce108fc8ecfa308149e6b12dfa9..48d63010d5c6aaaae8513b18ee3929edd5e363f6 100644 --- a/pmu/evt_list_default.h +++ b/pmu/evt_list_default.h @@ -47,7 +47,8 @@ public: void SetGroupInfo(const EventGroupInfo &grpInfo) override; void AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) override; - void ClearExitFd(); + void ClearExitFd(std::set noProcList) override; + void RemoveInitErr() override; private: int CollectorXYArrayDoTask(std::vector>& xyArray, int task); void FillFields(size_t start, size_t end, CpuTopology* cpuTopo, ProcTopology* procTopo, std::vector& pmuData); diff --git a/pmu/perf_counter_default.cpp b/pmu/perf_counter_default.cpp index 656d42e911171d1c9e93ac265fc36b4f7727da21..4a6e5fe766cdca77dd53e9f386f481ff112046af 100644 --- a/pmu/perf_counter_default.cpp +++ b/pmu/perf_counter_default.cpp @@ -308,9 +308,10 @@ int KUNPENG_PMU::PerfCounterDefault::MapPerfAttr(const bool groupEnable, const i // support cgroup feature unsigned flags = 0; + int pid = this->pid; if (this->GetCgroupFd() != -1) { flags = PERF_FLAG_PID_CGROUP | PERF_FLAG_FD_CLOEXEC; - this->pid = this->GetCgroupFd(); + pid = this->GetCgroupFd(); } /** @@ -331,9 +332,9 @@ int KUNPENG_PMU::PerfCounterDefault::MapPerfAttr(const bool groupEnable, const i groupStatus = GroupStatus::GROUP_LEADER; } attr.read_format |= PERF_FORMAT_GROUP; - this->fd = PerfEventOpen(&attr, this->pid, this->cpu, groupFd, flags); + this->fd = PerfEventOpen(&attr, pid, this->cpu, groupFd, flags); } else { - this->fd = PerfEventOpen(&attr, this->pid, this->cpu, groupFd, flags); + this->fd = PerfEventOpen(&attr, pid, this->cpu, groupFd, flags); groupStatus = GroupStatus::NO_GROUP; } this->groupFd = groupFd; diff --git a/pmu/pmu_list.cpp b/pmu/pmu_list.cpp index 47ef6e17f6631da2f6ddce9d8b666e0a5483f6da..c8d1b1d0d9950e8506280866ca09b4e8752a8d69 100644 --- a/pmu/pmu_list.cpp +++ b/pmu/pmu_list.cpp @@ -69,7 +69,7 @@ namespace KUNPENG_PMU { evtData.collectType = static_cast(pmuTaskAttrHead->pmuEvt->collectType); evtData.pd = pd; } - + unsigned fdNum = 0; while (pmuTaskAttrHead) { /** @@ -80,26 +80,25 @@ namespace KUNPENG_PMU { if (err != SUCCESS) { return err; } - /** * Create process topology list */ std::vector procTopoList; - err = PrepareProcTopoList(pmuTaskAttrHead, procTopoList); + err = PrepareProcTopoList(pmuTaskAttrHead, procTopoList, pd); if (err != SUCCESS) { return err; } fdNum += CalRequireFd(cpuTopoList.size(), procTopoList.size(), taskParam->pmuEvt->collectType); - #ifdef BPF_ENABLED +#ifdef BPF_ENABLED if (taskParam->pmuEvt->enableBpf) { - std::shared_ptr evtList = - std::make_shared(GetSymbolMode(pd), cpuTopoList, procTopoList, pmuTaskAttrHead->pmuEvt, pmuTaskAttrHead->groupId); + std::shared_ptr evtList = std::make_shared( + GetSymbolMode(pd), cpuTopoList, procTopoList, pmuTaskAttrHead->pmuEvt, pmuTaskAttrHead->groupId); InsertEvtList(pd, evtList); } else - #endif +#endif { - std::shared_ptr evtList = - std::make_shared(GetSymbolMode(pd), cpuTopoList, procTopoList, pmuTaskAttrHead->pmuEvt, pmuTaskAttrHead->groupId); + std::shared_ptr evtList = std::make_shared( + GetSymbolMode(pd), cpuTopoList, procTopoList, pmuTaskAttrHead->pmuEvt, pmuTaskAttrHead->groupId); evtList->SetBranchSampleFilter(GetBranchSampleFilter(pd)); InsertEvtList(pd, evtList); } @@ -195,6 +194,10 @@ namespace KUNPENG_PMU { } groupMapPtr eventDataEvtGroup = std::make_shared>(eventGroupInfoMap); InsertDataEvtGroupList(pd, eventDataEvtGroup); + // after init move the init err perfEvt + for (auto& evtList : GetEvtList(pd)) { + evtList->RemoveInitErr(); + } return SUCCESS; } @@ -223,6 +226,77 @@ namespace KUNPENG_PMU { return SUCCESS; } + std::pair> PmuList::GetEvtGroupState(const int groupId, std::shared_ptr evtList, groupMapPtr eventGroupInfoMap) + { + if (groupId == -1 || eventGroupInfoMap == nullptr) { + return std::make_pair(false, nullptr); + } + // if the event is the event group leader, initialize it in the default way. + if (evtList == (*eventGroupInfoMap)[groupId].evtLeader) { + return std::make_pair(false, nullptr); + } else { + // In this case, the event group contains only some uncore events or all other events. + if ((*eventGroupInfoMap)[groupId].uncoreState == static_cast(UncoreState::HasUncore)) { + return std::make_pair(false, nullptr); + } else { + return std::make_pair(true, (*eventGroupInfoMap)[groupId].evtLeader); + } + } + } + + void PmuList::AddNewProcess(const unsigned &pd, int pid) + { + if (pid <= 0) { + return; + } + auto& procList = pmuProcList[pd]; + ProcTopology* topology = GetProcTopology(pid); + if (topology == nullptr) { + return; + } + procList.emplace_back(shared_ptr(topology, FreeProcTopo)); + + auto eventList = GetEvtList(pd); + for (const auto& evtList : eventList) { + auto groupId = evtList->GetGroupId(); + auto evtGroupInfo = GetEvtGroupState(groupId, evtList, GetDataEvtGroupList(pd)); + evtList->AddNewProcess(pid, evtGroupInfo.first, evtGroupInfo.second); + } + } + + void PmuList::ClearExitFd(const unsigned &pd) + { + if (pmuProcList.find(pd) == pmuProcList.end()) { + return; + } + auto &pidList = pmuProcList[pd]; + if (pidList.size() == 1 && pidList[0]->tid == -1) { + return; + } + std::set noProcList; + for (const auto &it : pidList) { + if (it->isMain) { + continue; + } + std::string path = "/proc/" + std::to_string(it->tid); + if (!ExistPath(path)) { + noProcList.insert(it->tid); + } + } + + if (noProcList.empty()) { + return; + } + + auto eventList = GetEvtList(pd); + for (const auto& evtList : eventList) { + evtList->ClearExitFd(noProcList); + } + + noProcList.clear(); + } + + std::vector& PmuList::Read(const int pd) { // Exchange data in to . @@ -368,6 +442,8 @@ namespace KUNPENG_PMU { return err; } } + + this->ClearExitFd(pd); return SUCCESS; } @@ -946,7 +1022,7 @@ namespace KUNPENG_PMU { return SUCCESS; } - int PmuList::PrepareProcTopoList(PmuTaskAttr* pmuTaskAttrHead, std::vector& procTopoList) const + int PmuList::PrepareProcTopoList(PmuTaskAttr* pmuTaskAttrHead, std::vector& procTopoList, const int pd) { if (pmuTaskAttrHead->pidList.empty() || (pmuTaskAttrHead->pidList.size() == 1 && pmuTaskAttrHead->pidList[0] == -1)) { struct ProcTopology* procTopo = GetProcTopology(-1); @@ -954,9 +1030,14 @@ namespace KUNPENG_PMU { New(LIBPERF_ERR_FAIL_GET_PROC); return LIBPERF_ERR_FAIL_GET_PROC; } + procTopo->isMain = true; procTopoList.emplace_back(unique_ptr(procTopo, FreeProcTopo)); return SUCCESS; } + if (pmuProcList.find(pd) != pmuProcList.end()) { + procTopoList = pmuProcList[pd]; + return SUCCESS; + } for (int masterPid : pmuTaskAttrHead->pidList) { int numChild = 0; int* childTidList = GetChildTid(masterPid, &numChild); @@ -981,6 +1062,7 @@ namespace KUNPENG_PMU { return LIBPERF_ERR_FAIL_GET_PROC; } } + pmuProcList[pd] = procTopoList; return SUCCESS; } @@ -1031,7 +1113,7 @@ namespace KUNPENG_PMU { if (taskParam->pidList.empty()) { return; } - auto* dummyEvent = new DummyEvent(GetEvtList(pd), ppidList.at(pd), GetDataEvtGroupList(pd)); + auto* dummyEvent = new DummyEvent(pd, ppidList.at(pd)); dummyEvent->ObserverForkThread(); dummyList[pd] = dummyEvent; } diff --git a/pmu/pmu_list.h b/pmu/pmu_list.h index 61a02425b485896026bff548589fb323270e1107..3d0e67849f4d9abf165b3e310f0939458fa7d4cd 100644 --- a/pmu/pmu_list.h +++ b/pmu/pmu_list.h @@ -25,6 +25,8 @@ namespace KUNPENG_PMU { +class DummyEvent; + enum AnalysisStatus { STOP_RESOLVE=0, // stop resolving data GOING_RESOLVE=1 // go resolving data @@ -84,6 +86,7 @@ public: int ResolvePmuDataSymbol(struct PmuData* iPmuData); std::vector GetMetaData(PmuData* pmuData) const; + void AddNewProcess(const unsigned &pd, int pid); private: using ProcPtr = std::shared_ptr; @@ -101,6 +104,7 @@ private: void EraseSymModeList(const unsigned pd); void ErasePpidList(const unsigned pd); + std::pair> GetEvtGroupState(const int groupId, std::shared_ptr evtList, groupMapPtr eventGroupInfoMap); int EvtInit(const bool groupEnable, const std::shared_ptr evtLeader, const int pd, const std::shared_ptr &evtList); int Init(const int pd); @@ -124,9 +128,11 @@ private: bool IsCpuInList(const int &cpu) const; void AddSpeCpu(const unsigned &pd, const int &cpu); void EraseSpeCpu(const unsigned &pd); + void ClearExitFd(const unsigned &pd); + void RemoveInitErrEvt(const unsigned &pd); int PrepareCpuTopoList( const unsigned& pd, PmuTaskAttr* pmuTaskAttrHead, std::vector& cpuTopoList); - int PrepareProcTopoList(PmuTaskAttr* pmuTaskAttrHead, std::vector& procTopoList) const; + int PrepareProcTopoList(PmuTaskAttr* pmuTaskAttrHead, std::vector& procTopoList, const int pd); int CheckRlimit(const unsigned fdNum); static unsigned CalRequireFd(unsigned cpuSize, unsigned proSize, const unsigned collectType); static void AggregateData(const std::vector& evData, std::vector& newEvData); @@ -187,6 +193,8 @@ private: // Key: pd // Value: analysis status std::unordered_map analysisStatusList; + + std::unordered_map> pmuProcList; }; } // namespace KUNPENG_PMU #endif diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index 88e58f75ecd72c0fe9edabc70154e367ab35533a..865c9791efe8443eab06c47b0f1bba6afe1e0b71 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -88,13 +88,14 @@ int KUNPENG_PMU::PerfSampler::MapPerfAttr(const bool groupEnable, const int grou attr.disabled = 0; } unsigned flags = 0; + int pid = this->pid; if (this->GetCgroupFd() != -1) { flags = PERF_FLAG_PID_CGROUP | PERF_FLAG_FD_CLOEXEC; - this->pid = this->GetCgroupFd(); + pid = this->GetCgroupFd(); } - this->fd = PerfEventOpen(&attr, this->pid, this->cpu, groupFd, flags); - DBG_PRINT("pid: %d type: %d cpu: %d config: %X myfd: %d groupfd: %d\n", this->pid, attr.type, cpu, attr.config, this->fd, groupFd); + this->fd = PerfEventOpen(&attr, pid, this->cpu, groupFd, flags); + DBG_PRINT("pid: %d type: %d cpu: %d config: %X myfd: %d groupfd: %d\n", pid, attr.type, cpu, attr.config, this->fd, groupFd); if (__glibc_unlikely(this->fd < 0)) { return MapErrno(errno); } diff --git a/test/test_perf/case/test_new_fork.cpp b/test/test_perf/case/test_new_fork.cpp index 0716da5722ec48114e5961d50a5c9031b2dbcc53..f63fd65476c18ac372ed4be417e3b6edc7e024e8 100644 --- a/test/test_perf/case/test_new_fork.cpp +++ b/test/test_perf/case/test_new_fork.cpp @@ -20,7 +20,7 @@ void sum() { int sum = 0; for (int i = 0; i < 2000; i++) { - sleep(1000); + usleep(1000); sum += i; } } diff --git a/test/test_perf/test_count.cpp b/test/test_perf/test_count.cpp index 380ceb9919ea1c2253017fafcf69d37538b9faaf..7dd484dec8830fbf007c8ff2f5366de81e91eaa9 100644 --- a/test/test_perf/test_count.cpp +++ b/test/test_perf/test_count.cpp @@ -183,7 +183,7 @@ TEST_F(TestCount, NumaFluxWr) for (int i=0;i