xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/ftrace/binder_tracker.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 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_TRACE_PROCESSOR_IMPORTERS_FTRACE_BINDER_TRACKER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_BINDER_TRACKER_H_
19 
20 #include <stdint.h>
21 #include <optional>
22 #include <stack>
23 
24 #include "perfetto/base/flat_set.h"
25 #include "perfetto/ext/base/flat_hash_map.h"
26 #include "src/trace_processor/importers/common/args_tracker.h"
27 #include "src/trace_processor/storage/trace_storage.h"
28 #include "src/trace_processor/types/destructible.h"
29 #include "src/trace_processor/types/trace_processor_context.h"
30 
31 namespace perfetto {
32 namespace trace_processor {
33 
34 class TraceProcessorContext;
35 
36 class BinderTracker : public Destructible {
37  public:
38   // Commands sent from userspace to the kernel binder driver.
39   enum : uint32_t {
40     kBC_TRANSACTION = 0x40406300,
41     kBC_REPLY = 0x40406301,
42     kBC_TRANSACTION_SG = 0x40486311,
43     kBC_REPLY_SG = 0x40486312,
44   };
45 
46   // Return commands sent from the kernel binder driver to userspace.
47   enum : uint32_t {
48     kBR_TRANSACTION_SEC_CTX = 0x80487202,
49     kBR_TRANSACTION = 0x80407202,
50     kBR_REPLY = 0x80407203,
51     kBR_DEAD_REPLY = 0x7205,
52     kBR_TRANSACTION_COMPLETE = 0x7206,
53     kBR_FAILED_REPLY = 0x7211,
54     kBR_FROZEN_REPLY = 0x7212,
55     kBR_TRANSACTION_PENDING_FROZEN = 0x7214,
56     kBR_ONEWAY_SPAM_SUSPECT = 0x7213,
57   };
58 
59   using SetArgsCallback = std::function<void(ArgsTracker::BoundInserter*)>;
60   // Declared public for testing only.
61   explicit BinderTracker(TraceProcessorContext*);
62   BinderTracker(const BinderTracker&) = delete;
63   BinderTracker& operator=(const BinderTracker&) = delete;
64   ~BinderTracker() override;
GetOrCreate(TraceProcessorContext * context)65   static BinderTracker* GetOrCreate(TraceProcessorContext* context) {
66     if (!context->binder_tracker) {
67       context->binder_tracker.reset(new BinderTracker(context));
68     }
69     return static_cast<BinderTracker*>(context->binder_tracker.get());
70   }
71 
72   void Transaction(int64_t timestamp,
73                    uint32_t tid,
74                    int32_t transaction_id,
75                    int32_t dest_node,
76                    uint32_t dest_tgid,
77                    uint32_t dest_tid,
78                    bool is_reply,
79                    uint32_t flags,
80                    StringId code);
81   void Locked(int64_t timestamp, uint32_t pid);
82   void Lock(int64_t timestamp, uint32_t dest_pid);
83   void Unlock(int64_t timestamp, uint32_t pid);
84   void TransactionReceived(int64_t timestamp,
85                            uint32_t tid,
86                            int32_t transaction_id);
87   void CommandToKernel(int64_t timestamp, uint32_t tid, uint32_t cmd);
88   void ReturnFromKernel(int64_t timestamp, uint32_t tid, uint32_t cmd);
89   void TransactionAllocBuf(int64_t timestamp,
90                            uint32_t pid,
91                            uint64_t data_size,
92                            uint64_t offsets_size);
93 
94   // For testing
utid_stacks_empty()95   bool utid_stacks_empty() const { return utid_stacks_.size() == 0; }
96 
97  private:
98   TraceProcessorContext* const context_;
99 
100   struct OutstandingTransaction {
101     bool is_reply = false;
102     bool is_oneway = false;
103     SetArgsCallback args_inserter;
104     std::optional<TrackId> send_track_id;
105     std::optional<SliceId> send_slice_id;
106   };
107   // TODO(rsavitski): switch back to FlatHashMap once the latter's perf is fixed
108   // for insert+erase heavy workfloads.
109   std::unordered_map<int32_t, OutstandingTransaction> outstanding_transactions_;
110 
111   struct TxnFrame {
112     // The state of this thread at this stack level.
113     enum State : uint32_t;
114     State state;
115     struct TxnInfo {
116       bool is_oneway;
117       bool is_reply;
118     };
119     std::optional<TxnInfo> txn_info;
120   };
121   // Each thread can have a stack of multiple transactions.
122   base::FlatHashMap<UniqueTid, std::stack<TxnFrame>> utid_stacks_;
123 
124   // Returns the current state of this thread or nullptr, if the thread doesn't
125   // have a binder state.
126   TxnFrame* GetTidTopFrame(uint32_t tid);
127   // Creates a new frame in the stack for this thread. Note: this might
128   // invalidate previously returned TxnFrame*.
129   TxnFrame* PushTidFrame(uint32_t tid);
130   // Removes the current frame for this thread. It's an error to call this if
131   // the thread didn't have a frame. Note: this might invalidate previously
132   // returned TxnFrame*.
133   void PopTidFrame(uint32_t tid);
134 
135   base::FlatHashMap<uint32_t, int64_t> attempt_lock_;
136   base::FlatHashMap<uint32_t, int64_t> lock_acquired_;
137 
138   const StringId binder_category_id_;
139   const StringId lock_waiting_id_;
140   const StringId lock_held_id_;
141   const StringId transaction_slice_id_;
142   const StringId transaction_async_id_;
143   const StringId reply_id_;
144   const StringId async_rcv_id_;
145   const StringId transaction_id_;
146   const StringId dest_node_;
147   const StringId dest_process_;
148   const StringId dest_thread_;
149   const StringId dest_name_;
150   const StringId is_reply_;
151   const StringId flags_;
152   const StringId code_;
153   const StringId calling_tid_;
154   const StringId data_size_;
155   const StringId offsets_size_;
156 };
157 
158 }  // namespace trace_processor
159 }  // namespace perfetto
160 
161 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_BINDER_TRACKER_H_
162