xref: /aosp_15_r20/external/bcc/examples/lua/tracepoint-offcputime.lua (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env bcc-lua
2*387f9dfdSAndroid Build Coastguard Worker--[[
3*387f9dfdSAndroid Build Coastguard WorkerCopyright 2016 Marek Vavrusa <[email protected]>
4*387f9dfdSAndroid Build Coastguard Worker
5*387f9dfdSAndroid Build Coastguard WorkerLicensed under the Apache License, Version 2.0 (the "License");
6*387f9dfdSAndroid Build Coastguard Workeryou may not use this file except in compliance with the License.
7*387f9dfdSAndroid Build Coastguard WorkerYou may obtain a copy of the License at
8*387f9dfdSAndroid Build Coastguard Worker
9*387f9dfdSAndroid Build Coastguard Workerhttp://www.apache.org/licenses/LICENSE-2.0
10*387f9dfdSAndroid Build Coastguard Worker
11*387f9dfdSAndroid Build Coastguard WorkerUnless required by applicable law or agreed to in writing, software
12*387f9dfdSAndroid Build Coastguard Workerdistributed under the License is distributed on an "AS IS" BASIS,
13*387f9dfdSAndroid Build Coastguard WorkerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*387f9dfdSAndroid Build Coastguard WorkerSee the License for the specific language governing permissions and
15*387f9dfdSAndroid Build Coastguard Workerlimitations under the License.
16*387f9dfdSAndroid Build Coastguard Worker]]
17*387f9dfdSAndroid Build Coastguard Worker-- Summarize off-CPU time by stack trace
18*387f9dfdSAndroid Build Coastguard Worker-- Related tool: https://github.com/iovisor/bcc/blob/master/tools/offcputime.py
19*387f9dfdSAndroid Build Coastguard Workerlocal ffi = require('ffi')
20*387f9dfdSAndroid Build Coastguard Workerlocal bpf = require('bpf')
21*387f9dfdSAndroid Build Coastguard Workerlocal S = require('syscall')
22*387f9dfdSAndroid Build Coastguard Worker-- Create BPF maps
23*387f9dfdSAndroid Build Coastguard Worker-- TODO: made smaller to fit default memory limits
24*387f9dfdSAndroid Build Coastguard Workerlocal key_t = 'struct { char name[16]; int32_t stack_id; }'
25*387f9dfdSAndroid Build Coastguard Workerlocal starts = assert(bpf.map('hash', 128, ffi.typeof('uint32_t'), ffi.typeof('uint64_t')))
26*387f9dfdSAndroid Build Coastguard Workerlocal counts = assert(bpf.map('hash', 128, ffi.typeof(key_t), ffi.typeof('uint64_t')))
27*387f9dfdSAndroid Build Coastguard Workerlocal stack_traces = assert(bpf.map('stack_trace', 16))
28*387f9dfdSAndroid Build Coastguard Worker-- Open tracepoint and attach BPF program
29*387f9dfdSAndroid Build Coastguard Worker-- The 'arg' parses tracepoint format automatically
30*387f9dfdSAndroid Build Coastguard Workerlocal tp = bpf.tracepoint('sched/sched_switch', function (arg)
31*387f9dfdSAndroid Build Coastguard Worker	-- Update previous thread sleep time
32*387f9dfdSAndroid Build Coastguard Worker	local pid = arg.prev_pid
33*387f9dfdSAndroid Build Coastguard Worker	local now = time()
34*387f9dfdSAndroid Build Coastguard Worker	starts[pid] = now
35*387f9dfdSAndroid Build Coastguard Worker	-- Calculate current thread's delta time
36*387f9dfdSAndroid Build Coastguard Worker	pid = arg.next_pid
37*387f9dfdSAndroid Build Coastguard Worker	local from = starts[pid]
38*387f9dfdSAndroid Build Coastguard Worker	if not from then
39*387f9dfdSAndroid Build Coastguard Worker		return 0
40*387f9dfdSAndroid Build Coastguard Worker	end
41*387f9dfdSAndroid Build Coastguard Worker	local delta = (now - from) / 1000
42*387f9dfdSAndroid Build Coastguard Worker	starts[pid] = nil
43*387f9dfdSAndroid Build Coastguard Worker	-- Check if the delta is below 1us
44*387f9dfdSAndroid Build Coastguard Worker	if delta < 1 then
45*387f9dfdSAndroid Build Coastguard Worker		return
46*387f9dfdSAndroid Build Coastguard Worker	end
47*387f9dfdSAndroid Build Coastguard Worker	-- Create key for this thread
48*387f9dfdSAndroid Build Coastguard Worker	local key = ffi.new(key_t)
49*387f9dfdSAndroid Build Coastguard Worker	comm(key.name)
50*387f9dfdSAndroid Build Coastguard Worker	key.stack_id = stack_id(stack_traces, BPF.F_FAST_STACK_CMP)
51*387f9dfdSAndroid Build Coastguard Worker	-- Update current thread off cpu time with delta
52*387f9dfdSAndroid Build Coastguard Worker	local val = counts[key]
53*387f9dfdSAndroid Build Coastguard Worker	if not val then
54*387f9dfdSAndroid Build Coastguard Worker		counts[key] = 0
55*387f9dfdSAndroid Build Coastguard Worker	end
56*387f9dfdSAndroid Build Coastguard Worker	xadd(counts[key], delta)
57*387f9dfdSAndroid Build Coastguard Workerend, 0, -1)
58*387f9dfdSAndroid Build Coastguard Worker-- Helper: load kernel symbols
59*387f9dfdSAndroid Build Coastguard Workerffi.cdef 'unsigned long long strtoull(const char *, char **, int);'
60*387f9dfdSAndroid Build Coastguard Workerlocal ksyms = {}
61*387f9dfdSAndroid Build Coastguard Workerfor l in io.lines('/proc/kallsyms') do
62*387f9dfdSAndroid Build Coastguard Worker	local addr, sym = l:match '(%w+) %w (%S+)'
63*387f9dfdSAndroid Build Coastguard Worker	if addr then ksyms[ffi.C.strtoull(addr, nil, 16)] = sym end
64*387f9dfdSAndroid Build Coastguard Workerend
65*387f9dfdSAndroid Build Coastguard Worker-- User-space part of the program
66*387f9dfdSAndroid Build Coastguard Workerwhile true do
67*387f9dfdSAndroid Build Coastguard Worker	for k,v in counts.pairs,counts,nil do
68*387f9dfdSAndroid Build Coastguard Worker		local s = ''
69*387f9dfdSAndroid Build Coastguard Worker		local traces = stack_traces[k.stack_id]
70*387f9dfdSAndroid Build Coastguard Worker		if traces then
71*387f9dfdSAndroid Build Coastguard Worker			for i, ip in ipairs(traces) do
72*387f9dfdSAndroid Build Coastguard Worker				s = s .. string.format("    %-16p %s", ip, ksyms[ip])
73*387f9dfdSAndroid Build Coastguard Worker			end
74*387f9dfdSAndroid Build Coastguard Worker		end
75*387f9dfdSAndroid Build Coastguard Worker		s = s .. string.format("    %-16s %s", "-", ffi.string(k.name))
76*387f9dfdSAndroid Build Coastguard Worker		s = s .. string.format("        %d", tonumber(v))
77*387f9dfdSAndroid Build Coastguard Worker		print(s)
78*387f9dfdSAndroid Build Coastguard Worker	end
79*387f9dfdSAndroid Build Coastguard Worker	S.sleep(1)
80*387f9dfdSAndroid Build Coastguard Workerend
81