xref: /aosp_15_r20/external/bcc/tools/swapin.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1#!/usr/bin/env python
2# @lint-avoid-python-3-compatibility-imports
3#
4# swapin        Count swapins by process.
5#               For Linux, uses BCC, eBPF. Embedded C.
6#
7# TODO: add -s for total swapin time column (sum)
8#
9# Copyright (c) 2019 Brendan Gregg.
10# Licensed under the Apache License, Version 2.0 (the "License").
11# This was originally created for the BPF Performance Tools book
12# published by Addison Wesley. ISBN-13: 9780136554820
13# When copying or porting, include this comment.
14#
15# 03-Jul-2019   Brendan Gregg   Ported from bpftrace to BCC.
16
17from __future__ import print_function
18from bcc import BPF
19from time import sleep, strftime
20import argparse
21
22# arguments
23parser = argparse.ArgumentParser(
24    description="Count swapin events by process.")
25parser.add_argument("-T", "--notime", action="store_true",
26    help="do not show the timestamp (HH:MM:SS)")
27parser.add_argument("interval", nargs="?", default=1,
28    help="output interval, in seconds")
29parser.add_argument("count", nargs="?", default=99999999,
30    help="number of outputs")
31parser.add_argument("--ebpf", action="store_true",
32    help=argparse.SUPPRESS)
33args = parser.parse_args()
34interval = int(args.interval)
35countdown = int(args.count)
36debug = 0
37
38# load BPF program
39b = BPF(text="""
40#include <linux/sched.h>
41
42struct key_t {
43    u32 pid;
44    char comm[TASK_COMM_LEN];
45};
46
47BPF_HASH(counts, struct key_t, u64);
48
49int kprobe__swap_readpage(struct pt_regs *ctx)
50{
51    u64 *val, zero = 0;
52    u32 tgid = bpf_get_current_pid_tgid() >> 32;
53    struct key_t key = {.pid = tgid};
54    bpf_get_current_comm(&key.comm, sizeof(key.comm));
55    val = counts.lookup_or_init(&key, &zero);
56    ++(*val);
57    return 0;
58}
59""")
60if debug or args.ebpf:
61    print(bpf_text)
62    if args.ebpf:
63        exit()
64
65print("Counting swap ins. Ctrl-C to end.");
66
67# output
68exiting = 0
69while 1:
70    try:
71        sleep(interval)
72    except KeyboardInterrupt:
73        exiting = 1
74
75    if not args.notime:
76        print(strftime("%H:%M:%S"))
77    print("%-16s %-7s %s" % ("COMM", "PID", "COUNT"))
78    counts = b.get_table("counts")
79    for k, v in sorted(counts.items(),
80		       key=lambda counts: counts[1].value):
81        print("%-16s %-7d %d" % (k.comm, k.pid, v.value))
82    counts.clear()
83    print()
84
85    countdown -= 1
86    if exiting or countdown == 0:
87        print("Detaching...")
88        exit()
89