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