• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACED_PROBES_FTRACE_FTRACE_CONFIG_MUXER_H_
18 #define SRC_TRACED_PROBES_FTRACE_FTRACE_CONFIG_MUXER_H_
19 
20 #include <map>
21 #include <set>
22 
23 #include "src/traced/probes/ftrace/compact_sched.h"
24 #include "src/traced/probes/ftrace/ftrace_config_utils.h"
25 #include "src/traced/probes/ftrace/ftrace_controller.h"
26 #include "src/traced/probes/ftrace/ftrace_procfs.h"
27 #include "src/traced/probes/ftrace/proto_translation_table.h"
28 
29 namespace perfetto {
30 
31 namespace protos {
32 namespace pbzero {
33 enum FtraceClock : int32_t;
34 }  // namespace pbzero
35 }  // namespace protos
36 
37 struct FtraceSetupErrors;
38 
39 // State held by the muxer per data source, used to parse ftrace according to
40 // that data source's config.
41 struct FtraceDataSourceConfig {
FtraceDataSourceConfigFtraceDataSourceConfig42   FtraceDataSourceConfig(EventFilter _event_filter,
43                          CompactSchedConfig _compact_sched,
44                          std::vector<std::string> _atrace_apps,
45                          std::vector<std::string> _atrace_categories,
46                          bool _symbolize_ksyms)
47       : event_filter(std::move(_event_filter)),
48         compact_sched(_compact_sched),
49         atrace_apps(std::move(_atrace_apps)),
50         atrace_categories(std::move(_atrace_categories)),
51         symbolize_ksyms(_symbolize_ksyms) {}
52 
53   // The event filter allows to quickly check if a certain ftrace event with id
54   // x is enabled for this data source.
55   EventFilter event_filter;
56 
57   // Configuration of the optional compact encoding of scheduling events.
58   const CompactSchedConfig compact_sched;
59 
60   // Used only in Android for ATRACE_EVENT/os.Trace() userspace annotations.
61   std::vector<std::string> atrace_apps;
62   std::vector<std::string> atrace_categories;
63 
64   // When enabled will turn on the kallsyms symbolizer in CpuReader.
65   const bool symbolize_ksyms;
66 };
67 
68 // Ftrace is a bunch of globally modifiable persistent state.
69 // Given a number of FtraceConfig's we need to find the best union of all
70 // the settings to make everyone happy while also watching out for anybody
71 // messing with the ftrace settings at the same time as us.
72 //
73 // Specifically FtraceConfigMuxer takes in a *requested* FtraceConfig
74 // (|SetupConfig|), makes a best effort attempt to modify the ftrace
75 // debugfs files to honor those settings without interrupting other perfetto
76 // traces already in progress or other users of ftrace, then returns an
77 // FtraceConfigId representing that config or zero on failure.
78 //
79 // When you are finished with a config you can signal that with |RemoveConfig|.
80 class FtraceConfigMuxer {
81  public:
82   // The FtraceConfigMuxer and ProtoTranslationTable
83   // should outlive this instance.
84   FtraceConfigMuxer(
85       FtraceProcfs* ftrace,
86       ProtoTranslationTable* table,
87       std::map<std::string, std::vector<GroupAndName>> vendor_events);
88   virtual ~FtraceConfigMuxer();
89 
90   // Ask FtraceConfigMuxer to adjust ftrace procfs settings to
91   // match the requested config. Returns an id to manage this
92   // config or zero on failure.
93   // This is best effort. FtraceConfigMuxer may not be able to adjust the
94   // buffer size right now. Events may be missing or there may be extra events
95   // (if you enable an atrace category we try to give you the matching events).
96   // If someone else is tracing we won't touch atrace (since it resets the
97   // buffer).
98   FtraceConfigId SetupConfig(const FtraceConfig& request,
99                              FtraceSetupErrors* = nullptr);
100 
101   // Activate ftrace for the given config (if not already active).
102   bool ActivateConfig(FtraceConfigId);
103 
104   // Undo changes for the given config. Returns false iff the id is 0
105   // or already removed.
106   bool RemoveConfig(FtraceConfigId);
107 
108   const FtraceDataSourceConfig* GetDataSourceConfig(FtraceConfigId id);
109 
110   // Returns the current per-cpu buffer size, as configured by this muxer
111   // (without consulting debugfs). Constant for a given tracing session.
112   // Note that if there are multiple concurrent tracing sessions, the first
113   // session's buffer size is used for all of them.
114   size_t GetPerCpuBufferSizePages();
115 
116   // public for testing
SetupClockForTesting(const FtraceConfig & request)117   void SetupClockForTesting(const FtraceConfig& request) {
118     SetupClock(request);
119   }
120 
ftrace_clock()121   protos::pbzero::FtraceClock ftrace_clock() const {
122     return current_state_.ftrace_clock;
123   }
124 
GetFtraceEventsForTesting(const FtraceConfig & request,const ProtoTranslationTable * table)125   std::set<GroupAndName> GetFtraceEventsForTesting(
126       const FtraceConfig& request,
127       const ProtoTranslationTable* table) {
128     return GetFtraceEvents(request, table);
129   }
130 
GetCentralEventFilterForTesting()131   const EventFilter* GetCentralEventFilterForTesting() const {
132     return &current_state_.ftrace_events;
133   }
134 
135  private:
136   static bool StartAtrace(const std::vector<std::string>& apps,
137                           const std::vector<std::string>& categories,
138                           std::string* atrace_errors);
139 
140   struct FtraceState {
141     EventFilter ftrace_events;
142     // Used only in Android for ATRACE_EVENT/os.Trace() userspace
143     std::vector<std::string> atrace_apps;
144     std::vector<std::string> atrace_categories;
145     size_t cpu_buffer_size_pages = 0;
146     bool atrace_on = false;
147     protos::pbzero::FtraceClock ftrace_clock{};
148   };
149 
150   FtraceConfigMuxer(const FtraceConfigMuxer&) = delete;
151   FtraceConfigMuxer& operator=(const FtraceConfigMuxer&) = delete;
152 
153   void SetupClock(const FtraceConfig& request);
154   void SetupBufferSize(const FtraceConfig& request);
155   void UpdateAtrace(const FtraceConfig& request, std::string* atrace_errors);
156   void DisableAtrace();
157 
158   // This processes the config to get the exact events.
159   // group/* -> Will read the fs and add all events in group.
160   // event -> Will look up the event to find the group.
161   // atrace category -> Will add events in that category.
162   std::set<GroupAndName> GetFtraceEvents(const FtraceConfig& request,
163                                          const ProtoTranslationTable*);
164 
165   FtraceConfigId GetNextId();
166 
167   FtraceConfigId last_id_ = 1;
168   FtraceProcfs* ftrace_;
169   ProtoTranslationTable* table_;
170 
171   FtraceState current_state_;
172 
173   // Set of all requested tracing configurations, with the associated derived
174   // data used during parsing. Note that not all of these configurations might
175   // be active. When a config is present but not active, we do setup buffer
176   // sizes and events, but don't enable ftrace (i.e. tracing_on).
177   std::map<FtraceConfigId, FtraceDataSourceConfig> ds_configs_;
178 
179   std::map<std::string, std::vector<GroupAndName>> vendor_events_;
180 
181   // Subset of |ds_configs_| that are currently active. At any time ftrace is
182   // enabled iff |active_configs_| is not empty.
183   std::set<FtraceConfigId> active_configs_;
184 };
185 
186 size_t ComputeCpuBufferSizeInPages(size_t requested_buffer_size_kb);
187 
188 }  // namespace perfetto
189 
190 #endif  // SRC_TRACED_PROBES_FTRACE_FTRACE_CONFIG_MUXER_H_
191