Skip to content

Commit

Permalink
tools/biolatency: Add disk filter support (iovisor#4026)
Browse files Browse the repository at this point in the history
Sometimes, I just want to focus on a specified disk rather than all disks or per-disk. Refer to libbpf-tools/biolatency, this patch try to add disk filter support.
  • Loading branch information
xingfeng2510 committed Jun 3, 2022
1 parent 65efffe commit ae680db
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 15 deletions.
7 changes: 5 additions & 2 deletions man/man8/biolatency.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.SH NAME
biolatency \- Summarize block device I/O latency as a histogram.
.SH SYNOPSIS
.B biolatency [\-h] [\-F] [\-T] [\-Q] [\-m] [\-D] [\-e] [interval [count]]
.B biolatency [\-h] [\-F] [\-T] [\-Q] [\-m] [\-D] [\-F] [\-e] [\-j] [\-d DISK] [interval [count]]
.SH DESCRIPTION
biolatency traces block device I/O (disk I/O), and records the distribution
of I/O latency (time). This is printed as a histogram either on Ctrl-C, or
Expand Down Expand Up @@ -42,6 +42,9 @@ Print a histogram dictionary
\-e
Show extension summary(total, average)
.TP
\-d DISK
Trace this disk only
.TP
interval
Output interval, in seconds.
.TP
Expand Down Expand Up @@ -108,6 +111,6 @@ Linux
.SH STABILITY
Unstable - in development.
.SH AUTHOR
Brendan Gregg
Brendan Gregg, Rocky Xing
.SH SEE ALSO
biosnoop(8)
36 changes: 35 additions & 1 deletion tools/biolatency.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@
# biolatency Summarize block device I/O latency as a histogram.
# For Linux, uses BCC, eBPF.
#
# USAGE: biolatency [-h] [-T] [-Q] [-m] [-D] [-F] [-e] [-j] [interval] [count]
# USAGE: biolatency [-h] [-T] [-Q] [-m] [-D] [-F] [-e] [-j] [-d DISK] [interval] [count]
#
# Copyright (c) 2015 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 20-Sep-2015 Brendan Gregg Created this.
# 31-Mar-2022 Rocky Xing Added disk filter support.

from __future__ import print_function
from bcc import BPF
from time import sleep, strftime
import argparse
import ctypes as ct
import os

# arguments
examples = """examples:
Expand All @@ -27,6 +29,7 @@
./biolatency -F # show I/O flags separately
./biolatency -j # print a dictionary
./biolatency -e # show extension summary(total, average)
./biolatency -d sdc # Trace sdc only
"""
parser = argparse.ArgumentParser(
description="Summarize block device I/O latency as a histogram",
Expand All @@ -52,6 +55,8 @@
help=argparse.SUPPRESS)
parser.add_argument("-j", "--json", action="store_true",
help="json output")
parser.add_argument("-d", "--disk", type=str,
help="Trace this disk only")

args = parser.parse_args()
countdown = int(args.count)
Expand Down Expand Up @@ -87,6 +92,8 @@
// time block I/O
int trace_req_start(struct pt_regs *ctx, struct request *req)
{
DISK_FILTER
u64 ts = bpf_ktime_get_ns();
start.update(&req, &ts);
return 0;
Expand Down Expand Up @@ -149,6 +156,33 @@
storage_str += "BPF_HISTOGRAM(dist);"
store_str += "dist.atomic_increment(bpf_log2l(delta));"

if args.disk is not None:
disk_path = os.path.join('/dev', args.disk)
if not os.path.exists(disk_path):
print("no such disk '%s'" % args.disk)
exit(1)

stat_info = os.stat(disk_path)
major = os.major(stat_info.st_rdev)
minor = os.minor(stat_info.st_rdev)

disk_field_str = ""
if BPF.kernel_struct_has_field(b'request', b'rq_disk') == 1:
disk_field_str = 'req->rq_disk'
else:
disk_field_str = 'req->q->disk'

disk_filter_str = """
struct gendisk *disk = %s;
if (!(disk->major == %d && disk->first_minor == %d)) {
return 0;
}
""" % (disk_field_str, major, minor)

bpf_text = bpf_text.replace('DISK_FILTER', disk_filter_str)
else:
bpf_text = bpf_text.replace('DISK_FILTER', '')

if args.extension:
storage_str += "BPF_ARRAY(extension, ext_val_t, 1);"
bpf_text = bpf_text.replace('EXTENSION', """
Expand Down
26 changes: 14 additions & 12 deletions tools/biolatency_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -352,24 +352,25 @@ The -j with -m prints a millisecond histogram dictionary. The `value_type` key i
USAGE message:

# ./biolatency -h
usage: biolatency.py [-h] [-T] [-Q] [-m] [-D] [-F] [-j]
[interval] [count]
usage: biolatency.py [-h] [-T] [-Q] [-m] [-D] [-F] [-e] [-j] [-d DISK]
[interval] [count]

Summarize block device I/O latency as a histogram

positional arguments:
interval output interval, in seconds
count number of outputs
interval output interval, in seconds
count number of outputs

optional arguments:
-h, --help show this help message and exit
-T, --timestamp include timestamp on output
-Q, --queued include OS queued time in I/O time
-m, --milliseconds millisecond histogram
-D, --disks print a histogram per disk device
-F, --flags print a histogram per set of I/O flags
-e, --extension also show extension summary(total, average)
-j, --json json output
-h, --help show this help message and exit
-T, --timestamp include timestamp on output
-Q, --queued include OS queued time in I/O time
-m, --milliseconds millisecond histogram
-D, --disks print a histogram per disk device
-F, --flags print a histogram per set of I/O flags
-e, --extension summarize average/total value
-j, --json json output
-d DISK, --disk DISK Trace this disk only

examples:
./biolatency # summarize block I/O latency as a histogram
Expand All @@ -380,3 +381,4 @@ examples:
./biolatency -F # show I/O flags separately
./biolatency -j # print a dictionary
./biolatency -e # show extension summary(total, average)
./biolatency -d sdc # Trace sdc only

0 comments on commit ae680db

Please sign in to comment.