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