From ff1c578a0cb239dceb0f0c8ab333bd4d045ff2d8 Mon Sep 17 00:00:00 2001 From: Yabin Date: Thu, 18 Aug 2022 17:01:54 -0700 Subject: simpleperf: update --print-hw-counter to check each cpu. Little/Big cores may have different numbers of CPU PMU hardware counters. So check them separately. Bug: 243034569 Test: run simpleperf_unit_test Change-Id: I33527d69bc935b8523482feaf98378c5f6641762 (cherry picked from commit 6b771a2e12740f4bbcef515d772e62b364d87858) --- simpleperf/cmd_stat.cpp | 27 +++++++++++++++++++-------- simpleperf/workload.cpp | 13 +++++++++++++ simpleperf/workload.h | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp index 40a6bb0b..c46bd548 100644 --- a/simpleperf/cmd_stat.cpp +++ b/simpleperf/cmd_stat.cpp @@ -739,23 +739,23 @@ bool StatCommand::ParseOptions(const std::vector& args, return true; } -bool StatCommand::PrintHardwareCounters() { +std::optional GetHardwareCountersOnCpu(int cpu) { size_t available_counters = 0; const EventType* event = FindEventTypeByName("cpu-cycles", true); if (event == nullptr) { - return false; + return std::nullopt; } perf_event_attr attr = CreateDefaultPerfEventAttr(*event); while (true) { auto workload = Workload::CreateWorkload({"sleep", "0.1"}); - if (!workload) { - return false; + if (!workload || !workload->SetCpuAffinity(cpu)) { + return std::nullopt; } std::vector> event_fds; for (size_t i = 0; i <= available_counters; i++) { EventFd* group_event_fd = event_fds.empty() ? nullptr : event_fds[0].get(); - auto event_fd = - EventFd::OpenEventFile(attr, workload->GetPid(), -1, group_event_fd, "cpu-cycles", false); + auto event_fd = EventFd::OpenEventFile(attr, workload->GetPid(), cpu, group_event_fd, + "cpu-cycles", false); if (!event_fd) { break; } @@ -771,7 +771,7 @@ bool StatCommand::PrintHardwareCounters() { for (auto& event_fd : event_fds) { PerfCounter counter; if (!event_fd->ReadCounter(&counter)) { - return false; + return std::nullopt; } if (counter.time_enabled == 0 || counter.time_enabled > counter.time_running) { always_running = false; @@ -783,7 +783,18 @@ bool StatCommand::PrintHardwareCounters() { } available_counters++; } - printf("There are %zu CPU PMU hardware counters available on this device.\n", available_counters); + return available_counters; +} + +bool StatCommand::PrintHardwareCounters() { + for (int cpu : GetOnlineCpus()) { + std::optional counters = GetHardwareCountersOnCpu(cpu); + if (!counters) { + LOG(ERROR) << "failed to get CPU PMU hardware counters on cpu " << cpu; + return false; + } + printf("There are %zu CPU PMU hardware counters available on cpu %d.\n", counters.value(), cpu); + } return true; } diff --git a/simpleperf/workload.cpp b/simpleperf/workload.cpp index 4bb7c540..142ed713 100644 --- a/simpleperf/workload.cpp +++ b/simpleperf/workload.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -160,6 +161,18 @@ void Workload::ChildProcessFn(int start_signal_fd, int exec_child_fd) { } } +bool Workload::SetCpuAffinity(int cpu) { + CHECK_EQ(work_state_, NotYetStartNewProcess); + cpu_set_t mask; + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (sched_setaffinity(GetPid(), sizeof(mask), &mask) != 0) { + PLOG(ERROR) << "sched_setaffinity failed"; + return false; + } + return true; +} + bool Workload::Start() { CHECK_EQ(work_state_, NotYetStartNewProcess); char start_signal = 1; diff --git a/simpleperf/workload.h b/simpleperf/workload.h index 2400ac8f..86b28924 100644 --- a/simpleperf/workload.h +++ b/simpleperf/workload.h @@ -43,6 +43,7 @@ class Workload { ~Workload(); + bool SetCpuAffinity(int cpu); bool Start(); bool IsStarted() { return work_state_ == Started; } pid_t GetPid() { return work_pid_; } -- cgit v1.2.3