Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add in tool bitesize #342

Merged
merged 4 commits into from
Feb 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Tools:
- tools/[bashreadline](tools/bashreadline.py): Print entered bash commands system wide. [Examples](tools/bashreadline_example.txt).
- tools/[biolatency](tools/biolatency.py): Summarize block device I/O latency as a histogram. [Examples](tools/biolatency_example.txt).
- tools/[biosnoop](tools/biosnoop.py): Trace block device I/O with PID and latency. [Examples](tools/biosnoop_example.txt).
- tools/[bitesize](tools/bitesize.py): Show per process I/O size histogram. [Examples](tools/bitesize_example.txt).
- tools/[cachestat](tools/cachestat.py): Trace page cache hit/miss ratio. [Examples](tools/cachestat_example.txt).
- tools/[funccount](tools/funccount.py): Count kernel function calls. [Examples](tools/funccount_example.txt).
- tools/[funclatency](tools/funclatency.py): Time kernel functions and show their latency distribution. [Examples](tools/funclatency_example.txt).
Expand Down
52 changes: 52 additions & 0 deletions man/man8/bitesize.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.TH bitesize 8 "2016-02-05" "USER COMMANDS"
.SH NAME
bitesize \- Summarize block device I/O size as a histogram \- Linux eBPF/bcc.
.SH SYNOPSIS
.B bitesize
.SH DESCRIPTION
Show I/O distribution for requested block sizes, by process name.

This works by tracing block I/O kernel functions using dynamic
tracing and prints a historgram of I/O size.

Since this uses BPF, only the root user can use this tool.
.SH REQUIREMENTS
CONFIG_BPF and bcc.
.SH EXAMPLES
.TP
Count I/O size per process until Ctrl-C is hit:
#
.B bitesize
.SH FIELDS
.TP
Kbtes
Size in kilobytes of range
.TP
count
How many I/O fell into this range
.TP
distribution
An ASCII bar chart to visualize the distribution (count column)

.SH OVERHEAD
This traces kernel block I/O functions to update a histgroam, which are
asynchronously copied to user-space. This method is very efficient, and
the overhead for most storage I/O rates (< 10k IOPS) should be negligible.
If you have a higher IOPS storage environment, test and quantify the overhead
before use.

.SH SOURCE
This is from bcc.
.IP
https://github.com/iovisor/bcc
.PP
Also look in the bcc distribution for a companion _examples.txt file containing
example usage, output, and commentary for this tool.
.SH OS
Linux
.SH STABILITY
Unstable - in development.
.SH AUTHOR
Allan McAleavy
.SH SEE ALSO
https://github.com/brendangregg/systemtap-lwtools/blob/master/disk/bitesize-nd.stp
75 changes: 75 additions & 0 deletions tools/bitesize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/python
#
# bitehist.py Block I/O size histogram.
# For Linux, uses BCC, eBPF. See .c file.
#
# USAGE: bitesize
# Ctrl-C will print the partially gathered histogram then exit.
#
#
# Copyright (c) 2016 Allan McAleavy
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 05-Feb-2016 Allan McAleavy ran pep8 against file

from bcc import BPF
from time import sleep

bpf_text = """
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>

struct proc_key_t {
char name[TASK_COMM_LEN];
u64 slot;
};

struct val_t {
char name[TASK_COMM_LEN];
};

BPF_HISTOGRAM(dist, struct proc_key_t);
BPF_HASH(commbyreq, struct request *, struct val_t);

int trace_pid_start(struct pt_regs *ctx, struct request *req)
{
struct val_t val = {};

if (bpf_get_current_comm(&val.name, sizeof(val.name)) == 0) {
commbyreq.update(&req, &val);
}
return 0;
}

int do_count (struct pt_regs *ctx, struct request *req)
{
struct val_t *valp;

valp = commbyreq.lookup(&req);
if ( valp == 0) {
return 0;
}

if (req->__data_len > 0) {
struct proc_key_t key = {.slot = bpf_log2l(req->__data_len / 1024)};
bpf_probe_read(&key.name, sizeof(key.name),valp->name);
dist.increment(key);
}
return 0;
}
"""

# load BPF program
b = BPF(text=bpf_text)
b.attach_kprobe(event="blk_account_io_start", fn_name="trace_pid_start")
b.attach_kprobe(event="blk_account_io_completion", fn_name="do_count")

print("Tracing... Hit Ctrl-C to end.")

# trace until Ctrl-C
dist = b.get_table("dist")

try:
sleep(99999999)
except KeyboardInterrupt:
dist.print_log2_hist("Kbytes", "Process Name:")
92 changes: 92 additions & 0 deletions tools/bitesize_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Example of BCC tool bitesize.py

The aim of this tool is to show I/O distribution for requested block sizes, by process name.

# ./bitesize.py
Tracing... Hit Ctrl-C to end.
^C

Process Name: = 'kworker/u128:1'
Kbytes : count distribution
0 -> 1 : 1 |******************** |
2 -> 3 : 0 | |
4 -> 7 : 2 |****************************************|

Process Name: = 'bitesize.py'
Kbytes : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 0 | |
64 -> 127 : 0 | |
128 -> 255 : 1 |****************************************|

Process Name: = 'dd'
Kbytes : count distribution
0 -> 1 : 3 | |
2 -> 3 : 0 | |
4 -> 7 : 6 | |
8 -> 15 : 0 | |
16 -> 31 : 1 | |
32 -> 63 : 1 | |
64 -> 127 : 0 | |
128 -> 255 : 0 | |
256 -> 511 : 1 | |
512 -> 1023 : 0 | |
1024 -> 2047 : 488 |****************************************|

Process Name: = 'jbd2/dm-1-8'
Kbytes : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 1 |****************************************|

Process Name: = 'cat'
Kbytes : count distribution
0 -> 1 : 1 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 1 | |
64 -> 127 : 0 | |
128 -> 255 : 0 | |
256 -> 511 : 1924 |****************************************|

Process Name: = 'ntpd'
Kbytes : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 104 |****************************************|

Process Name: = 'vmtoolsd'
Kbytes : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 1 |****************************************|

Process Name: = 'bash'
Kbytes : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 2 |****************************************|

Process Name: = 'jbd2/sdb-8'
Kbytes : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 1 |****************************************|
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 1 |****************************************|

We can see from above that there was a dd command being run which generated 488 IOPS between 1MB and 2MB, we can also see the
cat command generating 1924 IOPS between 256Kb and 512Kb.


See also systemtap version:
https://github.com/brendangregg/systemtap-lwtools/blob/master/disk/bitesize-nd.stp