From 7068c0e48b13bcc58b07073376fcc055b30ee9e2 Mon Sep 17 00:00:00 2001 From: Galaxy Date: Sun, 26 May 2024 20:01:49 -0700 Subject: [PATCH] Add warning code for spe sampling. Some arch or OS does not implement context id for spe packets, and match of tid to spe events may be inaccurate. Then a warning code is returned from GetWarn. --- include/pcerrc.h | 15 +++++++++++++++ pmu/pmu.cpp | 11 +++++++++++ pmu/pmu_event_list.cpp | 1 + pmu/spe.cpp | 4 ++++ util/pcerr.cpp | 26 ++++++++++++++++++++++++++ util/pcerr.h | 1 + 6 files changed, 58 insertions(+) diff --git a/include/pcerrc.h b/include/pcerrc.h index a677cff..a835c71 100644 --- a/include/pcerrc.h +++ b/include/pcerrc.h @@ -77,6 +77,10 @@ extern "C" { #define UNKNOWN_ERROR 9999 +// warnning code +#define LIBPERF_WARN_CTXID_LOST 1000 + + /** * @brief Obtaining error codes */ @@ -86,6 +90,17 @@ int Perrorno(); * @brief Obtaining Error Information */ const char* Perror(); + +/**. + * @brief Get warnning codes +*/ +int GetWarn(); + +/** + * @brief Get warning message. +*/ +const char* GetWarnMsg(); + #ifdef __cplusplus } #endif diff --git a/pmu/pmu.cpp b/pmu/pmu.cpp index dd1ed6e..53bf707 100644 --- a/pmu/pmu.cpp +++ b/pmu/pmu.cpp @@ -248,6 +248,7 @@ static void PmuTaskAttrFree(PmuTaskAttr *taskAttr) int PmuOpen(enum PmuTaskType collectType, struct PmuAttr *attr) { + SetWarn(SUCCESS); try { auto err = CheckAttr(collectType, attr); if (err != SUCCESS) { @@ -296,16 +297,19 @@ int PmuOpen(enum PmuTaskType collectType, struct PmuAttr *attr) int PmuEnable(int pd) { + SetWarn(SUCCESS); return PmuCollectStart(pd); } int PmuDisable(int pd) { + SetWarn(SUCCESS); return PmuCollectPause(pd); } int PmuAppendData(struct PmuData *fromData, struct PmuData **toData) { + SetWarn(SUCCESS); int toLen = 0; PmuList::GetInstance()->AppendData(fromData, toData, toLen); return toLen; @@ -395,6 +399,7 @@ static int DoCollect(int pd, int milliseconds, unsigned interval) int PmuCollect(int pd, int milliseconds, unsigned interval) { + SetWarn(SUCCESS); int err = SUCCESS; string errMsg = ""; try { @@ -491,6 +496,7 @@ static int InnerCollect(int *pds, unsigned len, size_t collectTime, bool &stop) int PmuCollectV(int *pds, unsigned len, int milliseconds) { + SetWarn(SUCCESS); constexpr int collectInterval = 100; constexpr int usecPerMilli = 1000; // Collect every milliseconds, @@ -523,6 +529,7 @@ int PmuCollectV(int *pds, unsigned len, int milliseconds) void PmuStop(int pd) { + SetWarn(SUCCESS); if (!PdValid(pd)) { New(LIBPERF_ERR_INVALID_PD); return; @@ -536,6 +543,7 @@ void PmuStop(int pd) int PmuRead(int pd, struct PmuData** pmuData) { + SetWarn(SUCCESS); try { if (!PdValid(pd)) { New(LIBPERF_ERR_INVALID_PD); @@ -562,6 +570,7 @@ int PmuRead(int pd, struct PmuData** pmuData) void PmuClose(int pd) { + SetWarn(SUCCESS); if (!PdValid(pd)) { New(LIBPERF_ERR_INVALID_PD); return; @@ -667,6 +676,7 @@ struct PmuTaskAttr* AssignPmuTaskParam(enum PmuTaskType collectType, struct PmuA void PmuDataFree(struct PmuData* pmuData) { + SetWarn(SUCCESS); PmuList::GetInstance()->FreeData(pmuData); New(SUCCESS); } @@ -695,6 +705,7 @@ static void DumpStack(ofstream &out, Stack *stack, int dumpDwf) int PmuDumpData(struct PmuData *pmuData, unsigned len, char *filepath, int dumpDwf) { + SetWarn(SUCCESS); ofstream out(filepath, ios_base::app); if (!out.is_open()) { New(LIBPERF_ERR_PATH_INACCESSIBLE, "cannot access: " + string(filepath)); diff --git a/pmu/pmu_event_list.cpp b/pmu/pmu_event_list.cpp index a90861c..077587e 100644 --- a/pmu/pmu_event_list.cpp +++ b/pmu/pmu_event_list.cpp @@ -245,6 +245,7 @@ static const unordered_map QueryMap{ const char** PmuEventList(enum PmuEventType eventType, unsigned *numEvt) { lock_guard lg(pmuEventListMtx); + SetWarn(SUCCESS); const char** eventList; if (QueryMap.find(eventType) == QueryMap.end()) { New(LIBPERF_ERR_QUERY_EVENT_TYPE_INVALID, "Event type is invalid."); diff --git a/pmu/spe.cpp b/pmu/spe.cpp index 641a977..650d9a4 100644 --- a/pmu/spe.cpp +++ b/pmu/spe.cpp @@ -29,6 +29,7 @@ #include "spe.h" using namespace std; +using namespace pcerr; using namespace KUNPENG_PMU; constexpr unsigned SPE_RECORD_MAX = 100000; @@ -411,6 +412,9 @@ static void SetTidByTimestamp(struct ContextSwitchData *dummyData, int *dummyIdx // Then we do not need dummy events to derive tid for this packet. continue; } + // Some OS does not implement context id for spe packets, + // and match of tid to spe events may be inaccurate. + SetWarn(LIBPERF_WARN_CTXID_LOST); if (*dummyIdx >= dummyData[0].num - 1) { // Now, all spe records locate after the last switch-in data. diff --git a/util/pcerr.cpp b/util/pcerr.cpp index f286d25..6441a84 100644 --- a/util/pcerr.cpp +++ b/util/pcerr.cpp @@ -46,6 +46,11 @@ namespace pcerr { {LIBPERF_ERR_PATH_INACCESSIBLE, "cannot access file path"}, {LIBPERF_ERR_INVALID_SAMPLE_RATE, "invalid sample rate, please check /proc/sys/kernel/perf_event_max_sample_rate"}, }; + static std::unordered_map warnMsgs = { + {LIBPERF_WARN_CTXID_LOST, "Some SPE context packets are not found in the traces."} + }; + static int warnCode = SUCCESS; + static std::string warnMsg = ""; ProfErrorObj ProfErrorObj::profErrorObj; @@ -75,6 +80,17 @@ namespace pcerr { ProfErrorObj::GetInstance().SetProfError(profError); } + void SetWarn(int warn) + { + warnCode = warn; + auto findMsg = warnMsgs.find(warn); + if (findMsg != warnMsgs.end()) { + warnMsg = findMsg->second; + } else { + warnMsg = ""; + } + } + } // namespace pcerr int Perrorno() @@ -85,4 +101,14 @@ int Perrorno() const char* Perror() { return pcerr::ProfErrorObj::GetInstance().GetProfError()->Msg(); +} + +int GetWarn() +{ + return pcerr::warnCode; +} + +const char* GetWarnMsg() +{ + return pcerr::warnMsg.c_str(); } \ No newline at end of file diff --git a/util/pcerr.h b/util/pcerr.h index 8c43c4a..125bfe2 100644 --- a/util/pcerr.h +++ b/util/pcerr.h @@ -85,6 +85,7 @@ namespace pcerr { void [[nodiscard]] New(int code); void [[nodiscard]] New(int code, const std::string& msg); + void [[nodiscard]] SetWarn(int warn); } // namespace pcerr #endif \ No newline at end of file -- Gitee