blob: e57185dd981964deaf8e86d49bb0d3f3547e86aa [file] [log] [blame]
Alexey Ivanov777e8022019-01-03 13:46:38 -08001#!/usr/bin/env python
mcaleavya6959dcf2016-02-06 12:00:34 +00002#
3# bitehist.py Block I/O size histogram.
4# For Linux, uses BCC, eBPF. See .c file.
5#
6# USAGE: bitesize
mcaleavya6959dcf2016-02-06 12:00:34 +00007#
Brendan Gregg6497a842016-02-06 17:08:38 -08008# Ctrl-C will print the partially gathered histogram then exit.
mcaleavya6959dcf2016-02-06 12:00:34 +00009#
10# Copyright (c) 2016 Allan McAleavy
11# Licensed under the Apache License, Version 2.0 (the "License")
12#
13# 05-Feb-2016 Allan McAleavy ran pep8 against file
14
15from bcc import BPF
16from time import sleep
17
18bpf_text = """
19#include <uapi/linux/ptrace.h>
20#include <linux/blkdev.h>
21
Brendan Greggf6e92c92016-02-06 17:11:59 -080022struct proc_key_t {
mcaleavya6959dcf2016-02-06 12:00:34 +000023 char name[TASK_COMM_LEN];
24 u64 slot;
25};
26
27struct val_t {
28 char name[TASK_COMM_LEN];
29};
30
31BPF_HISTOGRAM(dist, struct proc_key_t);
32BPF_HASH(commbyreq, struct request *, struct val_t);
33
34int trace_pid_start(struct pt_regs *ctx, struct request *req)
35{
36 struct val_t val = {};
37
38 if (bpf_get_current_comm(&val.name, sizeof(val.name)) == 0) {
39 commbyreq.update(&req, &val);
40 }
41 return 0;
42}
43
Brendan Greggf6e92c92016-02-06 17:11:59 -080044int do_count(struct pt_regs *ctx, struct request *req)
mcaleavya6959dcf2016-02-06 12:00:34 +000045{
46 struct val_t *valp;
47
48 valp = commbyreq.lookup(&req);
Brendan Greggf6e92c92016-02-06 17:11:59 -080049 if (valp == 0) {
mcaleavya6959dcf2016-02-06 12:00:34 +000050 return 0;
51 }
52
53 if (req->__data_len > 0) {
54 struct proc_key_t key = {.slot = bpf_log2l(req->__data_len / 1024)};
55 bpf_probe_read(&key.name, sizeof(key.name),valp->name);
56 dist.increment(key);
57 }
Brendan Gregg6497a842016-02-06 17:08:38 -080058 return 0;
mcaleavya6959dcf2016-02-06 12:00:34 +000059}
60"""
61
62# load BPF program
63b = BPF(text=bpf_text)
64b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
65b.attach_kprobe(event="blk_account_io_completion", fn_name="do_count")
66
67print("Tracing... Hit Ctrl-C to end.")
68
69# trace until Ctrl-C
70dist = b.get_table("dist")
71
72try:
73 sleep(99999999)
74except KeyboardInterrupt:
Rafael F78948e42017-03-26 14:54:25 +020075 dist.print_log2_hist("Kbytes", "Process Name",
76 section_print_fn=bytes.decode)