xref: /aosp_15_r20/system/extras/simpleperf/event_selection_set.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #ifndef SIMPLE_PERF_EVENT_SELECTION_SET_H_
18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_EVENT_SELECTION_SET_H_
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <functional>
21*288bf522SAndroid Build Coastguard Worker #include <map>
22*288bf522SAndroid Build Coastguard Worker #include <set>
23*288bf522SAndroid Build Coastguard Worker #include <unordered_map>
24*288bf522SAndroid Build Coastguard Worker #include <vector>
25*288bf522SAndroid Build Coastguard Worker 
26*288bf522SAndroid Build Coastguard Worker #include <android-base/macros.h>
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #include "IOEventLoop.h"
29*288bf522SAndroid Build Coastguard Worker #include "RecordReadThread.h"
30*288bf522SAndroid Build Coastguard Worker #include "event_attr.h"
31*288bf522SAndroid Build Coastguard Worker #include "event_fd.h"
32*288bf522SAndroid Build Coastguard Worker #include "event_type.h"
33*288bf522SAndroid Build Coastguard Worker #include "perf_event.h"
34*288bf522SAndroid Build Coastguard Worker #include "record.h"
35*288bf522SAndroid Build Coastguard Worker 
36*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker constexpr double DEFAULT_PERIOD_TO_CHECK_MONITORED_TARGETS_IN_SEC = 1;
39*288bf522SAndroid Build Coastguard Worker constexpr uint64_t DEFAULT_SAMPLE_FREQ_FOR_NONTRACEPOINT_EVENT = 4000;
40*288bf522SAndroid Build Coastguard Worker constexpr uint64_t DEFAULT_SAMPLE_PERIOD_FOR_TRACEPOINT_EVENT = 1;
41*288bf522SAndroid Build Coastguard Worker 
42*288bf522SAndroid Build Coastguard Worker struct CounterInfo {
43*288bf522SAndroid Build Coastguard Worker   pid_t tid;
44*288bf522SAndroid Build Coastguard Worker   int cpu;
45*288bf522SAndroid Build Coastguard Worker   PerfCounter counter;
46*288bf522SAndroid Build Coastguard Worker };
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker struct CountersInfo {
49*288bf522SAndroid Build Coastguard Worker   uint32_t group_id;
50*288bf522SAndroid Build Coastguard Worker   std::string event_name;
51*288bf522SAndroid Build Coastguard Worker   std::string event_modifier;
52*288bf522SAndroid Build Coastguard Worker   std::vector<CounterInfo> counters;
53*288bf522SAndroid Build Coastguard Worker };
54*288bf522SAndroid Build Coastguard Worker 
55*288bf522SAndroid Build Coastguard Worker struct SampleRate {
56*288bf522SAndroid Build Coastguard Worker   // There are two ways to set sample rate:
57*288bf522SAndroid Build Coastguard Worker   // 1. sample_freq: take [sample_freq] samples every second.
58*288bf522SAndroid Build Coastguard Worker   // 2. sample_period: take one sample every [sample_period] events happen.
59*288bf522SAndroid Build Coastguard Worker   uint64_t sample_freq;
60*288bf522SAndroid Build Coastguard Worker   uint64_t sample_period;
sample_freqSampleRate61*288bf522SAndroid Build Coastguard Worker   SampleRate(uint64_t freq = 0, uint64_t period = 0) : sample_freq(freq), sample_period(period) {}
UseFreqSampleRate62*288bf522SAndroid Build Coastguard Worker   bool UseFreq() const {
63*288bf522SAndroid Build Coastguard Worker     // Only use one way to set sample rate.
64*288bf522SAndroid Build Coastguard Worker     CHECK_NE(sample_freq != 0u, sample_period != 0u);
65*288bf522SAndroid Build Coastguard Worker     return sample_freq != 0u;
66*288bf522SAndroid Build Coastguard Worker   }
67*288bf522SAndroid Build Coastguard Worker };
68*288bf522SAndroid Build Coastguard Worker 
69*288bf522SAndroid Build Coastguard Worker struct AddrFilter {
70*288bf522SAndroid Build Coastguard Worker   enum Type {
71*288bf522SAndroid Build Coastguard Worker     FILE_RANGE,
72*288bf522SAndroid Build Coastguard Worker     FILE_START,
73*288bf522SAndroid Build Coastguard Worker     FILE_STOP,
74*288bf522SAndroid Build Coastguard Worker     KERNEL_RANGE,
75*288bf522SAndroid Build Coastguard Worker     KERNEL_START,
76*288bf522SAndroid Build Coastguard Worker     KERNEL_STOP,
77*288bf522SAndroid Build Coastguard Worker   } type;
78*288bf522SAndroid Build Coastguard Worker   uint64_t addr;
79*288bf522SAndroid Build Coastguard Worker   uint64_t size;
80*288bf522SAndroid Build Coastguard Worker   std::string file_path;
81*288bf522SAndroid Build Coastguard Worker 
AddrFilterAddrFilter82*288bf522SAndroid Build Coastguard Worker   AddrFilter(AddrFilter::Type type, uint64_t addr, uint64_t size, const std::string& file_path)
83*288bf522SAndroid Build Coastguard Worker       : type(type), addr(addr), size(size), file_path(file_path) {}
84*288bf522SAndroid Build Coastguard Worker 
85*288bf522SAndroid Build Coastguard Worker   std::string ToString() const;
86*288bf522SAndroid Build Coastguard Worker };
87*288bf522SAndroid Build Coastguard Worker 
88*288bf522SAndroid Build Coastguard Worker // EventSelectionSet helps to monitor events. It is used in following steps:
89*288bf522SAndroid Build Coastguard Worker // 1. Create an EventSelectionSet, and add event types to monitor by calling
90*288bf522SAndroid Build Coastguard Worker //    AddEventType() or AddEventGroup().
91*288bf522SAndroid Build Coastguard Worker // 2. Define how to monitor events by calling SetEnableOnExec(), SampleIdAll(),
92*288bf522SAndroid Build Coastguard Worker //    SetSampleFreq(), etc.
93*288bf522SAndroid Build Coastguard Worker // 3. Start monitoring by calling OpenEventFilesForCpus() or
94*288bf522SAndroid Build Coastguard Worker //    OpenEventFilesForThreadsOnCpus(). If SetEnableOnExec() has been called
95*288bf522SAndroid Build Coastguard Worker //    in step 2, monitor will be delayed until the monitored thread calls
96*288bf522SAndroid Build Coastguard Worker //    exec().
97*288bf522SAndroid Build Coastguard Worker // 4. Read counters by calling ReadCounters(), or read mapped event records
98*288bf522SAndroid Build Coastguard Worker //    by calling MmapEventFiles(), PrepareToReadMmapEventData() and
99*288bf522SAndroid Build Coastguard Worker //    FinishReadMmapEventData().
100*288bf522SAndroid Build Coastguard Worker // 5. Stop monitoring automatically in the destructor of EventSelectionSet by
101*288bf522SAndroid Build Coastguard Worker //    closing perf event files.
102*288bf522SAndroid Build Coastguard Worker 
103*288bf522SAndroid Build Coastguard Worker class EventSelectionSet {
104*288bf522SAndroid Build Coastguard Worker  public:
105*288bf522SAndroid Build Coastguard Worker   EventSelectionSet(bool for_stat_cmd);
106*288bf522SAndroid Build Coastguard Worker   ~EventSelectionSet();
107*288bf522SAndroid Build Coastguard Worker 
empty()108*288bf522SAndroid Build Coastguard Worker   bool empty() const { return groups_.empty(); }
109*288bf522SAndroid Build Coastguard Worker 
110*288bf522SAndroid Build Coastguard Worker   bool AddEventType(const std::string& event_name);
111*288bf522SAndroid Build Coastguard Worker   bool AddEventType(const std::string& event_name, const SampleRate& sample_rate);
112*288bf522SAndroid Build Coastguard Worker   bool AddEventGroup(const std::vector<std::string>& event_names);
113*288bf522SAndroid Build Coastguard Worker   // For each sample generated for the existing event group, add counters for selected events.
114*288bf522SAndroid Build Coastguard Worker   bool AddCounters(const std::vector<std::string>& event_names);
115*288bf522SAndroid Build Coastguard Worker   std::vector<const EventType*> GetEvents() const;
116*288bf522SAndroid Build Coastguard Worker   std::vector<const EventType*> GetTracepointEvents() const;
117*288bf522SAndroid Build Coastguard Worker   bool ExcludeKernel() const;
HasAuxTrace()118*288bf522SAndroid Build Coastguard Worker   bool HasAuxTrace() const { return has_aux_trace_; }
119*288bf522SAndroid Build Coastguard Worker   EventAttrIds GetEventAttrWithId() const;
120*288bf522SAndroid Build Coastguard Worker   std::unordered_map<uint64_t, std::string> GetEventNamesById() const;
121*288bf522SAndroid Build Coastguard Worker   std::unordered_map<uint64_t, int> GetCpusById() const;
122*288bf522SAndroid Build Coastguard Worker   std::map<int, size_t> GetHardwareCountersForCpus() const;
123*288bf522SAndroid Build Coastguard Worker 
124*288bf522SAndroid Build Coastguard Worker   void SetEnableCondition(bool enable_on_open, bool enable_on_exec);
125*288bf522SAndroid Build Coastguard Worker   bool IsEnabledOnExec() const;
126*288bf522SAndroid Build Coastguard Worker   void SampleIdAll();
127*288bf522SAndroid Build Coastguard Worker   // Only set sample rate for events that haven't set sample rate.
128*288bf522SAndroid Build Coastguard Worker   void SetSampleRateForNewEvents(const SampleRate& rate);
129*288bf522SAndroid Build Coastguard Worker   // Set on which cpus to monitor events. Only set cpus for events that haven't set before.
130*288bf522SAndroid Build Coastguard Worker   void SetCpusForNewEvents(const std::vector<int>& cpus);
131*288bf522SAndroid Build Coastguard Worker   bool SetBranchSampling(uint64_t branch_sample_type);
132*288bf522SAndroid Build Coastguard Worker   void EnableFpCallChainSampling();
133*288bf522SAndroid Build Coastguard Worker   bool EnableDwarfCallChainSampling(uint32_t dump_stack_size);
134*288bf522SAndroid Build Coastguard Worker   void SetInherit(bool enable);
135*288bf522SAndroid Build Coastguard Worker   void SetClockId(int clock_id);
136*288bf522SAndroid Build Coastguard Worker   bool NeedKernelSymbol() const;
137*288bf522SAndroid Build Coastguard Worker   void SetRecordNotExecutableMaps(bool record);
138*288bf522SAndroid Build Coastguard Worker   bool RecordNotExecutableMaps() const;
139*288bf522SAndroid Build Coastguard Worker   void EnableSwitchRecord();
140*288bf522SAndroid Build Coastguard Worker   void WakeupPerSample();
SetAddrFilters(std::vector<AddrFilter> && filters)141*288bf522SAndroid Build Coastguard Worker   void SetAddrFilters(std::vector<AddrFilter>&& filters) { addr_filters_ = std::move(filters); }
142*288bf522SAndroid Build Coastguard Worker   bool SetTracepointFilter(const std::string& filter);
143*288bf522SAndroid Build Coastguard Worker 
144*288bf522SAndroid Build Coastguard Worker   template <typename Collection = std::vector<pid_t>>
AddMonitoredProcesses(const Collection & processes)145*288bf522SAndroid Build Coastguard Worker   void AddMonitoredProcesses(const Collection& processes) {
146*288bf522SAndroid Build Coastguard Worker     processes_.insert(processes.begin(), processes.end());
147*288bf522SAndroid Build Coastguard Worker   }
148*288bf522SAndroid Build Coastguard Worker 
149*288bf522SAndroid Build Coastguard Worker   template <typename Collection = std::vector<pid_t>>
AddMonitoredThreads(const Collection & threads)150*288bf522SAndroid Build Coastguard Worker   void AddMonitoredThreads(const Collection& threads) {
151*288bf522SAndroid Build Coastguard Worker     threads_.insert(threads.begin(), threads.end());
152*288bf522SAndroid Build Coastguard Worker   }
153*288bf522SAndroid Build Coastguard Worker 
GetMonitoredProcesses()154*288bf522SAndroid Build Coastguard Worker   const std::set<pid_t>& GetMonitoredProcesses() const { return processes_; }
155*288bf522SAndroid Build Coastguard Worker 
GetMonitoredThreads()156*288bf522SAndroid Build Coastguard Worker   const std::set<pid_t>& GetMonitoredThreads() const { return threads_; }
157*288bf522SAndroid Build Coastguard Worker 
ClearMonitoredTargets()158*288bf522SAndroid Build Coastguard Worker   void ClearMonitoredTargets() {
159*288bf522SAndroid Build Coastguard Worker     processes_.clear();
160*288bf522SAndroid Build Coastguard Worker     threads_.clear();
161*288bf522SAndroid Build Coastguard Worker   }
162*288bf522SAndroid Build Coastguard Worker 
HasMonitoredTarget()163*288bf522SAndroid Build Coastguard Worker   bool HasMonitoredTarget() const { return !processes_.empty() || !threads_.empty(); }
164*288bf522SAndroid Build Coastguard Worker 
GetIOEventLoop()165*288bf522SAndroid Build Coastguard Worker   IOEventLoop* GetIOEventLoop() { return loop_.get(); }
166*288bf522SAndroid Build Coastguard Worker 
167*288bf522SAndroid Build Coastguard Worker   bool OpenEventFiles();
168*288bf522SAndroid Build Coastguard Worker   bool ReadCounters(std::vector<CountersInfo>* counters);
169*288bf522SAndroid Build Coastguard Worker   bool MmapEventFiles(size_t min_mmap_pages, size_t max_mmap_pages, size_t aux_buffer_size,
170*288bf522SAndroid Build Coastguard Worker                       size_t record_buffer_size, bool allow_truncating_samples, bool exclude_perf);
171*288bf522SAndroid Build Coastguard Worker   bool PrepareToReadMmapEventData(const std::function<bool(Record*)>& callback);
172*288bf522SAndroid Build Coastguard Worker   bool SyncKernelBuffer();
173*288bf522SAndroid Build Coastguard Worker   bool FinishReadMmapEventData();
174*288bf522SAndroid Build Coastguard Worker   void CloseEventFiles();
175*288bf522SAndroid Build Coastguard Worker 
GetRecordStat()176*288bf522SAndroid Build Coastguard Worker   const simpleperf::RecordStat& GetRecordStat() { return record_read_thread_->GetStat(); }
177*288bf522SAndroid Build Coastguard Worker 
178*288bf522SAndroid Build Coastguard Worker   // Stop profiling if all monitored processes/threads don't exist.
179*288bf522SAndroid Build Coastguard Worker   bool StopWhenNoMoreTargets(
180*288bf522SAndroid Build Coastguard Worker       double check_interval_in_sec = DEFAULT_PERIOD_TO_CHECK_MONITORED_TARGETS_IN_SEC);
181*288bf522SAndroid Build Coastguard Worker 
182*288bf522SAndroid Build Coastguard Worker   bool SetEnableEvents(bool enable);
183*288bf522SAndroid Build Coastguard Worker   bool EnableETMEvents();
184*288bf522SAndroid Build Coastguard Worker   bool DisableETMEvents();
185*288bf522SAndroid Build Coastguard Worker 
186*288bf522SAndroid Build Coastguard Worker  private:
187*288bf522SAndroid Build Coastguard Worker   struct EventSelection {
188*288bf522SAndroid Build Coastguard Worker     EventTypeAndModifier event_type_modifier;
189*288bf522SAndroid Build Coastguard Worker     perf_event_attr event_attr;
190*288bf522SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<EventFd>> event_fds;
191*288bf522SAndroid Build Coastguard Worker     // counters for event files closed for cpu hotplug events
192*288bf522SAndroid Build Coastguard Worker     std::vector<CounterInfo> hotplugged_counters;
193*288bf522SAndroid Build Coastguard Worker     std::vector<int> allowed_cpus;
194*288bf522SAndroid Build Coastguard Worker     std::string tracepoint_filter;
195*288bf522SAndroid Build Coastguard Worker   };
196*288bf522SAndroid Build Coastguard Worker 
197*288bf522SAndroid Build Coastguard Worker   struct EventSelectionGroup {
198*288bf522SAndroid Build Coastguard Worker     std::vector<EventSelection> selections;
199*288bf522SAndroid Build Coastguard Worker     bool set_sample_rate = false;
200*288bf522SAndroid Build Coastguard Worker     // Select on which cpus to monitor this event group:
201*288bf522SAndroid Build Coastguard Worker     // If cpus = {}, monitor on all cpus, with a perf event file for each cpu. This is the default
202*288bf522SAndroid Build Coastguard Worker     // option.
203*288bf522SAndroid Build Coastguard Worker     // If cpus = {-1}, monitor on all cpus, with a perf event file shared by all cpus.
204*288bf522SAndroid Build Coastguard Worker     // Otherwise, monitor on selected cpus, with a perf event file for each cpu.
205*288bf522SAndroid Build Coastguard Worker     std::vector<int> cpus;
206*288bf522SAndroid Build Coastguard Worker   };
207*288bf522SAndroid Build Coastguard Worker 
208*288bf522SAndroid Build Coastguard Worker   bool BuildAndCheckEventSelection(const std::string& event_name, bool first_event,
209*288bf522SAndroid Build Coastguard Worker                                    EventSelection* selection);
210*288bf522SAndroid Build Coastguard Worker   void UnionSampleType();
211*288bf522SAndroid Build Coastguard Worker   void SetSampleRateForGroup(EventSelectionGroup& group, const SampleRate& rate);
212*288bf522SAndroid Build Coastguard Worker   bool OpenEventFilesOnGroup(EventSelectionGroup& group, pid_t tid, int cpu,
213*288bf522SAndroid Build Coastguard Worker                              std::string* failed_event_type);
214*288bf522SAndroid Build Coastguard Worker   bool ApplyFilters();
215*288bf522SAndroid Build Coastguard Worker   bool ApplyAddrFilters();
216*288bf522SAndroid Build Coastguard Worker   bool ApplyTracepointFilters();
217*288bf522SAndroid Build Coastguard Worker   bool ReadMmapEventData(bool with_time_limit);
218*288bf522SAndroid Build Coastguard Worker 
219*288bf522SAndroid Build Coastguard Worker   bool CheckMonitoredTargets();
220*288bf522SAndroid Build Coastguard Worker   bool HasSampler();
221*288bf522SAndroid Build Coastguard Worker 
222*288bf522SAndroid Build Coastguard Worker   const bool for_stat_cmd_;
223*288bf522SAndroid Build Coastguard Worker 
224*288bf522SAndroid Build Coastguard Worker   std::vector<EventSelectionGroup> groups_;
225*288bf522SAndroid Build Coastguard Worker   std::set<pid_t> processes_;
226*288bf522SAndroid Build Coastguard Worker   std::set<pid_t> threads_;
227*288bf522SAndroid Build Coastguard Worker 
228*288bf522SAndroid Build Coastguard Worker   std::unique_ptr<IOEventLoop> loop_;
229*288bf522SAndroid Build Coastguard Worker   std::function<bool(Record*)> record_callback_;
230*288bf522SAndroid Build Coastguard Worker 
231*288bf522SAndroid Build Coastguard Worker   std::unique_ptr<simpleperf::RecordReadThread> record_read_thread_;
232*288bf522SAndroid Build Coastguard Worker 
233*288bf522SAndroid Build Coastguard Worker   bool has_aux_trace_ = false;
234*288bf522SAndroid Build Coastguard Worker   std::vector<AddrFilter> addr_filters_;
235*288bf522SAndroid Build Coastguard Worker   std::optional<SampleRate> sample_rate_;
236*288bf522SAndroid Build Coastguard Worker   std::optional<std::vector<int>> cpus_;
237*288bf522SAndroid Build Coastguard Worker 
238*288bf522SAndroid Build Coastguard Worker   std::set<int> etm_event_cpus_;
239*288bf522SAndroid Build Coastguard Worker   std::set<int>::const_iterator etm_event_cpus_it_;
240*288bf522SAndroid Build Coastguard Worker 
241*288bf522SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(EventSelectionSet);
242*288bf522SAndroid Build Coastguard Worker };
243*288bf522SAndroid Build Coastguard Worker 
244*288bf522SAndroid Build Coastguard Worker bool IsBranchSamplingSupported();
245*288bf522SAndroid Build Coastguard Worker bool IsDwarfCallChainSamplingSupported();
246*288bf522SAndroid Build Coastguard Worker bool IsDumpingRegsForTracepointEventsSupported();
247*288bf522SAndroid Build Coastguard Worker bool IsSettingClockIdSupported();
248*288bf522SAndroid Build Coastguard Worker bool IsMmap2Supported();
249*288bf522SAndroid Build Coastguard Worker bool IsHardwareEventSupported();
250*288bf522SAndroid Build Coastguard Worker bool IsSwitchRecordSupported();
251*288bf522SAndroid Build Coastguard Worker 
252*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
253*288bf522SAndroid Build Coastguard Worker 
254*288bf522SAndroid Build Coastguard Worker #endif  // SIMPLE_PERF_EVENT_SELECTION_SET_H_
255