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