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