xref: /aosp_15_r20/external/bcc/tools/xfsslower.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python
2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports
3*387f9dfdSAndroid Build Coastguard Worker#
4*387f9dfdSAndroid Build Coastguard Worker# xfsslower  Trace slow XFS operations.
5*387f9dfdSAndroid Build Coastguard Worker#            For Linux, uses BCC, eBPF.
6*387f9dfdSAndroid Build Coastguard Worker#
7*387f9dfdSAndroid Build Coastguard Worker# USAGE: xfsslower [-h] [-j] [-p PID] [min_ms]
8*387f9dfdSAndroid Build Coastguard Worker#
9*387f9dfdSAndroid Build Coastguard Worker# This script traces common XFS file operations: reads, writes, opens, and
10*387f9dfdSAndroid Build Coastguard Worker# syncs. It measures the time spent in these operations, and prints details
11*387f9dfdSAndroid Build Coastguard Worker# for each that exceeded a threshold.
12*387f9dfdSAndroid Build Coastguard Worker#
13*387f9dfdSAndroid Build Coastguard Worker# WARNING: This adds low-overhead instrumentation to these XFS operations,
14*387f9dfdSAndroid Build Coastguard Worker# including reads and writes from the file system cache. Such reads and writes
15*387f9dfdSAndroid Build Coastguard Worker# can be very frequent (depending on the workload; eg, 1M/sec), at which
16*387f9dfdSAndroid Build Coastguard Worker# point the overhead of this tool (even if it prints no "slower" events) can
17*387f9dfdSAndroid Build Coastguard Worker# begin to become significant.
18*387f9dfdSAndroid Build Coastguard Worker#
19*387f9dfdSAndroid Build Coastguard Worker# By default, a minimum millisecond threshold of 10 is used.
20*387f9dfdSAndroid Build Coastguard Worker#
21*387f9dfdSAndroid Build Coastguard Worker# Copyright 2016 Netflix, Inc.
22*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
23*387f9dfdSAndroid Build Coastguard Worker#
24*387f9dfdSAndroid Build Coastguard Worker# 11-Feb-2016   Brendan Gregg   Created this.
25*387f9dfdSAndroid Build Coastguard Worker# 16-Oct-2016   Dina Goldshtein -p to filter by process ID.
26*387f9dfdSAndroid Build Coastguard Worker
27*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
28*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
29*387f9dfdSAndroid Build Coastguard Workerimport argparse
30*387f9dfdSAndroid Build Coastguard Workerfrom time import strftime
31*387f9dfdSAndroid Build Coastguard Worker
32*387f9dfdSAndroid Build Coastguard Worker# arguments
33*387f9dfdSAndroid Build Coastguard Workerexamples = """examples:
34*387f9dfdSAndroid Build Coastguard Worker    ./xfsslower             # trace operations slower than 10 ms (default)
35*387f9dfdSAndroid Build Coastguard Worker    ./xfsslower 1           # trace operations slower than 1 ms
36*387f9dfdSAndroid Build Coastguard Worker    ./xfsslower -j 1        # ... 1 ms, parsable output (csv)
37*387f9dfdSAndroid Build Coastguard Worker    ./xfsslower 0           # trace all operations (warning: verbose)
38*387f9dfdSAndroid Build Coastguard Worker    ./xfsslower -p 185      # trace PID 185 only
39*387f9dfdSAndroid Build Coastguard Worker"""
40*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
41*387f9dfdSAndroid Build Coastguard Worker    description="Trace common XFS file operations slower than a threshold",
42*387f9dfdSAndroid Build Coastguard Worker    formatter_class=argparse.RawDescriptionHelpFormatter,
43*387f9dfdSAndroid Build Coastguard Worker    epilog=examples)
44*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-j", "--csv", action="store_true",
45*387f9dfdSAndroid Build Coastguard Worker    help="just print fields: comma-separated values")
46*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid",
47*387f9dfdSAndroid Build Coastguard Worker    help="trace this PID only")
48*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("min_ms", nargs="?", default='10',
49*387f9dfdSAndroid Build Coastguard Worker    help="minimum I/O duration to trace, in ms (default 10)")
50*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true",
51*387f9dfdSAndroid Build Coastguard Worker    help=argparse.SUPPRESS)
52*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
53*387f9dfdSAndroid Build Coastguard Workermin_ms = int(args.min_ms)
54*387f9dfdSAndroid Build Coastguard Workerpid = args.pid
55*387f9dfdSAndroid Build Coastguard Workercsv = args.csv
56*387f9dfdSAndroid Build Coastguard Workerdebug = 0
57*387f9dfdSAndroid Build Coastguard Worker
58*387f9dfdSAndroid Build Coastguard Worker# define BPF program
59*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
60*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
61*387f9dfdSAndroid Build Coastguard Worker#include <linux/fs.h>
62*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h>
63*387f9dfdSAndroid Build Coastguard Worker#include <linux/dcache.h>
64*387f9dfdSAndroid Build Coastguard Worker
65*387f9dfdSAndroid Build Coastguard Worker// XXX: switch these to char's when supported
66*387f9dfdSAndroid Build Coastguard Worker#define TRACE_READ      0
67*387f9dfdSAndroid Build Coastguard Worker#define TRACE_WRITE     1
68*387f9dfdSAndroid Build Coastguard Worker#define TRACE_OPEN      2
69*387f9dfdSAndroid Build Coastguard Worker#define TRACE_FSYNC     3
70*387f9dfdSAndroid Build Coastguard Worker
71*387f9dfdSAndroid Build Coastguard Workerstruct val_t {
72*387f9dfdSAndroid Build Coastguard Worker    u64 ts;
73*387f9dfdSAndroid Build Coastguard Worker    u64 offset;
74*387f9dfdSAndroid Build Coastguard Worker    struct file *fp;
75*387f9dfdSAndroid Build Coastguard Worker};
76*387f9dfdSAndroid Build Coastguard Worker
77*387f9dfdSAndroid Build Coastguard Workerstruct data_t {
78*387f9dfdSAndroid Build Coastguard Worker    // XXX: switch some to u32's when supported
79*387f9dfdSAndroid Build Coastguard Worker    u64 ts_us;
80*387f9dfdSAndroid Build Coastguard Worker    u64 type;
81*387f9dfdSAndroid Build Coastguard Worker    u64 size;
82*387f9dfdSAndroid Build Coastguard Worker    u64 offset;
83*387f9dfdSAndroid Build Coastguard Worker    u64 delta_us;
84*387f9dfdSAndroid Build Coastguard Worker    u32 pid;
85*387f9dfdSAndroid Build Coastguard Worker    char task[TASK_COMM_LEN];
86*387f9dfdSAndroid Build Coastguard Worker    char file[DNAME_INLINE_LEN];
87*387f9dfdSAndroid Build Coastguard Worker};
88*387f9dfdSAndroid Build Coastguard Worker
89*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(entryinfo, u64, struct val_t);
90*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(events);
91*387f9dfdSAndroid Build Coastguard Worker
92*387f9dfdSAndroid Build Coastguard Worker//
93*387f9dfdSAndroid Build Coastguard Worker// Store timestamp and size on entry
94*387f9dfdSAndroid Build Coastguard Worker//
95*387f9dfdSAndroid Build Coastguard Worker
96*387f9dfdSAndroid Build Coastguard Worker// xfs_file_read_iter(), xfs_file_write_iter():
97*387f9dfdSAndroid Build Coastguard Workerint trace_rw_entry(struct pt_regs *ctx, struct kiocb *iocb)
98*387f9dfdSAndroid Build Coastguard Worker{
99*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
100*387f9dfdSAndroid Build Coastguard Worker    u32 pid = id >> 32; // PID is higher part
101*387f9dfdSAndroid Build Coastguard Worker
102*387f9dfdSAndroid Build Coastguard Worker    if (FILTER_PID)
103*387f9dfdSAndroid Build Coastguard Worker        return 0;
104*387f9dfdSAndroid Build Coastguard Worker
105*387f9dfdSAndroid Build Coastguard Worker    // store filep and timestamp by id
106*387f9dfdSAndroid Build Coastguard Worker    struct val_t val = {};
107*387f9dfdSAndroid Build Coastguard Worker    val.ts = bpf_ktime_get_ns();
108*387f9dfdSAndroid Build Coastguard Worker    val.fp = iocb->ki_filp;
109*387f9dfdSAndroid Build Coastguard Worker    val.offset = iocb->ki_pos;
110*387f9dfdSAndroid Build Coastguard Worker    if (val.fp)
111*387f9dfdSAndroid Build Coastguard Worker        entryinfo.update(&id, &val);
112*387f9dfdSAndroid Build Coastguard Worker
113*387f9dfdSAndroid Build Coastguard Worker    return 0;
114*387f9dfdSAndroid Build Coastguard Worker}
115*387f9dfdSAndroid Build Coastguard Worker
116*387f9dfdSAndroid Build Coastguard Worker// xfs_file_open():
117*387f9dfdSAndroid Build Coastguard Workerint trace_open_entry(struct pt_regs *ctx, struct inode *inode,
118*387f9dfdSAndroid Build Coastguard Worker    struct file *file)
119*387f9dfdSAndroid Build Coastguard Worker{
120*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
121*387f9dfdSAndroid Build Coastguard Worker    u32 pid = id >> 32; // PID is higher part
122*387f9dfdSAndroid Build Coastguard Worker
123*387f9dfdSAndroid Build Coastguard Worker    if (FILTER_PID)
124*387f9dfdSAndroid Build Coastguard Worker        return 0;
125*387f9dfdSAndroid Build Coastguard Worker
126*387f9dfdSAndroid Build Coastguard Worker    // store filep and timestamp by id
127*387f9dfdSAndroid Build Coastguard Worker    struct val_t val = {};
128*387f9dfdSAndroid Build Coastguard Worker    val.ts = bpf_ktime_get_ns();
129*387f9dfdSAndroid Build Coastguard Worker    val.fp = file;
130*387f9dfdSAndroid Build Coastguard Worker    val.offset = 0;
131*387f9dfdSAndroid Build Coastguard Worker    if (val.fp)
132*387f9dfdSAndroid Build Coastguard Worker        entryinfo.update(&id, &val);
133*387f9dfdSAndroid Build Coastguard Worker
134*387f9dfdSAndroid Build Coastguard Worker    return 0;
135*387f9dfdSAndroid Build Coastguard Worker}
136*387f9dfdSAndroid Build Coastguard Worker
137*387f9dfdSAndroid Build Coastguard Worker// xfs_file_fsync():
138*387f9dfdSAndroid Build Coastguard Workerint trace_fsync_entry(struct pt_regs *ctx, struct file *file)
139*387f9dfdSAndroid Build Coastguard Worker{
140*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
141*387f9dfdSAndroid Build Coastguard Worker    u32 pid = id >> 32; // PID is higher part
142*387f9dfdSAndroid Build Coastguard Worker
143*387f9dfdSAndroid Build Coastguard Worker    if (FILTER_PID)
144*387f9dfdSAndroid Build Coastguard Worker        return 0;
145*387f9dfdSAndroid Build Coastguard Worker
146*387f9dfdSAndroid Build Coastguard Worker    // store filep and timestamp by id
147*387f9dfdSAndroid Build Coastguard Worker    struct val_t val = {};
148*387f9dfdSAndroid Build Coastguard Worker    val.ts = bpf_ktime_get_ns();
149*387f9dfdSAndroid Build Coastguard Worker    val.fp = file;
150*387f9dfdSAndroid Build Coastguard Worker    val.offset = 0;
151*387f9dfdSAndroid Build Coastguard Worker    if (val.fp)
152*387f9dfdSAndroid Build Coastguard Worker        entryinfo.update(&id, &val);
153*387f9dfdSAndroid Build Coastguard Worker
154*387f9dfdSAndroid Build Coastguard Worker    return 0;
155*387f9dfdSAndroid Build Coastguard Worker}
156*387f9dfdSAndroid Build Coastguard Worker
157*387f9dfdSAndroid Build Coastguard Worker//
158*387f9dfdSAndroid Build Coastguard Worker// Output
159*387f9dfdSAndroid Build Coastguard Worker//
160*387f9dfdSAndroid Build Coastguard Worker
161*387f9dfdSAndroid Build Coastguard Workerstatic int trace_return(struct pt_regs *ctx, int type)
162*387f9dfdSAndroid Build Coastguard Worker{
163*387f9dfdSAndroid Build Coastguard Worker    struct val_t *valp;
164*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
165*387f9dfdSAndroid Build Coastguard Worker    u32 pid = id >> 32; // PID is higher part
166*387f9dfdSAndroid Build Coastguard Worker
167*387f9dfdSAndroid Build Coastguard Worker    valp = entryinfo.lookup(&id);
168*387f9dfdSAndroid Build Coastguard Worker    if (valp == 0) {
169*387f9dfdSAndroid Build Coastguard Worker        // missed tracing issue or filtered
170*387f9dfdSAndroid Build Coastguard Worker        return 0;
171*387f9dfdSAndroid Build Coastguard Worker    }
172*387f9dfdSAndroid Build Coastguard Worker
173*387f9dfdSAndroid Build Coastguard Worker    // calculate delta
174*387f9dfdSAndroid Build Coastguard Worker    u64 ts = bpf_ktime_get_ns();
175*387f9dfdSAndroid Build Coastguard Worker    u64 delta_us = ts - valp->ts;
176*387f9dfdSAndroid Build Coastguard Worker    entryinfo.delete(&id);
177*387f9dfdSAndroid Build Coastguard Worker
178*387f9dfdSAndroid Build Coastguard Worker    // Skip entries with backwards time: temp workaround for #728
179*387f9dfdSAndroid Build Coastguard Worker    if ((s64) delta_us < 0)
180*387f9dfdSAndroid Build Coastguard Worker        return 0;
181*387f9dfdSAndroid Build Coastguard Worker
182*387f9dfdSAndroid Build Coastguard Worker    delta_us /= 1000;
183*387f9dfdSAndroid Build Coastguard Worker
184*387f9dfdSAndroid Build Coastguard Worker    if (FILTER_US)
185*387f9dfdSAndroid Build Coastguard Worker        return 0;
186*387f9dfdSAndroid Build Coastguard Worker
187*387f9dfdSAndroid Build Coastguard Worker    // populate output struct
188*387f9dfdSAndroid Build Coastguard Worker    u32 size = PT_REGS_RC(ctx);
189*387f9dfdSAndroid Build Coastguard Worker    struct data_t data = {};
190*387f9dfdSAndroid Build Coastguard Worker    data.type = type;
191*387f9dfdSAndroid Build Coastguard Worker    data.size = size;
192*387f9dfdSAndroid Build Coastguard Worker    data.delta_us = delta_us;
193*387f9dfdSAndroid Build Coastguard Worker    data.pid = pid;
194*387f9dfdSAndroid Build Coastguard Worker    data.ts_us = ts / 1000;
195*387f9dfdSAndroid Build Coastguard Worker    data.offset = valp->offset;
196*387f9dfdSAndroid Build Coastguard Worker    bpf_get_current_comm(&data.task, sizeof(data.task));
197*387f9dfdSAndroid Build Coastguard Worker
198*387f9dfdSAndroid Build Coastguard Worker    // workaround (rewriter should handle file to d_name in one step):
199*387f9dfdSAndroid Build Coastguard Worker    struct qstr qs = valp->fp->f_path.dentry->d_name;
200*387f9dfdSAndroid Build Coastguard Worker    if (qs.len == 0)
201*387f9dfdSAndroid Build Coastguard Worker        return 0;
202*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read_kernel(&data.file, sizeof(data.file), (void *)qs.name);
203*387f9dfdSAndroid Build Coastguard Worker
204*387f9dfdSAndroid Build Coastguard Worker    // output
205*387f9dfdSAndroid Build Coastguard Worker    events.perf_submit(ctx, &data, sizeof(data));
206*387f9dfdSAndroid Build Coastguard Worker
207*387f9dfdSAndroid Build Coastguard Worker    return 0;
208*387f9dfdSAndroid Build Coastguard Worker}
209*387f9dfdSAndroid Build Coastguard Worker
210*387f9dfdSAndroid Build Coastguard Workerint trace_read_return(struct pt_regs *ctx)
211*387f9dfdSAndroid Build Coastguard Worker{
212*387f9dfdSAndroid Build Coastguard Worker    return trace_return(ctx, TRACE_READ);
213*387f9dfdSAndroid Build Coastguard Worker}
214*387f9dfdSAndroid Build Coastguard Worker
215*387f9dfdSAndroid Build Coastguard Workerint trace_write_return(struct pt_regs *ctx)
216*387f9dfdSAndroid Build Coastguard Worker{
217*387f9dfdSAndroid Build Coastguard Worker    return trace_return(ctx, TRACE_WRITE);
218*387f9dfdSAndroid Build Coastguard Worker}
219*387f9dfdSAndroid Build Coastguard Worker
220*387f9dfdSAndroid Build Coastguard Workerint trace_open_return(struct pt_regs *ctx)
221*387f9dfdSAndroid Build Coastguard Worker{
222*387f9dfdSAndroid Build Coastguard Worker    return trace_return(ctx, TRACE_OPEN);
223*387f9dfdSAndroid Build Coastguard Worker}
224*387f9dfdSAndroid Build Coastguard Worker
225*387f9dfdSAndroid Build Coastguard Workerint trace_fsync_return(struct pt_regs *ctx)
226*387f9dfdSAndroid Build Coastguard Worker{
227*387f9dfdSAndroid Build Coastguard Worker    return trace_return(ctx, TRACE_FSYNC);
228*387f9dfdSAndroid Build Coastguard Worker}
229*387f9dfdSAndroid Build Coastguard Worker
230*387f9dfdSAndroid Build Coastguard Worker"""
231*387f9dfdSAndroid Build Coastguard Workerif min_ms == 0:
232*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER_US', '0')
233*387f9dfdSAndroid Build Coastguard Workerelse:
234*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER_US',
235*387f9dfdSAndroid Build Coastguard Worker        'delta_us <= %s' % str(min_ms * 1000))
236*387f9dfdSAndroid Build Coastguard Workerif args.pid:
237*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
238*387f9dfdSAndroid Build Coastguard Workerelse:
239*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace('FILTER_PID', '0')
240*387f9dfdSAndroid Build Coastguard Workerif debug or args.ebpf:
241*387f9dfdSAndroid Build Coastguard Worker    print(bpf_text)
242*387f9dfdSAndroid Build Coastguard Worker    if args.ebpf:
243*387f9dfdSAndroid Build Coastguard Worker        exit()
244*387f9dfdSAndroid Build Coastguard Worker
245*387f9dfdSAndroid Build Coastguard Worker# process event
246*387f9dfdSAndroid Build Coastguard Workerdef print_event(cpu, data, size):
247*387f9dfdSAndroid Build Coastguard Worker    event = b["events"].event(data)
248*387f9dfdSAndroid Build Coastguard Worker
249*387f9dfdSAndroid Build Coastguard Worker    type = 'R'
250*387f9dfdSAndroid Build Coastguard Worker    if event.type == 1:
251*387f9dfdSAndroid Build Coastguard Worker        type = 'W'
252*387f9dfdSAndroid Build Coastguard Worker    elif event.type == 2:
253*387f9dfdSAndroid Build Coastguard Worker        type = 'O'
254*387f9dfdSAndroid Build Coastguard Worker    elif event.type == 3:
255*387f9dfdSAndroid Build Coastguard Worker        type = 'S'
256*387f9dfdSAndroid Build Coastguard Worker
257*387f9dfdSAndroid Build Coastguard Worker    if (csv):
258*387f9dfdSAndroid Build Coastguard Worker        print("%d,%s,%d,%s,%d,%d,%d,%s" % (
259*387f9dfdSAndroid Build Coastguard Worker            event.ts_us, event.task, event.pid, type, event.size,
260*387f9dfdSAndroid Build Coastguard Worker            event.offset, event.delta_us, event.file))
261*387f9dfdSAndroid Build Coastguard Worker        return
262*387f9dfdSAndroid Build Coastguard Worker    print("%-8s %-14.14s %-6s %1s %-7s %-8d %7.2f %s" % (strftime("%H:%M:%S"),
263*387f9dfdSAndroid Build Coastguard Worker        event.task, event.pid, type, event.size, event.offset / 1024,
264*387f9dfdSAndroid Build Coastguard Worker        float(event.delta_us) / 1000, event.file))
265*387f9dfdSAndroid Build Coastguard Worker
266*387f9dfdSAndroid Build Coastguard Worker# initialize BPF
267*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
268*387f9dfdSAndroid Build Coastguard Worker
269*387f9dfdSAndroid Build Coastguard Worker# common file functions
270*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="xfs_file_read_iter", fn_name="trace_rw_entry")
271*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="xfs_file_write_iter", fn_name="trace_rw_entry")
272*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="xfs_file_open", fn_name="trace_open_entry")
273*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="xfs_file_fsync", fn_name="trace_fsync_entry")
274*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="xfs_file_read_iter", fn_name="trace_read_return")
275*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="xfs_file_write_iter", fn_name="trace_write_return")
276*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="xfs_file_open", fn_name="trace_open_return")
277*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="xfs_file_fsync", fn_name="trace_fsync_return")
278*387f9dfdSAndroid Build Coastguard Worker
279*387f9dfdSAndroid Build Coastguard Worker# header
280*387f9dfdSAndroid Build Coastguard Workerif (csv):
281*387f9dfdSAndroid Build Coastguard Worker    print("ENDTIME_us,TASK,PID,TYPE,BYTES,OFFSET_b,LATENCY_us,FILE")
282*387f9dfdSAndroid Build Coastguard Workerelse:
283*387f9dfdSAndroid Build Coastguard Worker    if min_ms == 0:
284*387f9dfdSAndroid Build Coastguard Worker        print("Tracing XFS operations")
285*387f9dfdSAndroid Build Coastguard Worker    else:
286*387f9dfdSAndroid Build Coastguard Worker        print("Tracing XFS operations slower than %d ms" % min_ms)
287*387f9dfdSAndroid Build Coastguard Worker    print("%-8s %-14s %-6s %1s %-7s %-8s %7s %s" % ("TIME", "COMM", "PID", "T",
288*387f9dfdSAndroid Build Coastguard Worker        "BYTES", "OFF_KB", "LAT(ms)", "FILENAME"))
289*387f9dfdSAndroid Build Coastguard Worker
290*387f9dfdSAndroid Build Coastguard Worker# read events
291*387f9dfdSAndroid Build Coastguard Workerb["events"].open_perf_buffer(print_event, page_cnt=64)
292*387f9dfdSAndroid Build Coastguard Workerwhile 1:
293*387f9dfdSAndroid Build Coastguard Worker    try:
294*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
295*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
296*387f9dfdSAndroid Build Coastguard Worker        exit()
297