summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python/compaction-times.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/scripts/python/compaction-times.py')
-rw-r--r--tools/perf/scripts/python/compaction-times.py311
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)