Skip to content

Commit

Permalink
tools: Add pid filter option (-p PID) for biotop & cachetop
Browse files Browse the repository at this point in the history
  • Loading branch information
xingfeng2510 authored and yonghong-song committed Mar 21, 2022
1 parent 065ec13 commit 14dacd8
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
7 changes: 5 additions & 2 deletions man/man8/biotop.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.SH NAME
biotop \- Block device (disk) I/O by process top.
.SH SYNOPSIS
.B biotop [\-h] [\-C] [\-r MAXROWS] [interval] [count]
.B biotop [\-h] [\-C] [\-r MAXROWS] [\-p PID] [interval] [count]
.SH DESCRIPTION
This is top for disks.

Expand Down Expand Up @@ -30,6 +30,9 @@ Don't clear the screen.
\-r MAXROWS
Maximum number of rows to print. Default is 20.
.TP
\-p PID
Trace this PID only.
.TP
interval
Interval between updates, seconds.
.TP
Expand Down Expand Up @@ -98,7 +101,7 @@ Linux
.SH STABILITY
Unstable - in development.
.SH AUTHOR
Brendan Gregg
Brendan Gregg, Rocky Xing
.SH INSPIRATION
top(1) by William LeFebvre
.SH SEE ALSO
Expand Down
8 changes: 6 additions & 2 deletions man/man8/cachetop.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.SH NAME
cachetop \- Statistics for linux page cache hit/miss ratios per processes. Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B cachetop
.B cachetop [\-p PID]
[interval]
.SH DESCRIPTION
This traces four kernel functions and prints per-processes summaries every
Expand All @@ -15,6 +15,10 @@ need updating to match any changes to these functions. Edit the script to
customize which functions are traced.

Since this uses BPF, only the root user can use this tool.
.SH OPTIONS
.TP
\-p PID
Trace this PID only.
.SH KEYBINDINGS
The following keybindings can be used to control the output of \fBcachetop\fR.
.TP
Expand Down Expand Up @@ -86,6 +90,6 @@ Linux
.SH STABILITY
Unstable - in development.
.SH AUTHOR
Emmanuel Bretelle
Emmanuel Bretelle, Rocky Xing
.SH SEE ALSO
cachestat (8)
31 changes: 28 additions & 3 deletions tools/biotop.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# biotop block device (disk) I/O by process.
# For Linux, uses BCC, eBPF.
#
# USAGE: biotop.py [-h] [-C] [-r MAXROWS] [interval] [count]
# USAGE: biotop.py [-h] [-C] [-r MAXROWS] [-p PID] [interval] [count]
#
# This uses in-kernel eBPF maps to cache process details (PID and comm) by I/O
# request, as well as a starting timestamp for calculating I/O latency.
Expand All @@ -13,6 +13,7 @@
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 06-Feb-2016 Brendan Gregg Created this.
# 17-Mar-2022 Rocky Xing Added PID filter support.

from __future__ import print_function
from bcc import BPF
Expand All @@ -24,6 +25,7 @@
examples = """examples:
./biotop # block device I/O top, 1 second refresh
./biotop -C # don't clear the screen
./biotop -p 181 # only trace PID 181
./biotop 5 # 5 second summaries
./biotop 5 10 # 5 second summaries, 10 times only
"""
Expand All @@ -35,6 +37,8 @@
help="don't clear the screen")
parser.add_argument("-r", "--maxrows", default=20,
help="maximum rows to print, default 20")
parser.add_argument("-p", "--pid", type=int, metavar="PID",
help="trace this PID only")
parser.add_argument("interval", nargs="?", default=1,
help="output interval, in seconds")
parser.add_argument("count", nargs="?", default=99999999,
Expand Down Expand Up @@ -92,9 +96,14 @@
int trace_pid_start(struct pt_regs *ctx, struct request *req)
{
struct who_t who = {};
u32 pid;
if (bpf_get_current_comm(&who.name, sizeof(who.name)) == 0) {
who.pid = bpf_get_current_pid_tgid() >> 32;
pid = bpf_get_current_pid_tgid() >> 32;
if (FILTER_PID)
return 0;
who.pid = pid;
whobyreq.update(&req, &who);
}
Expand Down Expand Up @@ -124,6 +133,18 @@
}
struct who_t *whop;
u32 pid;
whop = whobyreq.lookup(&req);
pid = whop != 0 ? whop->pid : 0;
if (FILTER_PID) {
start.delete(&req);
if (whop != 0) {
whobyreq.delete(&req);
}
return 0;
}
struct val_t *valp, zero = {};
u64 delta_us = (bpf_ktime_get_ns() - startp->ts) / 1000;
Expand All @@ -146,7 +167,6 @@
info.rwflag = !!((req->cmd_flags & REQ_OP_MASK) == REQ_OP_WRITE);
#endif
whop = whobyreq.lookup(&req);
if (whop == 0) {
// missed pid who, save stats as pid 0
valp = counts.lookup_or_try_init(&info, &zero);
Expand Down Expand Up @@ -179,6 +199,11 @@
else:
bpf_text = bpf_text.replace('__RQ_DISK__', 'q->disk')

if args.pid is not None:
bpf_text = bpf_text.replace('FILTER_PID', 'pid != %d' % args.pid)
else:
bpf_text = bpf_text.replace('FILTER_PID', '0')

b = BPF(text=bpf_text)
if BPF.get_kprobe_functions(b'__blk_account_io_start'):
b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start")
Expand Down
18 changes: 15 additions & 3 deletions tools/cachetop.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 13-Jul-2016 Emmanuel Bretelle first version
# 17-Mar-2022 Rocky Xing Added PID filter support.

from __future__ import absolute_import
from __future__ import division
Expand Down Expand Up @@ -152,12 +153,15 @@ def handle_loop(stdscr, args):
BPF_HASH(counts, struct key_t);
int do_count(struct pt_regs *ctx) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
if (FILTER_PID)
return 0;
struct key_t key = {};
u64 pid = bpf_get_current_pid_tgid();
u32 uid = bpf_get_current_uid_gid();
key.ip = PT_REGS_IP(ctx);
key.pid = pid >> 32;
key.pid = pid;
key.uid = uid;
bpf_get_current_comm(&(key.comm), 16);
Expand All @@ -166,6 +170,12 @@ def handle_loop(stdscr, args):
}
"""

if args.pid:
bpf_text = bpf_text.replace('FILTER_PID', 'pid != %d' % args.pid)
else:
bpf_text = bpf_text.replace('FILTER_PID', '0')

b = BPF(text=bpf_text)
b.attach_kprobe(event="add_to_page_cache_lru", fn_name="do_count")
b.attach_kprobe(event="mark_page_accessed", fn_name="do_count")
Expand Down Expand Up @@ -251,9 +261,11 @@ def handle_loop(stdscr, args):

def parse_arguments():
parser = argparse.ArgumentParser(
description='show Linux page cache hit/miss statistics including read '
description='Show Linux page cache hit/miss statistics including read '
'and write hit % per processes in a UI like top.'
)
parser.add_argument("-p", "--pid", type=int, metavar="PID",
help="trace this PID only")
parser.add_argument(
'interval', type=int, default=5, nargs='?',
help='Interval between probes.'
Expand Down

0 comments on commit 14dacd8

Please sign in to comment.