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