Skip to content

Commit

Permalink
add swapin
Browse files Browse the repository at this point in the history
  • Loading branch information
brendangregg authored and yonghong-song committed Sep 17, 2020
1 parent 12c234f commit da8c6a9
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ pair of .c and .py files, and some are directories of files.
- tools/[solisten](tools/solisten.py): Trace TCP socket listen. [Examples](tools/solisten_example.txt).
- tools/[sslsniff](tools/sslsniff.py): Sniff OpenSSL written and readed data. [Examples](tools/sslsniff_example.txt).
- tools/[stackcount](tools/stackcount.py): Count kernel function calls and their stack traces. [Examples](tools/stackcount_example.txt).
- tools/[swapin](tools/swapin.py): Count swapins by process. [Examples](tools/swapin_example.txt).
- tools/[syncsnoop](tools/syncsnoop.py): Trace sync() syscall. [Examples](tools/syncsnoop_example.txt).
- tools/[syscount](tools/syscount.py): Summarize syscall counts and latencies. [Examples](tools/syscount_example.txt).
- tools/[tcpaccept](tools/tcpaccept.py): Trace TCP passive connections (accept()). [Examples](tools/tcpaccept_example.txt).
Expand Down
58 changes: 58 additions & 0 deletions man/man8/swapin.8
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.TH swapin 8 "2019-07-05" "USER COMMANDS"
.SH NAME
swapin \- Count swapins by process. Uses BCC/eBPF.
.SH SYNOPSIS
.B swapin
.SH DESCRIPTION
This tool counts swapins by process, to show which process is affected by
swapping (if swap devices are in use). This can explain a significant source
of application latency, if it has began swapping due to memory pressure on
the system.

This works by tracing the swap_readpage() kernel funciton
using dynamic instrumentation. This tool may need maintenance to keep working
if that function changes in later kernels.

Since this uses BPF, only the root user can use this tool.
.SH REQUIREMENTS
CONFIG_BPF and BCC.
.SH EXAMPLES
.TP
Count swapins by process, showing per-second summaries.
#
.B swapin
.SH FIELDS
.TP
1st
The process name.
.TP
2nd
The process ID.
.TP
3rd
The count of swapins during that interval.
.SH OVERHEAD
The rate of swapins should be low (bounded by swapin device IOPS), such that
the overhead of this tool is expected to be negligible.
.SH SOURCE
This originated as a bpftrace tool from the book "BPF Performance Tools",
published by Addison Wesley (2019):
.IP
http:https://www.brendangregg.com/bpf-performance-tools-book.html
.PP
See the book for more documentation on this tool.
.PP
This version is in the BCC repository:
.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
Brendan Gregg
.SH SEE ALSO
swapon(8)
88 changes: 88 additions & 0 deletions tools/swapin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/python
# @lint-avoid-python-3-compatibility-imports
#
# swapin Count swapins by process.
# For Linux, uses BCC, eBPF. Embedded C.
#
# TODO: add -s for total swapin time column (sum)
#
# Copyright (c) 2019 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License").
# This was originally created for the BPF Performance Tools book
# published by Addison Wesley. ISBN-13: 9780136554820
# When copying or porting, include this comment.
#
# 03-Jul-2019 Brendan Gregg Ported from bpftrace to BCC.

from __future__ import print_function
from bcc import BPF
from time import sleep, strftime
import argparse

# arguments
parser = argparse.ArgumentParser(
description="Count swapin events by process.")
parser.add_argument("-T", "--notime", action="store_true",
help="do not show the timestamp (HH:MM:SS)")
parser.add_argument("interval", nargs="?", default=1,
help="output interval, in seconds")
parser.add_argument("count", nargs="?", default=99999999,
help="number of outputs")
parser.add_argument("--ebpf", action="store_true",
help=argparse.SUPPRESS)
args = parser.parse_args()
interval = int(args.interval)
countdown = int(args.count)
debug = 0

# load BPF program
b = BPF(text="""
#include <linux/sched.h>
struct key_t {
u32 pid;
char comm[TASK_COMM_LEN];
};
BPF_HASH(counts, struct key_t, u64);
int kprobe__swap_readpage(struct pt_regs *ctx)
{
u64 *val, zero = 0;
u32 tgid = bpf_get_current_pid_tgid() >> 32;
struct key_t key = {.pid = tgid};
bpf_get_current_comm(&key.comm, sizeof(key.comm));
val = counts.lookup_or_init(&key, &zero);
++(*val);
return 0;
}
""")
if debug or args.ebpf:
print(bpf_text)
if args.ebpf:
exit()

print("Counting swap ins. Ctrl-C to end.");

# output
exiting = 0
while 1:
try:
sleep(interval)
except KeyboardInterrupt:
exiting = 1

if not args.notime:
print(strftime("%H:%M:%S"))
print("%-16s %-6s %s" % ("COMM", "PID", "COUNT"))
counts = b.get_table("counts")
for k, v in sorted(counts.items(),
key=lambda counts: counts[1].value):
print("%-16s %-6d %d" % (k.comm, k.pid, v.value))
counts.clear()
print()

countdown -= 1
if exiting or countdown == 0:
print("Detaching...")
exit()
48 changes: 48 additions & 0 deletions tools/swapin_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Demonstrations of swapin, the Linux BCC/eBPF version.


This tool counts swapins by process, to show which process is affected by
swapping. For example:

# swapin.py
Counting swap ins. Ctrl-C to end.
13:36:58
COMM PID COUNT

13:36:59
COMM PID COUNT
gnome-shell 2239 12410

13:37:00
COMM PID COUNT
chrome 4536 14635

13:37:01
COMM PID COUNT
gnome-shell 2239 14
cron 1180 23

13:37:02
COMM PID COUNT
gnome-shell 2239 2496
[...]

While tracing, this showed that PID 2239 (gnome-shell) and PID 4536 (chrome)
suffered over ten thousand swapins.



USAGE:

# swapin.py -h
usage: swapin.py [-h] [-T] [interval] [count]

Count swapin events by process.

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

optional arguments:
-h, --help show this help message and exit
-T, --notime do not show the timestamp (HH:MM:SS)

0 comments on commit da8c6a9

Please sign in to comment.