• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1-- Copyright 2022 The Android Open Source Project
2--
3-- Licensed under the Apache License, Version 2.0 (the "License");
4-- you may not use this file except in compliance with the License.
5-- You may obtain a copy of the License at
6--
7--     https://www.apache.org/licenses/LICENSE-2.0
8--
9-- Unless required by applicable law or agreed to in writing, software
10-- distributed under the License is distributed on an "AS IS" BASIS,
11-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-- See the License for the specific language governing permissions and
13-- limitations under the License.
14
15-- Find causes for CPUs powering up.
16--
17-- The scripts below analyse traces with the following tracing options
18-- enabled:
19--
20--  - Linux kernel:
21---    "power/*", "sched/*", "task/*",
22--  - Chromium:
23--      "toplevel", "toplevel.flow".
24
25-- Noteworthy tables:
26--
27--   chrome_cpu_power_first_toplevel_slice_after_powerup :: The top-level
28--      slices that ran after a CPU power-up.
29
30-- The CPU power transitions in the trace.
31--
32-- @column ts            The timestamp at the start of the slice.
33-- @column dur           The duration of the slice.
34-- @column cpu           The CPU on which the transition occurred
35-- @column power_state   The power state that the CPU was in at time 'ts' for
36--                       duration 'dur'.
37-- @column previous_power_state The power state that the CPU was previously in.
38-- @column powerup_id    A unique ID for the CPU power-up.
39--
40-- Power states are encoded as non-negative integers, with zero representing
41-- full-power operation and positive values representing increasingly deep
42-- sleep states.
43--
44-- On ARM systems, power state 1 represents the WFI (Wait For Interrupt) sleep
45-- state that the CPU enters while idle.
46CREATE VIEW chrome_cpu_power_slice AS
47  WITH cpu_power_states AS (
48    SELECT
49      c.id AS id,
50      cct.cpu AS cpu,
51      c.ts,
52      -- Encode the 'value' field as a power state.
53      CAST((CASE c.value WHEN 4294967295 THEN 0 ELSE c.value + 1 END)
54        AS INT) AS power_state
55    FROM counter AS c
56    JOIN cpu_counter_track AS cct
57      ON c.track_id = cct.id
58    WHERE cct.name = 'cpuidle'
59  )
60  SELECT *
61  FROM (
62    SELECT
63      ts,
64      LEAD(ts) OVER (PARTITION BY cpu ORDER BY ts ASC) - ts
65        AS dur,
66      cpu,
67      power_state,
68      LAG(power_state) OVER (PARTITION BY cpu ORDER BY ts ASC)
69        AS previous_power_state,
70      id AS powerup_id
71    FROM cpu_power_states
72  )
73  WHERE dur IS NOT NULL
74    AND previous_power_state IS NOT NULL
75    AND power_state = 0                      -- Track full-power states.
76    AND power_state != previous_power_state  -- Skip missing spans.
77    ORDER BY ts ASC;
78
79-- We do not want scheduler slices with utid = 0 (the 'swapper' kernel thread).
80CREATE VIEW internal_cpu_power_valid_sched_slice AS
81  SELECT *
82  FROM sched_slice
83  WHERE utid != 0;
84
85-- Join scheduler slices with the spans with CPU power slices.
86--
87-- There multiple scheduler slices could fall into one CPU power slice.
88--
89---  CPU Power:
90--   |----------------------------|....................|---------|
91--   A       <cpu active>         B     <cpu idling>   C         D
92
93--   Scheduler slices on that CPU:
94--     |-----T1-----| |....T2....|                      |---T3--|
95--     E            F G          H                      I       J
96--
97-- Here threads T1 and T2 executed in CPU power slice [A,B].  The
98-- time between F and G represents time between threads in the kernel.
99CREATE VIRTUAL TABLE internal_cpu_power_and_sched_slice
100USING
101  SPAN_JOIN(chrome_cpu_power_slice PARTITIONED cpu,
102            internal_cpu_power_valid_sched_slice PARTITIONED cpu);
103
104-- The Linux scheduler slices that executed immediately after a
105-- CPU power up.
106--
107-- @column ts          The timestamp at the start of the slice.
108-- @column dur         The duration of the slice.
109-- @column cpu         The cpu on which the slice executed.
110-- @column sched_id    Id for the sched_slice table.
111-- @column utid        Unique id for the thread that ran within the slice.
112-- @column previous_power_state   The CPU's power state before this slice.
113CREATE TABLE chrome_cpu_power_first_sched_slice_after_powerup AS
114  SELECT
115    ts,
116    dur,
117    cpu,
118    id AS sched_id,
119    utid,
120    previous_power_state,
121    powerup_id
122  FROM internal_cpu_power_and_sched_slice
123  WHERE power_state = 0     -- Power-ups only.
124  GROUP BY cpu, powerup_id
125  HAVING ts = MIN(ts)       -- There will only be one MIN sched slice
126                            -- per CPU power up.
127  ORDER BY ts ASC;
128
129-- A view joining thread tracks and top-level slices.
130--
131-- This view is intended to be intersected by time with the scheduler
132-- slices scheduled after a CPU power up.
133--
134--   utid      Thread unique id.
135--   slice_id  The slice_id for the top-level slice.
136--   ts        Starting timestamp for the slice.
137--   dur       The duration for the slice.
138CREATE VIEW internal_cpu_power_thread_and_toplevel_slice AS
139  SELECT
140    t.utid AS utid,
141    s.id AS slice_id,
142    s.ts,
143    s.dur
144  FROM slice AS s
145  JOIN thread_track AS t
146    ON s.track_id = t.id
147  WHERE s.depth = 0   -- Top-level slices only.
148  ORDER BY ts ASC;
149
150-- A table holding the slices that executed within the scheduler
151-- slice that ran on a CPU immediately after power-up.
152--
153-- @column  ts        Timestamp of the resulting slice
154-- @column dur        Duration of the slice.
155-- @column cpu        The CPU the sched slice ran on.
156-- @column utid       Unique thread id for the slice.
157-- @column sched_id   'id' field from the sched_slice table.
158-- @column type       From the sched_slice table, always 'sched_slice'.
159-- @column end_state  The ending state for the sched_slice
160-- @column priority   The kernel thread priority
161-- @column slice_id   Id of the top-level slice for this (sched) slice.
162CREATE VIRTUAL TABLE chrome_cpu_power_post_powerup_slice
163USING
164  SPAN_JOIN(chrome_cpu_power_first_sched_slice_after_powerup PARTITIONED utid,
165            internal_cpu_power_thread_and_toplevel_slice PARTITIONED utid);
166
167-- The first top-level slice that ran after a CPU power-up.
168--
169-- @column slice_id              ID of the slice in the slice table.
170-- @column previous_power_state  The power state of the CPU prior to power-up.
171CREATE VIEW chrome_cpu_power_first_toplevel_slice_after_powerup AS
172  SELECT slice_id, previous_power_state
173  FROM chrome_cpu_power_post_powerup_slice
174  GROUP BY cpu, powerup_id
175  HAVING ts = MIN(ts)
176  ORDER BY ts ASC;
177