xref: /aosp_15_r20/external/bcc/examples/tracing/disksnoop.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# disksnoop.py	Trace block device I/O: basic version of iosnoop.
4*387f9dfdSAndroid Build Coastguard Worker#		For Linux, uses BCC, eBPF. Embedded C.
5*387f9dfdSAndroid Build Coastguard Worker#
6*387f9dfdSAndroid Build Coastguard Worker# Written as a basic example of tracing latency.
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2015 Brendan Gregg.
9*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
10*387f9dfdSAndroid Build Coastguard Worker#
11*387f9dfdSAndroid Build Coastguard Worker# 11-Aug-2015	Brendan Gregg	Created this.
12*387f9dfdSAndroid Build Coastguard Worker
13*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
14*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
15*387f9dfdSAndroid Build Coastguard Workerfrom bcc.utils import printb
16*387f9dfdSAndroid Build Coastguard Worker
17*387f9dfdSAndroid Build Coastguard WorkerREQ_WRITE = 1		# from include/linux/blk_types.h
18*387f9dfdSAndroid Build Coastguard Worker
19*387f9dfdSAndroid Build Coastguard Worker# load BPF program
20*387f9dfdSAndroid Build Coastguard Workerb = BPF(text="""
21*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
22*387f9dfdSAndroid Build Coastguard Worker#include <linux/blk-mq.h>
23*387f9dfdSAndroid Build Coastguard Worker
24*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start, struct request *);
25*387f9dfdSAndroid Build Coastguard Worker
26*387f9dfdSAndroid Build Coastguard Workervoid trace_start(struct pt_regs *ctx, struct request *req) {
27*387f9dfdSAndroid Build Coastguard Worker	// stash start timestamp by request ptr
28*387f9dfdSAndroid Build Coastguard Worker	u64 ts = bpf_ktime_get_ns();
29*387f9dfdSAndroid Build Coastguard Worker
30*387f9dfdSAndroid Build Coastguard Worker	start.update(&req, &ts);
31*387f9dfdSAndroid Build Coastguard Worker}
32*387f9dfdSAndroid Build Coastguard Worker
33*387f9dfdSAndroid Build Coastguard Workervoid trace_completion(struct pt_regs *ctx, struct request *req) {
34*387f9dfdSAndroid Build Coastguard Worker	u64 *tsp, delta;
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Worker	tsp = start.lookup(&req);
37*387f9dfdSAndroid Build Coastguard Worker	if (tsp != 0) {
38*387f9dfdSAndroid Build Coastguard Worker		delta = bpf_ktime_get_ns() - *tsp;
39*387f9dfdSAndroid Build Coastguard Worker		bpf_trace_printk("%d %x %d\\n", req->__data_len,
40*387f9dfdSAndroid Build Coastguard Worker		    req->cmd_flags, delta / 1000);
41*387f9dfdSAndroid Build Coastguard Worker		start.delete(&req);
42*387f9dfdSAndroid Build Coastguard Worker	}
43*387f9dfdSAndroid Build Coastguard Worker}
44*387f9dfdSAndroid Build Coastguard Worker""")
45*387f9dfdSAndroid Build Coastguard Worker
46*387f9dfdSAndroid Build Coastguard Workerif BPF.get_kprobe_functions(b'blk_start_request'):
47*387f9dfdSAndroid Build Coastguard Worker        b.attach_kprobe(event="blk_start_request", fn_name="trace_start")
48*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start")
49*387f9dfdSAndroid Build Coastguard Workerif BPF.get_kprobe_functions(b'__blk_account_io_done'):
50*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_completion")
51*387f9dfdSAndroid Build Coastguard Workerelse:
52*387f9dfdSAndroid Build Coastguard Worker    b.attach_kprobe(event="blk_account_io_done", fn_name="trace_completion")
53*387f9dfdSAndroid Build Coastguard Worker
54*387f9dfdSAndroid Build Coastguard Worker# header
55*387f9dfdSAndroid Build Coastguard Workerprint("%-18s %-2s %-7s %8s" % ("TIME(s)", "T", "BYTES", "LAT(ms)"))
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard Worker# format output
58*387f9dfdSAndroid Build Coastguard Workerwhile 1:
59*387f9dfdSAndroid Build Coastguard Worker	try:
60*387f9dfdSAndroid Build Coastguard Worker		(task, pid, cpu, flags, ts, msg) = b.trace_fields()
61*387f9dfdSAndroid Build Coastguard Worker		(bytes_s, bflags_s, us_s) = msg.split()
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker		if int(bflags_s, 16) & REQ_WRITE:
64*387f9dfdSAndroid Build Coastguard Worker			type_s = b"W"
65*387f9dfdSAndroid Build Coastguard Worker		elif bytes_s == "0":	# see blk_fill_rwbs() for logic
66*387f9dfdSAndroid Build Coastguard Worker			type_s = b"M"
67*387f9dfdSAndroid Build Coastguard Worker		else:
68*387f9dfdSAndroid Build Coastguard Worker			type_s = b"R"
69*387f9dfdSAndroid Build Coastguard Worker		ms = float(int(us_s, 10)) / 1000
70*387f9dfdSAndroid Build Coastguard Worker
71*387f9dfdSAndroid Build Coastguard Worker		printb(b"%-18.9f %-2s %-7s %8.2f" % (ts, type_s, bytes_s, ms))
72*387f9dfdSAndroid Build Coastguard Worker	except KeyboardInterrupt:
73*387f9dfdSAndroid Build Coastguard Worker		exit()
74