diff --git a/include/pmu.h b/include/pmu.h index bb7cb3ab6b79c2d82baf3e8f6cc4d405b7468998..f2cb5904f8fe6bdb8bfcf4c64a5355457f439478 100644 --- a/include/pmu.h +++ b/include/pmu.h @@ -80,7 +80,7 @@ struct PmuAttr { unsigned excludeUser : 1; // don't count user unsigned excludeKernel : 1; // don't count kernel enum SymbolMode symbolMode; // refer to comments of SymbolMode - + unsigned callStack : 1; // collect complete call stack // SPE related fields. enum SpeFilter dataFilter; // spe data filter enum SpeEventFilter evFilter; // spe event filter diff --git a/pmu/pmu.cpp b/pmu/pmu.cpp index e2b0a461c17aa3bbc9abfd914293f3607e7f133d..0b50c3c26f96a1d3d3a53fb0b4462e68df70bdf5 100644 --- a/pmu/pmu.cpp +++ b/pmu/pmu.cpp @@ -616,6 +616,7 @@ static struct PmuTaskAttr* AssignTaskParam(PmuTaskType collectType, PmuAttr *att taskParam->pmuEvt->period = attr->period; taskParam->pmuEvt->excludeKernel = attr->excludeKernel; taskParam->pmuEvt->excludeUser = attr->excludeUser; + taskParam->pmuEvt->callStack = attr->callStack; return taskParam.release(); } diff --git a/pmu/pmu_event.h b/pmu/pmu_event.h index 992fa3a3ebad19556a2695ff63d225dde08ea21d..a80b1faf9a45af084113211e265ce629390ef27d 100644 --- a/pmu/pmu_event.h +++ b/pmu/pmu_event.h @@ -39,6 +39,7 @@ struct PmuEvt { int cpumask; // a representative CPU number for each socket (package) in the motherboard. unsigned excludeUser : 1; // don't count user unsigned excludeKernel : 1; // don't count kernel + unsigned callStack : 1; // collect complete call stack union { unsigned period; // sample period unsigned freq; // sample frequency diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index f8ad789527632933ebb858d17755ef461c447ce4..3fd1a17183276fdcb89b9f8ea8988efb6e06e9c1 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -131,9 +131,14 @@ void KUNPENG_PMU::PerfSampler::RawSampleProcess( KUNPENG_PMU::PerfRawSample *sample = (KUNPENG_PMU::PerfRawSample *)event->sample.array; 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]); + if (evt->callStack == 0 && sample->nr - 1 >= 0) { + ips->ips.push_back(sample->ips[sample->nr - 1]); + } else { + for (int i = sample->nr - 1; i >= 0; --i) { + ips->ips.push_back(sample->ips[i]); + } } + } current->cpu = static_cast(sample->cpu); current->pid = static_cast(sample->pid); diff --git a/symbol/symbol_resolve.cpp b/symbol/symbol_resolve.cpp index 79e97ea444f9b57381b3395e13d06e58eb25be06..7c0da16c7ebb1da0393317a0b7cc72c5f6928a50 100644 --- a/symbol/symbol_resolve.cpp +++ b/symbol/symbol_resolve.cpp @@ -817,7 +817,7 @@ struct Stack* SymbolResolve::StackToHash(int pid, unsigned long* stack, int nr) } else { current->symbol = nullptr; } - AddTail(&head, ¤t); + AddDoubleLinkedTail(&head, ¤t); } if (this->stackMap.at(pid).find(stackId) == this->stackMap.at(pid).end()) { diff --git a/util/linked_list.h b/util/linked_list.h index 2a2cd507ab36a06166bfa514a78d3472d2802b4d..ea0e687b5aa16e1c962c8875fd2c49ff6ddcba1c 100644 --- a/util/linked_list.h +++ b/util/linked_list.h @@ -55,6 +55,22 @@ void AddTail(ListNode** head, ListNode** newNode) } } +// Function to add a node at the tail of the double linked list +template +void AddDoubleLinkedTail(ListNode** head, ListNode** newNode) +{ + if (*head == nullptr) { + *head = *newNode; + } else { + ListNode* current = *head; + while (current->next != nullptr) { + current = current->next; + } + current->next = *newNode; + (*newNode)->prev = current; + } +} + // Function to free the linked list template void FreeList(ListNode** head)