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-- Raw ftrace events 17CREATE PERFETTO TABLE _raw_dmabuf_events AS 18SELECT 19 ( 20 SELECT 21 int_value 22 FROM args 23 WHERE 24 arg_set_id = c.arg_set_id AND key = 'inode' 25 ) AS inode, 26 tt.utid, 27 c.ts, 28 cast_int!(c.value) AS buf_size 29FROM thread_counter_track AS tt 30JOIN counter AS c 31 ON c.track_id = tt.id 32WHERE 33 tt.name = 'mem.dma_heap_change'; 34 35-- gralloc binder reply slices 36CREATE PERFETTO TABLE _gralloc_binders AS 37WITH 38 gralloc_threads AS ( 39 SELECT 40 utid 41 FROM process 42 JOIN thread 43 USING (upid) 44 WHERE 45 process.name GLOB '/vendor/bin/hw/android.hardware.graphics.allocator*' 46 ) 47SELECT 48 flow.slice_out AS client_slice_id, 49 gralloc_slice.ts, 50 gralloc_slice.dur, 51 thread_track.utid 52FROM slice AS gralloc_slice 53JOIN thread_track 54 ON gralloc_slice.track_id = thread_track.id 55JOIN gralloc_threads 56 USING (utid) 57JOIN flow 58 ON gralloc_slice.id = flow.slice_in 59WHERE 60 gralloc_slice.name = 'binder reply'; 61 62-- Match gralloc thread allocations to inbound binders 63CREATE PERFETTO TABLE _attributed_dmabufs AS 64SELECT 65 r.inode, 66 r.ts, 67 r.buf_size, 68 coalesce(client_thread.utid, r.utid) AS attr_utid 69FROM _raw_dmabuf_events AS r 70LEFT JOIN _gralloc_binders AS gb 71 ON r.utid = gb.utid AND r.ts BETWEEN gb.ts AND gb.ts + gb.dur 72LEFT JOIN thread_track AS client_thread 73 ON gb.client_slice_id = client_thread.id 74ORDER BY 75 r.inode, 76 r.ts; 77 78CREATE PERFETTO FUNCTION _alloc_source( 79 is_alloc BOOL, 80 inode LONG, 81 ts TIMESTAMP 82) 83RETURNS LONG AS 84SELECT 85 attr_utid 86FROM _attributed_dmabufs 87WHERE 88 inode = $inode 89 AND ( 90 ( 91 $is_alloc AND ts = $ts 92 ) OR ( 93 NOT $is_alloc AND ts < $ts 94 ) 95 ) 96ORDER BY 97 ts DESC 98LIMIT 1; 99 100-- Track dmabuf allocations, re-attributing gralloc allocations to their source 101-- (if binder transactions to gralloc are recorded). 102CREATE PERFETTO TABLE android_dmabuf_allocs ( 103 -- timestamp of the allocation 104 ts TIMESTAMP, 105 -- allocation size (will be negative for release) 106 buf_size LONG, 107 -- dmabuf inode 108 inode LONG, 109 -- utid of thread responsible for the allocation 110 -- if a dmabuf is allocated by gralloc we follow the binder transaction 111 -- to the requesting thread (requires binder tracing) 112 utid JOINID(thread.id), 113 -- tid of thread responsible for the allocation 114 tid LONG, 115 -- thread name 116 thread_name STRING, 117 -- upid of process responsible for the allocation (matches utid) 118 upid JOINID(process.id), 119 -- pid of process responsible for the allocation 120 pid LONG, 121 -- process name 122 process_name STRING 123) AS 124WITH 125 _thread_allocs AS ( 126 SELECT 127 inode, 128 ts, 129 buf_size, 130 _alloc_source(buf_size > 0, inode, ts) AS utid 131 FROM _attributed_dmabufs 132 ) 133SELECT 134 ts, 135 buf_size, 136 inode, 137 utid, 138 tid, 139 thread.name AS thread_name, 140 upid, 141 pid, 142 process.name AS process_name 143FROM _thread_allocs AS allocs 144JOIN thread 145 USING (utid) 146LEFT JOIN process 147 USING (upid) 148ORDER BY 149 ts; 150