xref: /aosp_15_r20/external/bcc/examples/lua/kprobe-latency.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-- This example program measures latency of block device operations and plots it
18*387f9dfdSAndroid Build Coastguard Worker-- in a histogram. It is similar to BPF example:
19*387f9dfdSAndroid Build Coastguard Worker-- https://github.com/torvalds/linux/blob/master/samples/bpf/tracex3_kern.c
20*387f9dfdSAndroid Build Coastguard Workerlocal ffi = require('ffi')
21*387f9dfdSAndroid Build Coastguard Workerlocal bpf = require('bpf')
22*387f9dfdSAndroid Build Coastguard Workerlocal S = require('syscall')
23*387f9dfdSAndroid Build Coastguard Worker
24*387f9dfdSAndroid Build Coastguard Worker-- Shared part of the program
25*387f9dfdSAndroid Build Coastguard Workerlocal bins = 100
26*387f9dfdSAndroid Build Coastguard Workerlocal map = bpf.map('hash', 512, ffi.typeof('uint64_t'), ffi.typeof('uint64_t'))
27*387f9dfdSAndroid Build Coastguard Workerlocal lat_map = bpf.map('array', bins)
28*387f9dfdSAndroid Build Coastguard Worker
29*387f9dfdSAndroid Build Coastguard Worker-- Kernel-space part of the program
30*387f9dfdSAndroid Build Coastguard Workerlocal trace_start = bpf.kprobe('myprobe:blk_start_request', function (ptregs)
31*387f9dfdSAndroid Build Coastguard Worker	map[ptregs.parm1] = time()
32*387f9dfdSAndroid Build Coastguard Workerend, false, -1, 0)
33*387f9dfdSAndroid Build Coastguard Workerlocal trace_end = bpf.kprobe('myprobe2:blk_account_io_done', function (ptregs)
34*387f9dfdSAndroid Build Coastguard Worker	-- The lines below are computing index
35*387f9dfdSAndroid Build Coastguard Worker	-- using log10(x)*10 = log2(x)*10/log2(10) = log2(x)*3
36*387f9dfdSAndroid Build Coastguard Worker	-- index = 29 ~ 1 usec
37*387f9dfdSAndroid Build Coastguard Worker	-- index = 59 ~ 1 msec
38*387f9dfdSAndroid Build Coastguard Worker	-- index = 89 ~ 1 sec
39*387f9dfdSAndroid Build Coastguard Worker	-- index = 99 ~ 10sec or more
40*387f9dfdSAndroid Build Coastguard Worker	local delta = time() - map[ptregs.parm1]
41*387f9dfdSAndroid Build Coastguard Worker	local index = 3 * math.log2(delta)
42*387f9dfdSAndroid Build Coastguard Worker	if index >= bins then
43*387f9dfdSAndroid Build Coastguard Worker		index = bins-1
44*387f9dfdSAndroid Build Coastguard Worker	end
45*387f9dfdSAndroid Build Coastguard Worker	xadd(lat_map[index], 1)
46*387f9dfdSAndroid Build Coastguard Worker	return true
47*387f9dfdSAndroid Build Coastguard Workerend, false, -1, 0)
48*387f9dfdSAndroid Build Coastguard Worker-- User-space part of the program
49*387f9dfdSAndroid Build Coastguard Workerpcall(function()
50*387f9dfdSAndroid Build Coastguard Worker	local counter = 0
51*387f9dfdSAndroid Build Coastguard Worker	local sym = {' ',' ','.','.','*','*','o','o','O','O','#','#'}
52*387f9dfdSAndroid Build Coastguard Worker	while true do
53*387f9dfdSAndroid Build Coastguard Worker		-- Print header once in a while
54*387f9dfdSAndroid Build Coastguard Worker		if counter % 50 == 0 then
55*387f9dfdSAndroid Build Coastguard Worker			print('|1us      |10us     |100us    |1ms      |10ms     |100ms    |1s       |10s')
56*387f9dfdSAndroid Build Coastguard Worker			counter = 0
57*387f9dfdSAndroid Build Coastguard Worker		end
58*387f9dfdSAndroid Build Coastguard Worker		counter = counter + 1
59*387f9dfdSAndroid Build Coastguard Worker		-- Collect all events
60*387f9dfdSAndroid Build Coastguard Worker		local hist, events = {}, 0
61*387f9dfdSAndroid Build Coastguard Worker		for i=29,bins-1 do
62*387f9dfdSAndroid Build Coastguard Worker			local v = tonumber(lat_map[i] or 0)
63*387f9dfdSAndroid Build Coastguard Worker			if v > 0 then
64*387f9dfdSAndroid Build Coastguard Worker				hist[i] = hist[i] or 0 + v
65*387f9dfdSAndroid Build Coastguard Worker				events = events + v
66*387f9dfdSAndroid Build Coastguard Worker			end
67*387f9dfdSAndroid Build Coastguard Worker		end
68*387f9dfdSAndroid Build Coastguard Worker		-- Print histogram symbols based on relative frequency
69*387f9dfdSAndroid Build Coastguard Worker		local s = ''
70*387f9dfdSAndroid Build Coastguard Worker		for i=29,bins-1 do
71*387f9dfdSAndroid Build Coastguard Worker			if hist[i] then
72*387f9dfdSAndroid Build Coastguard Worker				local c = math.ceil((hist[i] / (events + 1)) * #sym)
73*387f9dfdSAndroid Build Coastguard Worker				s = s .. sym[c]
74*387f9dfdSAndroid Build Coastguard Worker			else s = s .. ' ' end
75*387f9dfdSAndroid Build Coastguard Worker		end
76*387f9dfdSAndroid Build Coastguard Worker		print(s .. string.format('  ; %d events', events))
77*387f9dfdSAndroid Build Coastguard Worker		S.sleep(1)
78*387f9dfdSAndroid Build Coastguard Worker	end
79*387f9dfdSAndroid Build Coastguard Workerend)