xref: /aosp_15_r20/external/bcc/tools/old/compactsnoop.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports
3*387f9dfdSAndroid Build Coastguard Worker#
4*387f9dfdSAndroid Build Coastguard Worker# compactsnoop  Trace compact zone and print details including issuing PID.
5*387f9dfdSAndroid Build Coastguard Worker#       For Linux, uses BCC, eBPF.
6*387f9dfdSAndroid Build Coastguard Worker#
7*387f9dfdSAndroid Build Coastguard Worker# This uses in-kernel eBPF maps to cache process details (PID and comm) by
8*387f9dfdSAndroid Build Coastguard Worker# compact zone begin, as well as a starting timestamp for calculating
9*387f9dfdSAndroid Build Coastguard Worker# latency.
10*387f9dfdSAndroid Build Coastguard Worker#
11*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2019 Wenbo Zhang
12*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
13*387f9dfdSAndroid Build Coastguard Worker#
14*387f9dfdSAndroid Build Coastguard Worker# 11-NOV-2019   Wenbo Zhang   Created this.
15*387f9dfdSAndroid Build Coastguard Worker
16*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
17*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
18*387f9dfdSAndroid Build Coastguard Workerimport argparse
19*387f9dfdSAndroid Build Coastguard Workerimport platform
20*387f9dfdSAndroid Build Coastguard Workerfrom datetime import datetime, timedelta
21*387f9dfdSAndroid Build Coastguard Worker
22*387f9dfdSAndroid Build Coastguard Worker# arguments
23*387f9dfdSAndroid Build Coastguard Workerexamples = """examples:
24*387f9dfdSAndroid Build Coastguard Worker    ./compactsnoop          # trace all compact stall
25*387f9dfdSAndroid Build Coastguard Worker    ./compactsnoop -T       # include timestamps
26*387f9dfdSAndroid Build Coastguard Worker    ./compactsnoop -d 10    # trace for 10 seconds only
27*387f9dfdSAndroid Build Coastguard Worker    ./compactsnoop -K       # output kernel stack trace
28*387f9dfdSAndroid Build Coastguard Worker    ./compactsnoop -e       # show extended fields
29*387f9dfdSAndroid Build Coastguard Worker"""
30*387f9dfdSAndroid Build Coastguard Worker
31*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
32*387f9dfdSAndroid Build Coastguard Worker    description="Trace compact zone",
33*387f9dfdSAndroid Build Coastguard Worker    formatter_class=argparse.RawDescriptionHelpFormatter,
34*387f9dfdSAndroid Build Coastguard Worker    epilog=examples,
35*387f9dfdSAndroid Build Coastguard Worker)
36*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-T", "--timestamp", action="store_true",
37*387f9dfdSAndroid Build Coastguard Worker                    help="include timestamp on output")
38*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", help="trace this PID only")
39*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-d", "--duration",
40*387f9dfdSAndroid Build Coastguard Worker                    help="total duration of trace in seconds")
41*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-K", "--kernel-stack", action="store_true",
42*387f9dfdSAndroid Build Coastguard Worker                    help="output kernel stack trace")
43*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-e", "--extended_fields", action="store_true",
44*387f9dfdSAndroid Build Coastguard Worker                    help="show system memory state")
45*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true", help=argparse.SUPPRESS)
46*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
47*387f9dfdSAndroid Build Coastguard Workerdebug = 0
48*387f9dfdSAndroid Build Coastguard Workerif args.duration:
49*387f9dfdSAndroid Build Coastguard Worker    args.duration = timedelta(seconds=int(args.duration))
50*387f9dfdSAndroid Build Coastguard Worker
51*387f9dfdSAndroid Build Coastguard WorkerNO_EXTENDED = """
52*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
53*387f9dfdSAndroid Build Coastguard Worker#undef EXTNEDED_FIELDS
54*387f9dfdSAndroid Build Coastguard Worker#endif
55*387f9dfdSAndroid Build Coastguard Worker"""
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard WorkerEXTENDED = """
58*387f9dfdSAndroid Build Coastguard Worker#define EXTNEDED_FIELDS    1
59*387f9dfdSAndroid Build Coastguard Worker"""
60*387f9dfdSAndroid Build Coastguard Worker
61*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
62*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
63*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h>
64*387f9dfdSAndroid Build Coastguard Worker#include <linux/mmzone.h>
65*387f9dfdSAndroid Build Coastguard Workerstruct node;
66*387f9dfdSAndroid Build Coastguard Worker#include <linux/compaction.h>
67*387f9dfdSAndroid Build Coastguard Worker
68*387f9dfdSAndroid Build Coastguard Workerstruct compact_control {
69*387f9dfdSAndroid Build Coastguard Worker    struct list_head freepages;     /* List of free pages to migrate to */
70*387f9dfdSAndroid Build Coastguard Worker    struct list_head migratepages;  /* List of pages being migrated */
71*387f9dfdSAndroid Build Coastguard Worker    unsigned long nr_freepages;     /* Number of isolated free pages */
72*387f9dfdSAndroid Build Coastguard Worker    unsigned long nr_migratepages;  /* Number of pages to migrate */
73*387f9dfdSAndroid Build Coastguard Worker    unsigned long free_pfn;         /* isolate_freepages search base */
74*387f9dfdSAndroid Build Coastguard Worker    unsigned long migrate_pfn;      /* isolate_migratepages search base */
75*387f9dfdSAndroid Build Coastguard Worker    bool sync;                      /* Synchronous migration */
76*387f9dfdSAndroid Build Coastguard Worker};
77*387f9dfdSAndroid Build Coastguard Worker
78*387f9dfdSAndroid Build Coastguard Workerstruct val_t {
79*387f9dfdSAndroid Build Coastguard Worker    int nid;
80*387f9dfdSAndroid Build Coastguard Worker    int idx;
81*387f9dfdSAndroid Build Coastguard Worker    int order;
82*387f9dfdSAndroid Build Coastguard Worker    int sync;
83*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
84*387f9dfdSAndroid Build Coastguard Worker    int fragindex;
85*387f9dfdSAndroid Build Coastguard Worker    int low;
86*387f9dfdSAndroid Build Coastguard Worker    int min;
87*387f9dfdSAndroid Build Coastguard Worker    int high;
88*387f9dfdSAndroid Build Coastguard Worker    int free;
89*387f9dfdSAndroid Build Coastguard Worker#endif
90*387f9dfdSAndroid Build Coastguard Worker    u64 ts;    // compaction begin time
91*387f9dfdSAndroid Build Coastguard Worker};
92*387f9dfdSAndroid Build Coastguard Worker
93*387f9dfdSAndroid Build Coastguard Workerstruct data_t {
94*387f9dfdSAndroid Build Coastguard Worker    u32 pid;
95*387f9dfdSAndroid Build Coastguard Worker    u32 tid;
96*387f9dfdSAndroid Build Coastguard Worker    int nid;
97*387f9dfdSAndroid Build Coastguard Worker    int idx;
98*387f9dfdSAndroid Build Coastguard Worker    int order;
99*387f9dfdSAndroid Build Coastguard Worker    u64 delta;
100*387f9dfdSAndroid Build Coastguard Worker    u64 ts;    // compaction end time
101*387f9dfdSAndroid Build Coastguard Worker    int sync;
102*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
103*387f9dfdSAndroid Build Coastguard Worker    int fragindex;
104*387f9dfdSAndroid Build Coastguard Worker    int low;
105*387f9dfdSAndroid Build Coastguard Worker    int min;
106*387f9dfdSAndroid Build Coastguard Worker    int high;
107*387f9dfdSAndroid Build Coastguard Worker    int free;
108*387f9dfdSAndroid Build Coastguard Worker#endif
109*387f9dfdSAndroid Build Coastguard Worker    int status;
110*387f9dfdSAndroid Build Coastguard Worker    int stack_id;
111*387f9dfdSAndroid Build Coastguard Worker    char comm[TASK_COMM_LEN];
112*387f9dfdSAndroid Build Coastguard Worker};
113*387f9dfdSAndroid Build Coastguard Worker
114*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start, u64, struct val_t);
115*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(events);
116*387f9dfdSAndroid Build Coastguard WorkerBPF_STACK_TRACE(stack_traces, 2048);
117*387f9dfdSAndroid Build Coastguard Worker
118*387f9dfdSAndroid Build Coastguard Worker#ifdef CONFIG_NUMA
119*387f9dfdSAndroid Build Coastguard Workerstatic inline int zone_to_nid_(struct zone *zone)
120*387f9dfdSAndroid Build Coastguard Worker{
121*387f9dfdSAndroid Build Coastguard Worker    int node;
122*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read(&node, sizeof(node), &zone->node);
123*387f9dfdSAndroid Build Coastguard Worker    return node;
124*387f9dfdSAndroid Build Coastguard Worker}
125*387f9dfdSAndroid Build Coastguard Worker#else
126*387f9dfdSAndroid Build Coastguard Workerstatic inline int zone_to_nid_(struct zone *zone)
127*387f9dfdSAndroid Build Coastguard Worker{
128*387f9dfdSAndroid Build Coastguard Worker    return 0;
129*387f9dfdSAndroid Build Coastguard Worker}
130*387f9dfdSAndroid Build Coastguard Worker#endif
131*387f9dfdSAndroid Build Coastguard Worker
132*387f9dfdSAndroid Build Coastguard Worker// #define zone_idx(zone) ((zone) - (zone)->zone_pgdat->node_zones)
133*387f9dfdSAndroid Build Coastguard Workerstatic inline int zone_idx_(struct zone *zone)
134*387f9dfdSAndroid Build Coastguard Worker{
135*387f9dfdSAndroid Build Coastguard Worker    struct pglist_data *zone_pgdat = NULL;
136*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read(&zone_pgdat, sizeof(zone_pgdat), &zone->zone_pgdat);
137*387f9dfdSAndroid Build Coastguard Worker    return zone - zone_pgdat->node_zones;
138*387f9dfdSAndroid Build Coastguard Worker}
139*387f9dfdSAndroid Build Coastguard Worker
140*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
141*387f9dfdSAndroid Build Coastguard Workerstatic inline void get_all_wmark_pages(struct zone *zone, struct val_t *valp)
142*387f9dfdSAndroid Build Coastguard Worker{
143*387f9dfdSAndroid Build Coastguard Worker    u64 watermark[NR_WMARK] = {};
144*387f9dfdSAndroid Build Coastguard Worker    u64 watermark_boost = 0;
145*387f9dfdSAndroid Build Coastguard Worker
146*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read(&watermark, sizeof(watermark), &zone->watermark);
147*387f9dfdSAndroid Build Coastguard Worker    valp->min = watermark[WMARK_MIN];
148*387f9dfdSAndroid Build Coastguard Worker    valp->low = watermark[WMARK_LOW];
149*387f9dfdSAndroid Build Coastguard Worker    valp->high = watermark[WMARK_HIGH];
150*387f9dfdSAndroid Build Coastguard Worker    bpf_probe_read(&valp->free, sizeof(valp->free),
151*387f9dfdSAndroid Build Coastguard Worker                   &zone->vm_stat[NR_FREE_PAGES]);
152*387f9dfdSAndroid Build Coastguard Worker}
153*387f9dfdSAndroid Build Coastguard Worker#endif
154*387f9dfdSAndroid Build Coastguard Worker
155*387f9dfdSAndroid Build Coastguard Workerint trace_compact_zone_entry(struct pt_regs *ctx, struct zone *zone,
156*387f9dfdSAndroid Build Coastguard Worker                             struct compact_control *cc)
157*387f9dfdSAndroid Build Coastguard Worker{
158*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
159*387f9dfdSAndroid Build Coastguard Worker    struct val_t val = { .fragindex=-1000 };
160*387f9dfdSAndroid Build Coastguard Worker#else
161*387f9dfdSAndroid Build Coastguard Worker    struct val_t val = { };
162*387f9dfdSAndroid Build Coastguard Worker#endif
163*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
164*387f9dfdSAndroid Build Coastguard Worker    PID_FILTER
165*387f9dfdSAndroid Build Coastguard Worker    val.sync = cc->sync;
166*387f9dfdSAndroid Build Coastguard Worker    start.update(&id, &val);
167*387f9dfdSAndroid Build Coastguard Worker    return 0;
168*387f9dfdSAndroid Build Coastguard Worker}
169*387f9dfdSAndroid Build Coastguard Worker
170*387f9dfdSAndroid Build Coastguard Workerint trace_compaction_suitable_entry(struct pt_regs *ctx, struct zone *zone,
171*387f9dfdSAndroid Build Coastguard Worker                                    int order)
172*387f9dfdSAndroid Build Coastguard Worker{
173*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
174*387f9dfdSAndroid Build Coastguard Worker    struct val_t *valp = start.lookup(&id);
175*387f9dfdSAndroid Build Coastguard Worker    if (valp == NULL) {
176*387f9dfdSAndroid Build Coastguard Worker        // missed entry
177*387f9dfdSAndroid Build Coastguard Worker        return 0;
178*387f9dfdSAndroid Build Coastguard Worker    }
179*387f9dfdSAndroid Build Coastguard Worker    valp->nid = zone_to_nid_(zone);
180*387f9dfdSAndroid Build Coastguard Worker    valp->idx = zone_idx_(zone);
181*387f9dfdSAndroid Build Coastguard Worker    valp->order = order;
182*387f9dfdSAndroid Build Coastguard Worker
183*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
184*387f9dfdSAndroid Build Coastguard Worker     get_all_wmark_pages(zone, valp);
185*387f9dfdSAndroid Build Coastguard Worker#endif
186*387f9dfdSAndroid Build Coastguard Worker
187*387f9dfdSAndroid Build Coastguard Worker    return 0;
188*387f9dfdSAndroid Build Coastguard Worker}
189*387f9dfdSAndroid Build Coastguard Worker
190*387f9dfdSAndroid Build Coastguard Workerint trace_fragmentation_index_return(struct pt_regs *ctx)
191*387f9dfdSAndroid Build Coastguard Worker{
192*387f9dfdSAndroid Build Coastguard Worker    int ret = PT_REGS_RC(ctx);
193*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
194*387f9dfdSAndroid Build Coastguard Worker    struct val_t *valp = start.lookup(&id);
195*387f9dfdSAndroid Build Coastguard Worker    if (valp == NULL) {
196*387f9dfdSAndroid Build Coastguard Worker        // missed entry
197*387f9dfdSAndroid Build Coastguard Worker        return 0;
198*387f9dfdSAndroid Build Coastguard Worker    }
199*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
200*387f9dfdSAndroid Build Coastguard Worker    valp->fragindex = ret;
201*387f9dfdSAndroid Build Coastguard Worker#endif
202*387f9dfdSAndroid Build Coastguard Worker    return 0;
203*387f9dfdSAndroid Build Coastguard Worker}
204*387f9dfdSAndroid Build Coastguard Worker
205*387f9dfdSAndroid Build Coastguard Workerint trace_compaction_suitable_return(struct pt_regs *ctx)
206*387f9dfdSAndroid Build Coastguard Worker{
207*387f9dfdSAndroid Build Coastguard Worker    int ret = PT_REGS_RC(ctx);
208*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
209*387f9dfdSAndroid Build Coastguard Worker    struct val_t *valp = start.lookup(&id);
210*387f9dfdSAndroid Build Coastguard Worker    if (valp == NULL) {
211*387f9dfdSAndroid Build Coastguard Worker        // missed entry
212*387f9dfdSAndroid Build Coastguard Worker        return 0;
213*387f9dfdSAndroid Build Coastguard Worker    }
214*387f9dfdSAndroid Build Coastguard Worker    if (ret != COMPACT_CONTINUE)
215*387f9dfdSAndroid Build Coastguard Worker        start.delete(&id);
216*387f9dfdSAndroid Build Coastguard Worker    else
217*387f9dfdSAndroid Build Coastguard Worker        valp->ts = bpf_ktime_get_ns();
218*387f9dfdSAndroid Build Coastguard Worker    return 0;
219*387f9dfdSAndroid Build Coastguard Worker}
220*387f9dfdSAndroid Build Coastguard Worker
221*387f9dfdSAndroid Build Coastguard Workerint trace_compact_zone_return(struct pt_regs *ctx)
222*387f9dfdSAndroid Build Coastguard Worker{
223*387f9dfdSAndroid Build Coastguard Worker    int ret = PT_REGS_RC(ctx);
224*387f9dfdSAndroid Build Coastguard Worker    struct data_t data = {};
225*387f9dfdSAndroid Build Coastguard Worker    u64 ts = bpf_ktime_get_ns();
226*387f9dfdSAndroid Build Coastguard Worker    u64 id = bpf_get_current_pid_tgid();
227*387f9dfdSAndroid Build Coastguard Worker    struct val_t *valp = start.lookup(&id);
228*387f9dfdSAndroid Build Coastguard Worker    if (valp == NULL) {
229*387f9dfdSAndroid Build Coastguard Worker        // missed entry or unsuitable
230*387f9dfdSAndroid Build Coastguard Worker        return 0;
231*387f9dfdSAndroid Build Coastguard Worker    }
232*387f9dfdSAndroid Build Coastguard Worker
233*387f9dfdSAndroid Build Coastguard Worker    data.delta = ts - valp->ts;
234*387f9dfdSAndroid Build Coastguard Worker    data.ts = ts / 1000;
235*387f9dfdSAndroid Build Coastguard Worker    data.pid = id >> 32;
236*387f9dfdSAndroid Build Coastguard Worker    data.tid = id;
237*387f9dfdSAndroid Build Coastguard Worker    bpf_get_current_comm(&data.comm, sizeof(data.comm));
238*387f9dfdSAndroid Build Coastguard Worker    data.nid = valp->nid;
239*387f9dfdSAndroid Build Coastguard Worker    data.idx = valp->idx;
240*387f9dfdSAndroid Build Coastguard Worker    data.order = valp->order;
241*387f9dfdSAndroid Build Coastguard Worker    data.sync = valp->sync;
242*387f9dfdSAndroid Build Coastguard Worker
243*387f9dfdSAndroid Build Coastguard Worker#ifdef EXTNEDED_FIELDS
244*387f9dfdSAndroid Build Coastguard Worker    data.fragindex = valp->fragindex;
245*387f9dfdSAndroid Build Coastguard Worker    data.min = valp->min;
246*387f9dfdSAndroid Build Coastguard Worker    data.low = valp->low;
247*387f9dfdSAndroid Build Coastguard Worker    data.high = valp->high;
248*387f9dfdSAndroid Build Coastguard Worker    data.free = valp->free;
249*387f9dfdSAndroid Build Coastguard Worker#endif
250*387f9dfdSAndroid Build Coastguard Worker
251*387f9dfdSAndroid Build Coastguard Worker    data.status = ret;
252*387f9dfdSAndroid Build Coastguard Worker    data.stack_id = stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID);
253*387f9dfdSAndroid Build Coastguard Worker
254*387f9dfdSAndroid Build Coastguard Worker    events.perf_submit(ctx, &data, sizeof(data));
255*387f9dfdSAndroid Build Coastguard Worker
256*387f9dfdSAndroid Build Coastguard Worker    start.delete(&id);
257*387f9dfdSAndroid Build Coastguard Worker    return 0;
258*387f9dfdSAndroid Build Coastguard Worker}
259*387f9dfdSAndroid Build Coastguard Worker"""
260*387f9dfdSAndroid Build Coastguard Worker
261*387f9dfdSAndroid Build Coastguard Workerif platform.machine() != 'x86_64':
262*387f9dfdSAndroid Build Coastguard Worker    print("""
263*387f9dfdSAndroid Build Coastguard Worker          Currently only support x86_64 servers, if you want to use it on
264*387f9dfdSAndroid Build Coastguard Worker          other platforms, please refer include/linux/mmzone.h to modify
265*387f9dfdSAndroid Build Coastguard Worker          zone_idex_to_str to get the right zone type
266*387f9dfdSAndroid Build Coastguard Worker    """)
267*387f9dfdSAndroid Build Coastguard Worker    exit()
268*387f9dfdSAndroid Build Coastguard Worker
269*387f9dfdSAndroid Build Coastguard Workerif args.extended_fields:
270*387f9dfdSAndroid Build Coastguard Worker    bpf_text = EXTENDED + bpf_text
271*387f9dfdSAndroid Build Coastguard Workerelse:
272*387f9dfdSAndroid Build Coastguard Worker    bpf_text = NO_EXTENDED + bpf_text
273*387f9dfdSAndroid Build Coastguard Worker
274*387f9dfdSAndroid Build Coastguard Workerif args.pid:
275*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace(
276*387f9dfdSAndroid Build Coastguard Worker        "PID_FILTER", "if (id >> 32 != %s) { return 0; }" % args.pid)
277*387f9dfdSAndroid Build Coastguard Workerelse:
278*387f9dfdSAndroid Build Coastguard Worker    bpf_text = bpf_text.replace("PID_FILTER", "")
279*387f9dfdSAndroid Build Coastguard Workerif debug or args.ebpf:
280*387f9dfdSAndroid Build Coastguard Worker    print(bpf_text)
281*387f9dfdSAndroid Build Coastguard Worker    if args.ebpf:
282*387f9dfdSAndroid Build Coastguard Worker        exit()
283*387f9dfdSAndroid Build Coastguard Worker
284*387f9dfdSAndroid Build Coastguard Worker# load BPF program
285*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
286*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="compact_zone", fn_name="trace_compact_zone_entry")
287*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(event="compact_zone", fn_name="trace_compact_zone_return")
288*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(
289*387f9dfdSAndroid Build Coastguard Worker    event="compaction_suitable", fn_name="trace_compaction_suitable_entry"
290*387f9dfdSAndroid Build Coastguard Worker)
291*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(
292*387f9dfdSAndroid Build Coastguard Worker    event="fragmentation_index", fn_name="trace_fragmentation_index_return"
293*387f9dfdSAndroid Build Coastguard Worker)
294*387f9dfdSAndroid Build Coastguard Workerb.attach_kretprobe(
295*387f9dfdSAndroid Build Coastguard Worker    event="compaction_suitable", fn_name="trace_compaction_suitable_return"
296*387f9dfdSAndroid Build Coastguard Worker)
297*387f9dfdSAndroid Build Coastguard Worker
298*387f9dfdSAndroid Build Coastguard Workerstack_traces = b.get_table("stack_traces")
299*387f9dfdSAndroid Build Coastguard Workerinitial_ts = 0
300*387f9dfdSAndroid Build Coastguard Worker
301*387f9dfdSAndroid Build Coastguard Workerdef zone_idx_to_str(idx):
302*387f9dfdSAndroid Build Coastguard Worker    # from include/linux/mmzone.h
303*387f9dfdSAndroid Build Coastguard Worker    # NOTICE: consider only x86_64 servers
304*387f9dfdSAndroid Build Coastguard Worker    zonetype = {
305*387f9dfdSAndroid Build Coastguard Worker        0: "ZONE_DMA",
306*387f9dfdSAndroid Build Coastguard Worker        1: "ZONE_DMA32",
307*387f9dfdSAndroid Build Coastguard Worker        2: "ZONE_NORMAL",
308*387f9dfdSAndroid Build Coastguard Worker    }
309*387f9dfdSAndroid Build Coastguard Worker
310*387f9dfdSAndroid Build Coastguard Worker    if idx in zonetype:
311*387f9dfdSAndroid Build Coastguard Worker        return zonetype[idx]
312*387f9dfdSAndroid Build Coastguard Worker    else:
313*387f9dfdSAndroid Build Coastguard Worker        return str(idx)
314*387f9dfdSAndroid Build Coastguard Worker
315*387f9dfdSAndroid Build Coastguard Workerdef compact_result_to_str(status):
316*387f9dfdSAndroid Build Coastguard Worker    # from include/linux/compaction.h
317*387f9dfdSAndroid Build Coastguard Worker    compact_status = {
318*387f9dfdSAndroid Build Coastguard Worker        # COMPACT_SKIPPED: compaction didn't start as it was not possible
319*387f9dfdSAndroid Build Coastguard Worker        # or direct reclaim was more suitable
320*387f9dfdSAndroid Build Coastguard Worker        0: "skipped",
321*387f9dfdSAndroid Build Coastguard Worker        # COMPACT_CONTINUE: compaction should continue to another pageblock
322*387f9dfdSAndroid Build Coastguard Worker        1: "continue",
323*387f9dfdSAndroid Build Coastguard Worker        # COMPACT_PARTIAL: direct compaction partially compacted a zone and
324*387f9dfdSAndroid Build Coastguard Worker        # there are suitable pages
325*387f9dfdSAndroid Build Coastguard Worker        2: "partial",
326*387f9dfdSAndroid Build Coastguard Worker        # COMPACT_COMPLETE: The full zone was compacted
327*387f9dfdSAndroid Build Coastguard Worker        3: "complete",
328*387f9dfdSAndroid Build Coastguard Worker    }
329*387f9dfdSAndroid Build Coastguard Worker
330*387f9dfdSAndroid Build Coastguard Worker    if status in compact_status:
331*387f9dfdSAndroid Build Coastguard Worker        return compact_status[status]
332*387f9dfdSAndroid Build Coastguard Worker    else:
333*387f9dfdSAndroid Build Coastguard Worker        return str(status)
334*387f9dfdSAndroid Build Coastguard Worker
335*387f9dfdSAndroid Build Coastguard Worker# header
336*387f9dfdSAndroid Build Coastguard Workerif args.timestamp:
337*387f9dfdSAndroid Build Coastguard Worker    print("%-14s" % ("TIME(s)"), end=" ")
338*387f9dfdSAndroid Build Coastguard Workerprint(
339*387f9dfdSAndroid Build Coastguard Worker    "%-14s %-6s %-4s %-12s %-5s %-7s"
340*387f9dfdSAndroid Build Coastguard Worker    % ("COMM", "PID", "NODE", "ZONE", "ORDER", "MODE"),
341*387f9dfdSAndroid Build Coastguard Worker    end=" ",
342*387f9dfdSAndroid Build Coastguard Worker)
343*387f9dfdSAndroid Build Coastguard Workerif args.extended_fields:
344*387f9dfdSAndroid Build Coastguard Worker    print("%-8s %-8s %-8s %-8s %-8s" %
345*387f9dfdSAndroid Build Coastguard Worker            ("FRAGIDX", "MIN", "LOW", "HIGH", "FREE"), end=" ")
346*387f9dfdSAndroid Build Coastguard Workerprint("%9s %16s" % ("LAT(ms)", "STATUS"))
347*387f9dfdSAndroid Build Coastguard Worker
348*387f9dfdSAndroid Build Coastguard Worker# process event
349*387f9dfdSAndroid Build Coastguard Workerdef print_event(cpu, data, size):
350*387f9dfdSAndroid Build Coastguard Worker    event = b["events"].event(data)
351*387f9dfdSAndroid Build Coastguard Worker
352*387f9dfdSAndroid Build Coastguard Worker    global initial_ts
353*387f9dfdSAndroid Build Coastguard Worker
354*387f9dfdSAndroid Build Coastguard Worker    if not initial_ts:
355*387f9dfdSAndroid Build Coastguard Worker        initial_ts = event.ts
356*387f9dfdSAndroid Build Coastguard Worker
357*387f9dfdSAndroid Build Coastguard Worker    if args.timestamp:
358*387f9dfdSAndroid Build Coastguard Worker        delta = event.ts - initial_ts
359*387f9dfdSAndroid Build Coastguard Worker        print("%-14.9f" % (float(delta) / 1000000), end=" ")
360*387f9dfdSAndroid Build Coastguard Worker
361*387f9dfdSAndroid Build Coastguard Worker    print("%-14.14s %-6s %-4s %-12s %-5s %-7s" % (
362*387f9dfdSAndroid Build Coastguard Worker            event.comm.decode("utf-8", "replace"),
363*387f9dfdSAndroid Build Coastguard Worker            event.pid,
364*387f9dfdSAndroid Build Coastguard Worker            event.nid,
365*387f9dfdSAndroid Build Coastguard Worker            zone_idx_to_str(event.idx),
366*387f9dfdSAndroid Build Coastguard Worker            event.order,
367*387f9dfdSAndroid Build Coastguard Worker            "SYNC" if event.sync else "ASYNC"), end=" ")
368*387f9dfdSAndroid Build Coastguard Worker    if args.extended_fields:
369*387f9dfdSAndroid Build Coastguard Worker        print("%-8.3f %-8s %-8s %-8s %-8s" % (
370*387f9dfdSAndroid Build Coastguard Worker                float(event.fragindex) / 1000,
371*387f9dfdSAndroid Build Coastguard Worker                event.min,
372*387f9dfdSAndroid Build Coastguard Worker                event.low,
373*387f9dfdSAndroid Build Coastguard Worker                event.high,
374*387f9dfdSAndroid Build Coastguard Worker                event.free), end=" ")
375*387f9dfdSAndroid Build Coastguard Worker    print("%9.3f %16s" % (
376*387f9dfdSAndroid Build Coastguard Worker        float(event.delta) / 1000000, compact_result_to_str(event.status)))
377*387f9dfdSAndroid Build Coastguard Worker    if args.kernel_stack:
378*387f9dfdSAndroid Build Coastguard Worker        for addr in stack_traces.walk(event.stack_id):
379*387f9dfdSAndroid Build Coastguard Worker            sym = b.ksym(addr, show_offset=True)
380*387f9dfdSAndroid Build Coastguard Worker            print("\t%s" % sym)
381*387f9dfdSAndroid Build Coastguard Worker            print("")
382*387f9dfdSAndroid Build Coastguard Worker
383*387f9dfdSAndroid Build Coastguard Worker# loop with callback to print_event
384*387f9dfdSAndroid Build Coastguard Workerb["events"].open_perf_buffer(print_event, page_cnt=64)
385*387f9dfdSAndroid Build Coastguard Workerstart_time = datetime.now()
386*387f9dfdSAndroid Build Coastguard Workerwhile not args.duration or datetime.now() - start_time < args.duration:
387*387f9dfdSAndroid Build Coastguard Worker    try:
388*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
389*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
390*387f9dfdSAndroid Build Coastguard Worker        exit()
391