blob: 7b6891b7f48fa4a3033949032ed81ed8e5c77ed0 [file] [log] [blame]
Alexey Ivanovcc01a9c2019-01-16 09:50:46 -08001#!/usr/bin/python
Brendan Gregg48fbc3e2015-08-18 14:56:14 -07002#
3# disksnoop.py Trace block device I/O: basic version of iosnoop.
Brendan Gregg9894e3e2016-07-24 13:37:20 -07004# For Linux, uses BCC, eBPF. Embedded C.
Brendan Gregg48fbc3e2015-08-18 14:56:14 -07005#
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
Brendan Gregg762b1b42015-08-18 16:49:48 -070013from __future__ import print_function
Brenden Blancoc35989d2015-09-02 18:04:07 -070014from bcc import BPF
Gary Linbb65bea2019-02-27 16:52:35 +080015from bcc.utils import printb
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070016
17REQ_WRITE = 1 # from include/linux/blk_types.h
18
19# load BPF program
Brendan Gregg9894e3e2016-07-24 13:37:20 -070020b = BPF(text="""
21#include <uapi/linux/ptrace.h>
Hengqi Chen3a039012022-02-24 23:29:35 +080022#include <linux/blk-mq.h>
Brendan Gregg9894e3e2016-07-24 13:37:20 -070023
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
Adam Dreschera57dad42019-05-28 10:22:28 -040046if BPF.get_kprobe_functions(b'blk_start_request'):
47 b.attach_kprobe(event="blk_start_request", fn_name="trace_start")
Brendan Gregg6ed4a492015-09-16 15:12:55 -070048b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start")
Hengqi Chen3a039012022-02-24 23:29:35 +080049if 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")
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070053
54# header
Brendan Gregg762b1b42015-08-18 16:49:48 -070055print("%-18s %-2s %-7s %8s" % ("TIME(s)", "T", "BYTES", "LAT(ms)"))
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070056
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070057# format output
58while 1:
Xiaozhou Liu922f1ab2019-02-03 21:27:59 +080059 try:
60 (task, pid, cpu, flags, ts, msg) = b.trace_fields()
61 (bytes_s, bflags_s, us_s) = msg.split()
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070062
Xiaozhou Liu922f1ab2019-02-03 21:27:59 +080063 if int(bflags_s, 16) & REQ_WRITE:
Gary Linbb65bea2019-02-27 16:52:35 +080064 type_s = b"W"
Xiaozhou Liu922f1ab2019-02-03 21:27:59 +080065 elif bytes_s == "0": # see blk_fill_rwbs() for logic
Gary Linbb65bea2019-02-27 16:52:35 +080066 type_s = b"M"
Xiaozhou Liu922f1ab2019-02-03 21:27:59 +080067 else:
Gary Linbb65bea2019-02-27 16:52:35 +080068 type_s = b"R"
Xiaozhou Liu922f1ab2019-02-03 21:27:59 +080069 ms = float(int(us_s, 10)) / 1000
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070070
Gary Linbb65bea2019-02-27 16:52:35 +080071 printb(b"%-18.9f %-2s %-7s %8.2f" % (ts, type_s, bytes_s, ms))
Xiaozhou Liu922f1ab2019-02-03 21:27:59 +080072 except KeyboardInterrupt:
73 exit()