diff options
Diffstat (limited to 'tools/perf/scripts/python/compaction-times.py')
| -rw-r--r-- | tools/perf/scripts/python/compaction-times.py | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/tools/perf/scripts/python/compaction-times.py b/tools/perf/scripts/python/compaction-times.py deleted file mode 100644 index 9401f7c14747..000000000000 --- a/tools/perf/scripts/python/compaction-times.py +++ /dev/null @@ -1,311 +0,0 @@ -# report time spent in compaction -# Licensed under the terms of the GNU GPL License version 2 - -# testing: -# 'echo 1 > /proc/sys/vm/compact_memory' to force compaction of all zones - -import os -import sys -import re - -import signal -signal.signal(signal.SIGPIPE, signal.SIG_DFL) - -usage = "usage: perf script report compaction-times.py -- [-h] [-u] [-p|-pv] [-t | [-m] [-fs] [-ms]] [pid|pid-range|comm-regex]\n" - -class popt: - DISP_DFL = 0 - DISP_PROC = 1 - DISP_PROC_VERBOSE=2 - -class topt: - DISP_TIME = 0 - DISP_MIG = 1 - DISP_ISOLFREE = 2 - DISP_ISOLMIG = 4 - DISP_ALL = 7 - -class comm_filter: - def __init__(self, re): - self.re = re - - def filter(self, pid, comm): - m = self.re.search(comm) - return m == None or m.group() == "" - -class pid_filter: - def __init__(self, low, high): - self.low = (0 if low == "" else int(low)) - self.high = (0 if high == "" else int(high)) - - def filter(self, pid, comm): - return not (pid >= self.low and (self.high == 0 or pid <= self.high)) - -def set_type(t): - global opt_disp - opt_disp = (t if opt_disp == topt.DISP_ALL else opt_disp|t) - -def ns(sec, nsec): - return (sec * 1000000000) + nsec - -def time(ns): - return "%dns" % ns if opt_ns else "%dus" % (round(ns, -3) / 1000) - -class pair: - def __init__(self, aval, bval, alabel = None, blabel = None): - self.alabel = alabel - self.blabel = blabel - self.aval = aval - self.bval = bval - - def __add__(self, rhs): - self.aval += rhs.aval - self.bval += rhs.bval - return self - - def __str__(self): - return "%s=%d %s=%d" % (self.alabel, self.aval, self.blabel, self.bval) - -class cnode: - def __init__(self, ns): - self.ns = ns - self.migrated = pair(0, 0, "moved", "failed") - self.fscan = pair(0,0, "scanned", "isolated") - self.mscan = pair(0,0, "scanned", "isolated") - - def __add__(self, rhs): - self.ns += rhs.ns - self.migrated += rhs.migrated - self.fscan += rhs.fscan - self.mscan += rhs.mscan - return self - - def __str__(self): - prev = 0 - s = "%s " % time(self.ns) - if (opt_disp & topt.DISP_MIG): - s += "migration: %s" % self.migrated - prev = 1 - if (opt_disp & topt.DISP_ISOLFREE): - s += "%sfree_scanner: %s" % (" " if prev else "", self.fscan) - prev = 1 - if (opt_disp & topt.DISP_ISOLMIG): - s += "%smigration_scanner: %s" % (" " if prev else "", self.mscan) - return s - - def complete(self, secs, nsecs): - self.ns = ns(secs, nsecs) - self.ns - - def increment(self, migrated, fscan, mscan): - if (migrated != None): - self.migrated += migrated - if (fscan != None): - self.fscan += fscan - if (mscan != None): - self.mscan += mscan - - -class chead: - heads = {} - val = cnode(0); - fobj = None - - @classmethod - def add_filter(cls, filter): - cls.fobj = filter - - @classmethod - def create_pending(cls, pid, comm, start_secs, start_nsecs): - filtered = 0 - try: - head = cls.heads[pid] - filtered = head.is_filtered() - except KeyError: - if cls.fobj != None: - filtered = cls.fobj.filter(pid, comm) - head = cls.heads[pid] = chead(comm, pid, filtered) - - if not filtered: - head.mark_pending(start_secs, start_nsecs) - - @classmethod - def increment_pending(cls, pid, migrated, fscan, mscan): - head = cls.heads[pid] - if not head.is_filtered(): - if head.is_pending(): - head.do_increment(migrated, fscan, mscan) - else: - sys.stderr.write("missing start compaction event for pid %d\n" % pid) - - @classmethod - def complete_pending(cls, pid, secs, nsecs): - head = cls.heads[pid] - if not head.is_filtered(): - if head.is_pending(): - head.make_complete(secs, nsecs) - else: - sys.stderr.write("missing start compaction event for pid %d\n" % pid) - - @classmethod - def gen(cls): - if opt_proc != popt.DISP_DFL: - for i in cls.heads: - yield cls.heads[i] - - @classmethod - def str(cls): - return cls.val - - def __init__(self, comm, pid, filtered): - self.comm = comm - self.pid = pid - self.val = cnode(0) - self.pending = None - self.filtered = filtered - self.list = [] - - def __add__(self, rhs): - self.ns += rhs.ns - self.val += rhs.val - return self - - def mark_pending(self, secs, nsecs): - self.pending = cnode(ns(secs, nsecs)) - - def do_increment(self, migrated, fscan, mscan): - self.pending.increment(migrated, fscan, mscan) - - def make_complete(self, secs, nsecs): - self.pending.complete(secs, nsecs) - chead.val += self.pending - - if opt_proc != popt.DISP_DFL: - self.val += self.pending - - if opt_proc == popt.DISP_PROC_VERBOSE: - self.list.append(self.pending) - self.pending = None - - def enumerate(self): - if opt_proc == popt.DISP_PROC_VERBOSE and not self.is_filtered(): - for i, pelem in enumerate(self.list): - sys.stdout.write("%d[%s].%d: %s\n" % (self.pid, self.comm, i+1, pelem)) - - def is_pending(self): - return self.pending != None - - def is_filtered(self): - return self.filtered - - def display(self): - if not self.is_filtered(): - sys.stdout.write("%d[%s]: %s\n" % (self.pid, self.comm, self.val)) - - -def trace_end(): - sys.stdout.write("total: %s\n" % chead.str()) - for i in chead.gen(): - i.display(), - i.enumerate() - -def compaction__mm_compaction_migratepages(event_name, context, common_cpu, - common_secs, common_nsecs, common_pid, common_comm, - common_callchain, nr_migrated, nr_failed): - - chead.increment_pending(common_pid, - pair(nr_migrated, nr_failed), None, None) - -def compaction__mm_compaction_isolate_freepages(event_name, context, common_cpu, - common_secs, common_nsecs, common_pid, common_comm, - common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): - - chead.increment_pending(common_pid, - None, pair(nr_scanned, nr_taken), None) - -def compaction__mm_compaction_isolate_migratepages(event_name, context, common_cpu, - common_secs, common_nsecs, common_pid, common_comm, - common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): - - chead.increment_pending(common_pid, - None, None, pair(nr_scanned, nr_taken)) - -def compaction__mm_compaction_end(event_name, context, common_cpu, - common_secs, common_nsecs, common_pid, common_comm, - common_callchain, zone_start, migrate_start, free_start, zone_end, - sync, status): - - chead.complete_pending(common_pid, common_secs, common_nsecs) - -def compaction__mm_compaction_begin(event_name, context, common_cpu, - common_secs, common_nsecs, common_pid, common_comm, - common_callchain, zone_start, migrate_start, free_start, zone_end, - sync): - - chead.create_pending(common_pid, common_comm, common_secs, common_nsecs) - -def pr_help(): - global usage - - sys.stdout.write(usage) - sys.stdout.write("\n") - sys.stdout.write("-h display this help\n") - sys.stdout.write("-p display by process\n") - sys.stdout.write("-pv display by process (verbose)\n") - sys.stdout.write("-t display stall times only\n") - sys.stdout.write("-m display stats for migration\n") - sys.stdout.write("-fs display stats for free scanner\n") - sys.stdout.write("-ms display stats for migration scanner\n") - sys.stdout.write("-u display results in microseconds (default nanoseconds)\n") - - -comm_re = None -pid_re = None -pid_regex = r"^(\d*)-(\d*)$|^(\d*)$" - -opt_proc = popt.DISP_DFL -opt_disp = topt.DISP_ALL - -opt_ns = True - -argc = len(sys.argv) - 1 -if argc >= 1: - pid_re = re.compile(pid_regex) - - for i, opt in enumerate(sys.argv[1:]): - if opt[0] == "-": - if opt == "-h": - pr_help() - exit(0); - elif opt == "-p": - opt_proc = popt.DISP_PROC - elif opt == "-pv": - opt_proc = popt.DISP_PROC_VERBOSE - elif opt == '-u': - opt_ns = False - elif opt == "-t": - set_type(topt.DISP_TIME) - elif opt == "-m": - set_type(topt.DISP_MIG) - elif opt == "-fs": - set_type(topt.DISP_ISOLFREE) - elif opt == "-ms": - set_type(topt.DISP_ISOLMIG) - else: - sys.exit(usage) - - elif i == argc - 1: - m = pid_re.search(opt) - if m != None and m.group() != "": - if m.group(3) != None: - f = pid_filter(m.group(3), m.group(3)) - else: - f = pid_filter(m.group(1), m.group(2)) - else: - try: - comm_re=re.compile(opt) - except: - sys.stderr.write("invalid regex '%s'" % opt) - sys.exit(usage) - f = comm_filter(comm_re) - - chead.add_filter(f) |
