1*6dbdd20aSAndroid Build Coastguard Worker# CPU Scheduling events 2*6dbdd20aSAndroid Build Coastguard Worker 3*6dbdd20aSAndroid Build Coastguard WorkerOn Android and Linux Perfetto can gather scheduler traces via the Linux Kernel 4*6dbdd20aSAndroid Build Coastguard Worker[ftrace](https://www.kernel.org/doc/Documentation/trace/ftrace.txt) 5*6dbdd20aSAndroid Build Coastguard Workerinfrastructure. 6*6dbdd20aSAndroid Build Coastguard Worker 7*6dbdd20aSAndroid Build Coastguard WorkerThis allows to get fine grained scheduling events such as: 8*6dbdd20aSAndroid Build Coastguard Worker 9*6dbdd20aSAndroid Build Coastguard Worker* Which threads were scheduled on which CPU core at any point in time, with 10*6dbdd20aSAndroid Build Coastguard Worker nanosecond accuracy. 11*6dbdd20aSAndroid Build Coastguard Worker* The reason why a running thread got descheduled (e.g. pre-emption, blocked on 12*6dbdd20aSAndroid Build Coastguard Worker a mutex, blocking syscall or any other wait queue). 13*6dbdd20aSAndroid Build Coastguard Worker* The point in time when a thread became eligible to be executed, even if it was 14*6dbdd20aSAndroid Build Coastguard Worker not put immediately on any CPU run queue, together with the source thread that 15*6dbdd20aSAndroid Build Coastguard Worker made it executable. 16*6dbdd20aSAndroid Build Coastguard Worker 17*6dbdd20aSAndroid Build Coastguard Worker## UI 18*6dbdd20aSAndroid Build Coastguard Worker 19*6dbdd20aSAndroid Build Coastguard WorkerThe UI represents individual scheduling events as slices: 20*6dbdd20aSAndroid Build Coastguard Worker 21*6dbdd20aSAndroid Build Coastguard Worker 22*6dbdd20aSAndroid Build Coastguard Worker 23*6dbdd20aSAndroid Build Coastguard WorkerClicking on a CPU slice shows the relevant information in the details panel: 24*6dbdd20aSAndroid Build Coastguard Worker 25*6dbdd20aSAndroid Build Coastguard Worker 26*6dbdd20aSAndroid Build Coastguard Worker 27*6dbdd20aSAndroid Build Coastguard WorkerScrolling down, when expanding individual processes, the scheduling events also 28*6dbdd20aSAndroid Build Coastguard Workercreate one track for each thread, which allows to follow the evolution of the 29*6dbdd20aSAndroid Build Coastguard Workerstate of individual threads: 30*6dbdd20aSAndroid Build Coastguard Worker 31*6dbdd20aSAndroid Build Coastguard Worker 32*6dbdd20aSAndroid Build Coastguard Worker 33*6dbdd20aSAndroid Build Coastguard Worker## SQL 34*6dbdd20aSAndroid Build Coastguard Worker 35*6dbdd20aSAndroid Build Coastguard WorkerAt the SQL level, the scheduling data is exposed in the 36*6dbdd20aSAndroid Build Coastguard Worker[`sched_slice`](/docs/analysis/sql-tables.autogen#sched_slice) table. 37*6dbdd20aSAndroid Build Coastguard Worker 38*6dbdd20aSAndroid Build Coastguard Worker```sql 39*6dbdd20aSAndroid Build Coastguard Workerselect ts, dur, cpu, end_state, priority, process.name, thread.name 40*6dbdd20aSAndroid Build Coastguard Workerfrom sched_slice left join thread using(utid) left join process using(upid) 41*6dbdd20aSAndroid Build Coastguard Worker``` 42*6dbdd20aSAndroid Build Coastguard Worker 43*6dbdd20aSAndroid Build Coastguard Workerts | dur | cpu | end_state | priority | process.name, | thread.name 44*6dbdd20aSAndroid Build Coastguard Worker---|-----|-----|-----------|----------|---------------|------------ 45*6dbdd20aSAndroid Build Coastguard Worker261187012170995 | 247188 | 2 | S | 130 | /system/bin/logd | logd.klogd 46*6dbdd20aSAndroid Build Coastguard Worker261187012418183 | 12812 | 2 | D | 120 | /system/bin/traced_probes | traced_probes0 47*6dbdd20aSAndroid Build Coastguard Worker261187012421099 | 220000 | 4 | D | 120 | kthreadd | kworker/u16:2 48*6dbdd20aSAndroid Build Coastguard Worker261187012430995 | 72396 | 2 | D | 120 | /system/bin/traced_probes | traced_probes1 49*6dbdd20aSAndroid Build Coastguard Worker261187012454537 | 13958 | 0 | D | 120 | /system/bin/traced_probes | traced_probes0 50*6dbdd20aSAndroid Build Coastguard Worker261187012460318 | 46354 | 3 | S | 120 | /system/bin/traced_probes | traced_probes2 51*6dbdd20aSAndroid Build Coastguard Worker261187012468495 | 10625 | 0 | R | 120 | [NULL] | swapper/0 52*6dbdd20aSAndroid Build Coastguard Worker261187012479120 | 6459 | 0 | D | 120 | /system/bin/traced_probes | traced_probes0 53*6dbdd20aSAndroid Build Coastguard Worker261187012485579 | 7760 | 0 | R | 120 | [NULL] | swapper/0 54*6dbdd20aSAndroid Build Coastguard Worker261187012493339 | 34896 | 0 | D | 120 | /system/bin/traced_probes | traced_probes0 55*6dbdd20aSAndroid Build Coastguard Worker 56*6dbdd20aSAndroid Build Coastguard Worker## TraceConfig 57*6dbdd20aSAndroid Build Coastguard Worker 58*6dbdd20aSAndroid Build Coastguard WorkerTo collect this data, include the following data sources: 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Worker```protobuf 61*6dbdd20aSAndroid Build Coastguard Worker# Scheduling data from the kernel. 62*6dbdd20aSAndroid Build Coastguard Workerdata_sources: { 63*6dbdd20aSAndroid Build Coastguard Worker config { 64*6dbdd20aSAndroid Build Coastguard Worker name: "linux.ftrace" 65*6dbdd20aSAndroid Build Coastguard Worker ftrace_config { 66*6dbdd20aSAndroid Build Coastguard Worker compact_sched: { 67*6dbdd20aSAndroid Build Coastguard Worker enabled: true 68*6dbdd20aSAndroid Build Coastguard Worker } 69*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "sched/sched_switch" 70*6dbdd20aSAndroid Build Coastguard Worker # optional: precise thread lifetime tracking: 71*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "sched/sched_process_exit" 72*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "sched/sched_process_free" 73*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "task/task_newtask" 74*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "task/task_rename" 75*6dbdd20aSAndroid Build Coastguard Worker } 76*6dbdd20aSAndroid Build Coastguard Worker } 77*6dbdd20aSAndroid Build Coastguard Worker} 78*6dbdd20aSAndroid Build Coastguard Worker 79*6dbdd20aSAndroid Build Coastguard Worker# Adds full process names and thread<>process relationships: 80*6dbdd20aSAndroid Build Coastguard Workerdata_sources: { 81*6dbdd20aSAndroid Build Coastguard Worker config { 82*6dbdd20aSAndroid Build Coastguard Worker name: "linux.process_stats" 83*6dbdd20aSAndroid Build Coastguard Worker } 84*6dbdd20aSAndroid Build Coastguard Worker} 85*6dbdd20aSAndroid Build Coastguard Worker``` 86*6dbdd20aSAndroid Build Coastguard Worker 87*6dbdd20aSAndroid Build Coastguard Worker## Scheduling wakeups and latency analysis 88*6dbdd20aSAndroid Build Coastguard Worker 89*6dbdd20aSAndroid Build Coastguard WorkerBy further enabling the following in the TraceConfig, the ftrace data source 90*6dbdd20aSAndroid Build Coastguard Workerwill record also scheduling wake up events: 91*6dbdd20aSAndroid Build Coastguard Worker 92*6dbdd20aSAndroid Build Coastguard Worker```protobuf 93*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "sched/sched_wakeup_new" 94*6dbdd20aSAndroid Build Coastguard Worker ftrace_events: "sched/sched_waking" 95*6dbdd20aSAndroid Build Coastguard Worker``` 96*6dbdd20aSAndroid Build Coastguard Worker 97*6dbdd20aSAndroid Build Coastguard WorkerWhile `sched_switch` events are emitted only when a thread is in the 98*6dbdd20aSAndroid Build Coastguard Worker`R(unnable)` state AND is running on a CPU run queue, `sched_waking` events are 99*6dbdd20aSAndroid Build Coastguard Workeremitted when any event causes a thread state to change. 100*6dbdd20aSAndroid Build Coastguard Worker 101*6dbdd20aSAndroid Build Coastguard WorkerConsider the following example: 102*6dbdd20aSAndroid Build Coastguard Worker 103*6dbdd20aSAndroid Build Coastguard Worker``` 104*6dbdd20aSAndroid Build Coastguard WorkerThread A 105*6dbdd20aSAndroid Build Coastguard Workercondition_variable.wait() 106*6dbdd20aSAndroid Build Coastguard Worker Thread B 107*6dbdd20aSAndroid Build Coastguard Worker condition_variable.notify() 108*6dbdd20aSAndroid Build Coastguard Worker``` 109*6dbdd20aSAndroid Build Coastguard Worker 110*6dbdd20aSAndroid Build Coastguard WorkerWhen Thread A suspends on the wait() it will enter the state `S(sleeping)` and 111*6dbdd20aSAndroid Build Coastguard Workerget removed from the CPU run queue. When Thread B notifies the variable, the 112*6dbdd20aSAndroid Build Coastguard Workerkernel will transition Thread A into the `R(unnable)` state. Thread A at that 113*6dbdd20aSAndroid Build Coastguard Workerpoint is eligible to be put back on a run queue. However this might not happen 114*6dbdd20aSAndroid Build Coastguard Workerfor some time because, for instance: 115*6dbdd20aSAndroid Build Coastguard Worker 116*6dbdd20aSAndroid Build Coastguard Worker* All CPUs might be busy running some other thread, and Thread A needs to wait 117*6dbdd20aSAndroid Build Coastguard Worker to get a run queue slot assigned (or the other threads have higher priority). 118*6dbdd20aSAndroid Build Coastguard Worker* Some other CPUs other than the current one, but the scheduler load balancer 119*6dbdd20aSAndroid Build Coastguard Worker might take some time to move the thread on another CPU. 120*6dbdd20aSAndroid Build Coastguard Worker 121*6dbdd20aSAndroid Build Coastguard WorkerUnless using real-time thread priorities, most Linux Kernel scheduler 122*6dbdd20aSAndroid Build Coastguard Workerconfigurations are not strictly work-conserving. For instance the scheduler 123*6dbdd20aSAndroid Build Coastguard Workermight prefer to wait some time in the hope that the thread running on the 124*6dbdd20aSAndroid Build Coastguard Workercurrent CPU goes to idle, avoiding a cross-cpu migration which might be more 125*6dbdd20aSAndroid Build Coastguard Workercostly both in terms of overhead and power. 126*6dbdd20aSAndroid Build Coastguard Worker 127*6dbdd20aSAndroid Build Coastguard WorkerNOTE: `sched_waking` and `sched_wakeup` provide nearly the same information. The 128*6dbdd20aSAndroid Build Coastguard Worker difference lies in wakeup events across CPUs, which involve 129*6dbdd20aSAndroid Build Coastguard Worker inter-processor interrupts. The former is always emitted on the source (wakee) 130*6dbdd20aSAndroid Build Coastguard Worker CPU, the latter may be executed on either the source or the destination (waked) CPU 131*6dbdd20aSAndroid Build Coastguard Worker depending on several factors. `sched_waking` is usually sufficient for latency 132*6dbdd20aSAndroid Build Coastguard Worker analysis, unless you are looking into breaking down latency due to 133*6dbdd20aSAndroid Build Coastguard Worker the scheduler's wake up path, such as inter-processor signaling. 134*6dbdd20aSAndroid Build Coastguard Worker 135*6dbdd20aSAndroid Build Coastguard WorkerWhen enabling `sched_waking` events, the following will appear in the UI when 136*6dbdd20aSAndroid Build Coastguard Workerselecting a CPU slice: 137*6dbdd20aSAndroid Build Coastguard Worker 138*6dbdd20aSAndroid Build Coastguard Worker 139*6dbdd20aSAndroid Build Coastguard Worker 140*6dbdd20aSAndroid Build Coastguard Worker### Decoding `end_state` 141*6dbdd20aSAndroid Build Coastguard Worker 142*6dbdd20aSAndroid Build Coastguard WorkerThe [sched_slice](/docs/analysis/sql-tables.autogen#sched_slice) table contains 143*6dbdd20aSAndroid Build Coastguard Workerinformation on scheduling activity of the system: 144*6dbdd20aSAndroid Build Coastguard Worker 145*6dbdd20aSAndroid Build Coastguard Worker``` 146*6dbdd20aSAndroid Build Coastguard Worker> select * from sched_slice limit 1 147*6dbdd20aSAndroid Build Coastguard Workerid type ts dur cpu utid end_state priority 148*6dbdd20aSAndroid Build Coastguard Worker0 sched_slice 70730062200 125364 0 1 S 130 149*6dbdd20aSAndroid Build Coastguard Worker``` 150*6dbdd20aSAndroid Build Coastguard Worker 151*6dbdd20aSAndroid Build Coastguard WorkerEach row of the table shows when a given thread (`utid`) began running 152*6dbdd20aSAndroid Build Coastguard Worker(`ts`), on which core it ran (`cpu`), for how long it ran (`dur`), 153*6dbdd20aSAndroid Build Coastguard Workerand why it stopped running: `end_state`. 154*6dbdd20aSAndroid Build Coastguard Worker 155*6dbdd20aSAndroid Build Coastguard Worker`end_state` is encoded as one or more ascii characters. The UI uses 156*6dbdd20aSAndroid Build Coastguard Workerthe following translations to convert `end_state` into human readable 157*6dbdd20aSAndroid Build Coastguard Workertext: 158*6dbdd20aSAndroid Build Coastguard Worker 159*6dbdd20aSAndroid Build Coastguard Worker| end_state | Translation | 160*6dbdd20aSAndroid Build Coastguard Worker|------------|------------------------| 161*6dbdd20aSAndroid Build Coastguard Worker| R | Runnable | 162*6dbdd20aSAndroid Build Coastguard Worker| R+ | Runnable (Preempted) | 163*6dbdd20aSAndroid Build Coastguard Worker| S | Sleeping | 164*6dbdd20aSAndroid Build Coastguard Worker| D | Uninterruptible Sleep | 165*6dbdd20aSAndroid Build Coastguard Worker| T | Stopped | 166*6dbdd20aSAndroid Build Coastguard Worker| t | Traced | 167*6dbdd20aSAndroid Build Coastguard Worker| X | Exit (Dead) | 168*6dbdd20aSAndroid Build Coastguard Worker| Z | Exit (Zombie) | 169*6dbdd20aSAndroid Build Coastguard Worker| x | Task Dead | 170*6dbdd20aSAndroid Build Coastguard Worker| I | Idle | 171*6dbdd20aSAndroid Build Coastguard Worker| K | Wake Kill | 172*6dbdd20aSAndroid Build Coastguard Worker| W | Waking | 173*6dbdd20aSAndroid Build Coastguard Worker| P | Parked | 174*6dbdd20aSAndroid Build Coastguard Worker| N | No Load | 175*6dbdd20aSAndroid Build Coastguard Worker 176*6dbdd20aSAndroid Build Coastguard WorkerNot all combinations of characters are meaningful. 177*6dbdd20aSAndroid Build Coastguard Worker 178*6dbdd20aSAndroid Build Coastguard WorkerIf we do not know when the scheduling ended (for example because the 179*6dbdd20aSAndroid Build Coastguard Workertrace ended while the thread was still running) `end_state` will be 180*6dbdd20aSAndroid Build Coastguard Worker`NULL` and `dur` will be -1. 181*6dbdd20aSAndroid Build Coastguard Worker 182