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