• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 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--     https://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
17INCLUDE PERFETTO MODULE android.binder;
18
19INCLUDE PERFETTO MODULE intervals.overlap;
20
21INCLUDE PERFETTO MODULE intervals.intersect;
22
23INCLUDE PERFETTO MODULE slices.with_context;
24
25-- Client side of all binder txns, sorted by client_ts.
26-- Suitable for interval_intersect.
27CREATE PERFETTO VIEW _binder_client_view AS
28SELECT
29  binder_txn_id AS id,
30  client_upid AS upid,
31  client_ts AS ts,
32  client_dur AS dur
33FROM android_binder_txns
34WHERE
35  client_dur > 0
36ORDER BY
37  ts;
38
39-- Server side of all binder txns, sorted by server_ts.
40-- Suitable for interval_intersect.
41CREATE PERFETTO VIEW _binder_server_view AS
42SELECT
43  binder_txn_id AS id,
44  server_upid AS upid,
45  server_ts AS ts,
46  server_dur AS dur
47FROM android_binder_txns
48WHERE
49  server_dur > 0
50ORDER BY
51  ts;
52
53-- Thread state view suitable for interval intersect.
54CREATE PERFETTO VIEW _thread_state_view AS
55SELECT
56  id,
57  ts,
58  dur,
59  utid,
60  cpu,
61  state,
62  io_wait
63FROM thread_state
64WHERE
65  dur > 0
66ORDER BY
67  ts;
68
69-- Partitions and flattens slices underneath the server or client side of binder
70-- txns. The |name| column in the output is the lowest depth slice name in a
71-- given partition.
72CREATE PERFETTO MACRO _binder_flatten_descendants(
73    id ColumnName,
74    ts ColumnName,
75    dur ColumnName,
76    slice_name ColumnName
77)
78RETURNS TableOrSubQuery AS
79(
80  WITH
81    root_slices AS (
82      SELECT
83        $id AS id,
84        $ts AS ts,
85        $dur AS dur
86      FROM android_binder_txns
87    ),
88    child_slices AS (
89      SELECT
90        slice.id AS root_id,
91        dec.*
92      FROM slice, descendant_slice(slice.id) AS dec
93      WHERE
94        slice.name = $slice_name
95    ),
96    flat_slices AS (
97      SELECT
98        root_id,
99        id,
100        ts,
101        dur
102      FROM _intervals_flatten !(_intervals_merge_root_and_children !(root_slices,
103                                                                child_slices))
104    )
105  SELECT
106    row_number() OVER () AS id,
107    root_slice.binder_txn_id,
108    root_slice.binder_reply_id,
109    flat_slices.id AS flat_id,
110    flat_slices.ts,
111    flat_slices.dur,
112    thread_slice.name,
113    thread_slice.utid
114  FROM flat_slices
115  JOIN thread_slice
116    USING (id)
117  JOIN android_binder_txns AS root_slice
118    ON root_slice.$id = root_id
119  WHERE
120    flat_slices.dur > 0
121);
122
123-- Server side flattened descendant slices.
124CREATE PERFETTO TABLE _binder_server_flat_descendants AS
125SELECT
126  *
127FROM _binder_flatten_descendants!(binder_reply_id, server_ts,
128                                             server_dur, 'binder reply')
129ORDER BY
130  ts;
131
132-- Client side flattened descendant slices.
133CREATE PERFETTO TABLE _binder_client_flat_descendants AS
134SELECT
135  *
136FROM _binder_flatten_descendants!(binder_txn_id, client_ts, client_dur,
137                                           'binder transaction')
138ORDER BY
139  ts;
140
141-- Server side flattened descendants intersected with their thread_states.
142CREATE PERFETTO TABLE _binder_server_flat_descendants_with_thread_state AS
143SELECT
144  ii.ts,
145  ii.dur,
146  _server_flat.binder_txn_id,
147  _server_flat.binder_reply_id,
148  _server_flat.name,
149  _server_flat.flat_id,
150  _thread_state_view.state,
151  _thread_state_view.io_wait
152FROM _interval_intersect !((_binder_server_flat_descendants,
153                            _thread_state_view), (utid)) AS ii
154JOIN _binder_server_flat_descendants AS _server_flat
155  ON id_0 = _server_flat.id
156JOIN _thread_state_view
157  ON id_1 = _thread_state_view.id;
158
159-- Client side flattened descendants intersected with their thread_states.
160CREATE PERFETTO TABLE _binder_client_flat_descendants_with_thread_state AS
161SELECT
162  ii.ts,
163  ii.dur,
164  _client_flat.binder_txn_id,
165  _client_flat.binder_reply_id,
166  _client_flat.name,
167  _client_flat.flat_id,
168  _thread_state_view.state,
169  _thread_state_view.io_wait
170FROM _interval_intersect !((_binder_client_flat_descendants,
171                            _thread_state_view), (utid)) AS ii
172JOIN _binder_client_flat_descendants AS _client_flat
173  ON id_0 = _client_flat.id
174JOIN _thread_state_view
175  ON id_1 = _thread_state_view.id;
176
177-- Returns the 'reason' for a binder txn delay based on the descendant slice
178-- name and thread_state information. It follows the following priority:
179-- 1. direct_reclaim.
180-- 2. GC blocking stall.
181-- 3. Sleeping in monitor contention.
182-- 4. Sleeping in ART lock contention.
183-- 5. Sleeping in binder txn or reply.
184-- 6. Sleeping in Mutex contention.
185-- 7. IO.
186-- 8. State itself.
187CREATE PERFETTO FUNCTION _binder_reason(
188    name STRING,
189    state STRING,
190    io_wait LONG,
191    binder_txn_id LONG,
192    binder_reply_id LONG,
193    flat_id LONG
194)
195RETURNS STRING AS
196SELECT
197  CASE
198    WHEN $name = 'mm_vmscan_direct_reclaim'
199    THEN 'kernel_memory_reclaim'
200    WHEN $name GLOB 'GC: Wait For*'
201    THEN 'userspace_memory_reclaim'
202    WHEN $state = 'S'
203    AND (
204      $name GLOB 'monitor contention*'
205      OR $name GLOB 'Lock contention on a monitor lock*'
206    )
207    THEN 'monitor_contention'
208    WHEN $state = 'S' AND (
209      $name GLOB 'Lock contention*'
210    )
211    THEN 'art_lock_contention'
212    WHEN $state = 'S'
213    AND $binder_reply_id != $flat_id
214    AND $binder_txn_id != $flat_id
215    AND (
216      $name = 'binder transaction' OR $name = 'binder reply'
217    )
218    THEN 'binder'
219    WHEN $state = 'S' AND (
220      $name = 'Contending for pthread mutex'
221    )
222    THEN 'mutex_contention'
223    WHEN $state != 'S' AND $io_wait = 1
224    THEN 'io'
225    ELSE $state
226  END AS name;
227
228-- Server side binder breakdowns per transactions per txn.
229CREATE PERFETTO TABLE android_binder_server_breakdown (
230  -- Client side id of the binder txn.
231  binder_txn_id JOINID(slice.id),
232  -- Server side id of the binder txn.
233  binder_reply_id JOINID(slice.id),
234  -- Timestamp of an exclusive interval during the binder reply with a single
235  -- reason.
236  ts TIMESTAMP,
237  -- Duration of an exclusive interval during the binder reply with a single
238  -- reason.
239  dur DURATION,
240  -- Cause of delay during an exclusive interval of the binder reply.
241  reason STRING
242) AS
243SELECT
244  binder_txn_id,
245  binder_reply_id,
246  ts,
247  dur,
248  _binder_reason(name, state, io_wait, binder_txn_id, binder_reply_id, flat_id) AS reason
249FROM _binder_server_flat_descendants_with_thread_state;
250
251-- Client side binder breakdowns per transactions per txn.
252CREATE PERFETTO TABLE android_binder_client_breakdown (
253  -- Client side id of the binder txn.
254  binder_txn_id JOINID(slice.id),
255  -- Server side id of the binder txn.
256  binder_reply_id JOINID(slice.id),
257  -- Timestamp of an exclusive interval during the binder txn with a single
258  -- latency reason.
259  ts TIMESTAMP,
260  -- Duration of an exclusive interval during the binder txn with a single
261  -- latency reason.
262  dur DURATION,
263  -- Cause of delay during an exclusive interval of the binder txn.
264  reason STRING
265) AS
266SELECT
267  binder_txn_id,
268  binder_reply_id,
269  ts,
270  dur,
271  _binder_reason(name, state, io_wait, binder_txn_id, binder_reply_id, flat_id) AS reason
272FROM _binder_client_flat_descendants_with_thread_state;
273
274CREATE PERFETTO VIEW _binder_client_breakdown_view AS
275SELECT
276  binder_txn_id,
277  binder_reply_id,
278  ts,
279  dur,
280  reason AS client_reason
281FROM android_binder_client_breakdown;
282
283CREATE PERFETTO VIEW _binder_server_breakdown_view AS
284SELECT
285  binder_txn_id,
286  ts,
287  dur,
288  reason AS server_reason
289FROM android_binder_server_breakdown;
290
291CREATE VIRTUAL TABLE _binder_client_server_breakdown_sp USING SPAN_LEFT_JOIN (
292    _binder_client_breakdown_view PARTITIONED binder_txn_id,
293    _binder_server_breakdown_view PARTITIONED binder_txn_id);
294
295-- Combined client and server side binder breakdowns per transaction.
296CREATE PERFETTO TABLE android_binder_client_server_breakdown (
297  -- Client side id of the binder txn.
298  binder_txn_id JOINID(slice.id),
299  -- Server side id of the binder txn.
300  binder_reply_id JOINID(slice.id),
301  -- Timestamp of an exclusive interval during the binder txn with a single
302  -- latency reason.
303  ts TIMESTAMP,
304  -- Duration of an exclusive interval during the binder txn with a single
305  -- latency reason.
306  dur DURATION,
307  -- The server side component of this interval's binder latency reason, if any.
308  server_reason STRING,
309  -- The client side component of this interval's binder latency reason.
310  client_reason STRING,
311  -- Combined reason indicating whether latency came from client or server side.
312  reason STRING,
313  -- Whether the latency is due to the client or server.
314  reason_type STRING
315) AS
316SELECT
317  *,
318  iif(server_reason IS NOT NULL, server_reason, client_reason) AS reason,
319  iif(server_reason IS NOT NULL, 'server', 'client') AS reason_type
320FROM _binder_client_server_breakdown_sp;
321