Alexey Ivanov | cc01a9c | 2019-01-16 09:50:46 -0800 | [diff] [blame] | 1 | #!/usr/bin/python |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 2 | # |
| 3 | # disksnoop.py Trace block device I/O: basic version of iosnoop. |
Brendan Gregg | 9894e3e | 2016-07-24 13:37:20 -0700 | [diff] [blame] | 4 | # For Linux, uses BCC, eBPF. Embedded C. |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 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 | |
Brendan Gregg | 762b1b4 | 2015-08-18 16:49:48 -0700 | [diff] [blame] | 13 | from __future__ import print_function |
Brenden Blanco | c35989d | 2015-09-02 18:04:07 -0700 | [diff] [blame] | 14 | from bcc import BPF |
Gary Lin | bb65bea | 2019-02-27 16:52:35 +0800 | [diff] [blame] | 15 | from bcc.utils import printb |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 16 | |
| 17 | REQ_WRITE = 1 # from include/linux/blk_types.h |
| 18 | |
| 19 | # load BPF program |
Brendan Gregg | 9894e3e | 2016-07-24 13:37:20 -0700 | [diff] [blame] | 20 | b = BPF(text=""" |
| 21 | #include <uapi/linux/ptrace.h> |
Hengqi Chen | 3a03901 | 2022-02-24 23:29:35 +0800 | [diff] [blame] | 22 | #include <linux/blk-mq.h> |
Brendan Gregg | 9894e3e | 2016-07-24 13:37:20 -0700 | [diff] [blame] | 23 | |
| 24 | BPF_HASH(start, struct request *); |
| 25 | |
| 26 | void 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 | |
| 33 | void 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 Drescher | a57dad4 | 2019-05-28 10:22:28 -0400 | [diff] [blame] | 46 | if BPF.get_kprobe_functions(b'blk_start_request'): |
| 47 | b.attach_kprobe(event="blk_start_request", fn_name="trace_start") |
Brendan Gregg | 6ed4a49 | 2015-09-16 15:12:55 -0700 | [diff] [blame] | 48 | b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start") |
Hengqi Chen | 3a03901 | 2022-02-24 23:29:35 +0800 | [diff] [blame] | 49 | if BPF.get_kprobe_functions(b'__blk_account_io_done'): |
| 50 | b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_completion") |
| 51 | else: |
| 52 | b.attach_kprobe(event="blk_account_io_done", fn_name="trace_completion") |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 53 | |
| 54 | # header |
Brendan Gregg | 762b1b4 | 2015-08-18 16:49:48 -0700 | [diff] [blame] | 55 | print("%-18s %-2s %-7s %8s" % ("TIME(s)", "T", "BYTES", "LAT(ms)")) |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 56 | |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 57 | # format output |
| 58 | while 1: |
Xiaozhou Liu | 922f1ab | 2019-02-03 21:27:59 +0800 | [diff] [blame] | 59 | try: |
| 60 | (task, pid, cpu, flags, ts, msg) = b.trace_fields() |
| 61 | (bytes_s, bflags_s, us_s) = msg.split() |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 62 | |
Xiaozhou Liu | 922f1ab | 2019-02-03 21:27:59 +0800 | [diff] [blame] | 63 | if int(bflags_s, 16) & REQ_WRITE: |
Gary Lin | bb65bea | 2019-02-27 16:52:35 +0800 | [diff] [blame] | 64 | type_s = b"W" |
Xiaozhou Liu | 922f1ab | 2019-02-03 21:27:59 +0800 | [diff] [blame] | 65 | elif bytes_s == "0": # see blk_fill_rwbs() for logic |
Gary Lin | bb65bea | 2019-02-27 16:52:35 +0800 | [diff] [blame] | 66 | type_s = b"M" |
Xiaozhou Liu | 922f1ab | 2019-02-03 21:27:59 +0800 | [diff] [blame] | 67 | else: |
Gary Lin | bb65bea | 2019-02-27 16:52:35 +0800 | [diff] [blame] | 68 | type_s = b"R" |
Xiaozhou Liu | 922f1ab | 2019-02-03 21:27:59 +0800 | [diff] [blame] | 69 | ms = float(int(us_s, 10)) / 1000 |
Brendan Gregg | 48fbc3e | 2015-08-18 14:56:14 -0700 | [diff] [blame] | 70 | |
Gary Lin | bb65bea | 2019-02-27 16:52:35 +0800 | [diff] [blame] | 71 | printb(b"%-18.9f %-2s %-7s %8.2f" % (ts, type_s, bytes_s, ms)) |
Xiaozhou Liu | 922f1ab | 2019-02-03 21:27:59 +0800 | [diff] [blame] | 72 | except KeyboardInterrupt: |
| 73 | exit() |