1#!/usr/bin/python 2# 3# bitehist.py Block I/O size histogram. 4# For Linux, uses BCC, eBPF. See .c file. 5# 6# USAGE: bitesize 7# 8# Ctrl-C will print the partially gathered histogram then exit. 9# 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 22struct proc_key_t { 23 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 44int do_count(struct pt_regs *ctx, struct request *req) 45{ 46 struct val_t *valp; 47 48 valp = commbyreq.lookup(&req); 49 if (valp == 0) { 50 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 } 58 return 0; 59} 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: 75 dist.print_log2_hist("Kbytes", "Process Name", 76 section_print_fn=bytes.decode) 77