diff --git a/include/pcerrc.h b/include/pcerrc.h index ff666eaa7f0e9594094fb3d0cb87fb3fc646fb88..a1166124ec0121ba284e84dd387910e6c4d6fc5a 100644 --- a/include/pcerrc.h +++ b/include/pcerrc.h @@ -126,6 +126,7 @@ extern "C" { #define LIBPERF_ERR_BPF_ACT_FAILED 1079 #define LIBPERF_ERR_INVALID_BPF_PARAM 1080 #define LIBPERF_ERR_NULL_POINTER 1081 +#define LIBPERF_ERR_BUFFER_CORRUPTED 1082 #define UNKNOWN_ERROR 9999 diff --git a/pmu/sample_process.cpp b/pmu/sample_process.cpp index 670d0c89ee6e7f017529c0e9124bae06955dccb1..3eef6c6a7d6ed49a2daef81cec060d9a387e4d70 100644 --- a/pmu/sample_process.cpp +++ b/pmu/sample_process.cpp @@ -16,6 +16,7 @@ #include #include #include "pcerrc.h" +#include "pcerr.h" #include "evt.h" #include "sample_process.h" @@ -23,6 +24,8 @@ #define MB() asm volatile("dmb ish" ::: "memory") static constexpr int MAX_DATA_SIZE = 8192; +using namespace pcerr; + void KUNPENG_PMU::PerfMmapReadDone(PerfMmap &map) { struct perf_event_mmap_page *base = (struct perf_event_mmap_page *)map.base; @@ -62,6 +65,10 @@ static inline union KUNPENG_PMU::PerfEvent *PerfMmapRead(KUNPENG_PMU::PerfMmap & event = (union KUNPENG_PMU::PerfEvent *)&data[*startPointer & map.mask]; size = event->header.size; + if (__glibc_unlikely(size == 0)) { + New(LIBPERF_ERR_BUFFER_CORRUPTED); + return nullptr; + } if (__glibc_unlikely(size < sizeof(event->header) || diff < size)) { return nullptr; diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index 4a275950ded8698806f7706b82febb8dbc10a641..202c4afd04da0246de654a731fad058e002270e2 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -352,6 +352,9 @@ int KUNPENG_PMU::PerfSampler::Read(EventData &eventData) } auto cnt = eventData.data.size(); this->ReadRingBuffer(eventData); + if (__glibc_unlikely(Perrorno() == LIBPERF_ERR_BUFFER_CORRUPTED)) { + return Perrorno(); + } if (this->pid == -1) { FillComm(cnt, eventData.data.size(), eventData.data); } diff --git a/pmu/spe.cpp b/pmu/spe.cpp index a461ab25710abc05273820bfab138aeb8207a999..9da1c123680501920b57248aab4cd930a1821ea8 100644 --- a/pmu/spe.cpp +++ b/pmu/spe.cpp @@ -359,7 +359,7 @@ static void ParseContextSwitch(PerfEventSampleContextSwitch *contextSample, Cont } } -void Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize) +int Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize) { uint64_t maxNum = size / sizeof(struct ContextSwitchData); uint64_t num = 1; @@ -373,6 +373,9 @@ void Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData while ((dataTail < dataHead) && (num < maxNum)) { uint64_t off = dataTail % mpage->data_size; struct perf_event_header *header = (struct perf_event_header *)(ringBuf + off); + if (__glibc_unlikely(header->size == 0)) { + return LIBPERF_ERR_BUFFER_CORRUPTED; + } if (header->type == PERF_RECORD_MMAP) { struct PerfRecordMmap *sample = (struct PerfRecordMmap *)header; @@ -430,6 +433,7 @@ void Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData mpage->data_tail = mpage->data_head; MB(); + return SUCCESS; } static void SetTidByTimestamp(struct ContextSwitchData *dummyData, int *dummyIdx, struct SpeRecord *buf, @@ -559,7 +563,11 @@ int Spe::SpeReadData(struct SpeContext *context, struct SpeRecord *buf, int size { int remainSize = size; int dummySize = context->dummyMmapSize; - CoreDummyData(context->coreCtxes, dummyData, dummySize, context->pageSize); + int err = CoreDummyData(context->coreCtxes, dummyData, dummySize, context->pageSize); + if (err != SUCCESS) { + New(err); + return -1; + } CoreSpeData(context->coreCtxes, dummyData, buf, &remainSize, cpu); return size - remainSize; } @@ -658,7 +666,7 @@ int Spe::Read() pidRecords[rec->tid].push_back(rec); } status |= READ; - if (Perrorno() == LIBPERF_ERR_KERNEL_NOT_SUPPORT) { + if (Perrorno() == LIBPERF_ERR_KERNEL_NOT_SUPPORT || Perrorno() == LIBPERF_ERR_BUFFER_CORRUPTED) { return Perrorno(); } return SUCCESS; diff --git a/pmu/spe.h b/pmu/spe.h index 381508d7b401c2864e99f540631678c48f07b664..d71f63bb5549dd0e1eb0c07ef5e7336621ab84f3 100644 --- a/pmu/spe.h +++ b/pmu/spe.h @@ -210,7 +210,7 @@ public: private: int SpeReadData(struct SpeContext *context, struct SpeRecord *buf, int size); - void CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize); + int CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize); void UpdateProcMap(__u32 ppid, __u32 pid); const unsigned short NONE = 0; diff --git a/python/modules/kperf/perror.py b/python/modules/kperf/perror.py index 62cb6017da77bb0009d6df7705172186dd6297f6..f0dec93bd08d8be897d8fc253d9a6c9c38edc6a3 100644 --- a/python/modules/kperf/perror.py +++ b/python/modules/kperf/perror.py @@ -125,6 +125,7 @@ class Error: LIBPERF_ERR_BPF_ACT_FAILED = 1079 LIBPERF_ERR_INVALID_BPF_PARAM = 1080 LIBPERF_ERR_NULL_POINTER = 1081 + LIBPERF_ERR_BUFFER_CORRUPTED = 1082 UNKNOWN_ERROR = 9999