summaryrefslogtreecommitdiff
path: root/tools/sched
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-01-13 16:44:18 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-01-13 16:44:18 +0000
commit0199a61d9ff2c57c99f51deb6774907dcdf17468 (patch)
treedaf0fa5007f830f5c380cfc085f94c7ed9ab4047 /tools/sched
parent2977b8f9149fd04b49d9ac700d41c8a77778a91f (diff)
downloadsrc-test2-0199a61d9ff2c57c99f51deb6774907dcdf17468.tar.gz
src-test2-0199a61d9ff2c57c99f51deb6774907dcdf17468.zip
Notes
Diffstat (limited to 'tools/sched')
-rw-r--r--tools/sched/schedgraph.py226
1 files changed, 224 insertions, 2 deletions
diff --git a/tools/sched/schedgraph.py b/tools/sched/schedgraph.py
index 87a1c8948391..d217941661a1 100644
--- a/tools/sched/schedgraph.py
+++ b/tools/sched/schedgraph.py
@@ -672,6 +672,86 @@ class Sched_exit(StateEvent):
configtypes.append(Sched_exit)
+# Events for running callout routines
+
+class CalloutIdle(StateEvent):
+ name = "callwheel idle"
+ color = "grey"
+ enabled = 0
+ def __init__(self, wheel, cpu, timestamp):
+ StateEvent.__init__(self, wheel, cpu, timestamp)
+
+configtypes.append(CalloutIdle)
+
+class CalloutRunning(StateEvent):
+ name = "callout running"
+ color = "green"
+ enabled = 1
+ def __init__(self, wheel, cpu, timestamp, func, arg):
+ StateEvent.__init__(self, wheel, cpu, timestamp)
+ self.textadd(("function:", func, 0))
+ self.textadd(("argument:", arg, 0))
+ self.arg = arg
+ self.func = func
+
+ def stattxt(self):
+ statstr = StateEvent.stattxt(self)
+ statstr += " executing %s(%s)" % (self.func, self.arg)
+ return (statstr)
+
+configtypes.append(CalloutRunning)
+
+# Events on locks
+#
+# XXX: No support for upgrade/downgrade currently or differentiating
+# between read/write in general.
+#
+# XXX: Point events for recursion perhaps?
+
+class LockAcquire(StateEvent):
+ name = "lock acquire"
+ color = "blue"
+ enabled = 1
+ def __init__(self, lock, cpu, timestamp, file, line):
+ StateEvent.__init__(self, lock, cpu, timestamp)
+ self.textadd(("file:", file, 0))
+ self.textadd(("line:", line, 0))
+
+configtypes.append(LockAcquire)
+
+class LockContest(StateEvent):
+ name = "lock contest"
+ color = "purple"
+ enabled = 1
+ def __init__(self, lock, cpu, timestamp, file, line):
+ StateEvent.__init__(self, lock, cpu, timestamp)
+ self.textadd(("file:", file, 0))
+ self.textadd(("line:", line, 0))
+
+configtypes.append(LockContest)
+
+class LockFailedTry(PointEvent):
+ name = "failed lock try"
+ color = "red"
+ enabled = 1
+ def __init__(self, lock, cpu, timestamp, file, line):
+ PointEvent.__init__(self, lock, cpu, timestamp)
+ self.textadd(("file:", file, 0))
+ self.textadd(("line:", line, 0))
+
+configtypes.append(LockFailedTry)
+
+class LockRelease(StateEvent):
+ name = "lock release"
+ color = "grey"
+ enabled = 0
+ def __init__(self, lock, cpu, timestamp, file, line):
+ StateEvent.__init__(self, lock, cpu, timestamp)
+ self.textadd(("file:", file, 0))
+ self.textadd(("line:", line, 0))
+
+configtypes.append(LockRelease)
+
class Padevent(StateEvent):
def __init__(self, thread, cpu, timestamp, last=0):
StateEvent.__init__(self, thread, cpu, timestamp, last)
@@ -739,7 +819,7 @@ class Wokeup(PointEvent):
configtypes.append(Wokeup)
-(DEFAULT, LOAD, COUNT, THREAD) = range(4)
+(DEFAULT, LOAD, COUNT, CALLWHEEL, LOCK, THREAD) = range(6)
class EventSource:
def __init__(self, name, group=DEFAULT, order=0):
@@ -852,6 +932,29 @@ class Thread(EventSource):
def ysize(self):
return (10)
+class Callwheel(EventSource):
+ count = 0
+ def __init__(self, cpu):
+ EventSource.__init__(self, "Callwheel", CALLWHEEL, cpu)
+ self.wheel = cpu
+ Callwheel.count += 1
+
+ def fixup(self):
+ EventSource.fixup(self)
+ if (Callwheel.count == 1):
+ return
+ self.name += " (CPU %d)" % (self.wheel)
+
+ def ysize(self):
+ return (10)
+
+class Lock(EventSource):
+ def __init__(self, lock):
+ EventSource.__init__(self, lock, LOCK)
+
+ def ysize(self):
+ return (10)
+
class Counter(EventSource):
max = 0
def __init__(self, name):
@@ -888,6 +991,8 @@ class KTRFile:
self.timestamp_l = None
self.threads = []
self.sources = []
+ self.locks = {}
+ self.callwheels = {}
self.ticks = {}
self.load = {}
self.crit = {}
@@ -959,6 +1064,46 @@ class KTRFile:
ktrstr = "critical_\S+ by thread " + crittdname + " to (\d+)"
critsec_re = re.compile(ktrhdr + ktrstr)
+ ktrstr = "callout 0x[a-f\d]+ "
+ ktrstr += "func (0x[a-f\d]+) arg (0x[a-f\d]+)"
+ callout_start_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "callout mpsafe 0x[a-f\d]+ "
+ ktrstr += "func (0x[a-f\d]+) arg (0x[a-f\d]+)"
+ callout_mpsafe_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "callout mtx 0x[a-f\d]+ "
+ ktrstr += "func (0x[a-f\d]+) arg (0x[a-f\d]+)"
+ callout_mtx_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "callout 0x[a-f\d]+ finished"
+ callout_stop_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "TRY_([RSWX]?LOCK) \(.*\) (.*) r = ([0-9]+)"
+ ktrstr += " at (?:\.\./)*(.*):([0-9]+)"
+ lock_try_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "([RSWX]?UNLOCK) \(.*\) (.*) r = ([0-9]+)"
+ ktrstr += " at (?:\.\./)*(.*):([0-9]+)"
+ lock_release_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "([RSWX]?LOCK) \(.*\) (.*) r = ([0-9]+)"
+ ktrstr += " at (?:\.\./)*(.*):([0-9]+)"
+ lock_acquire_re = re.compile(ktrhdr + ktrstr)
+
+ ktrstr = "_mtx_lock_sleep: (.*) contested \(lock=0x?[0-9a-f]*\)"
+ ktrstr += " at (?:\.\./)*(.*):([0-9]+)"
+ mtx_contested_re = re.compile(ktrhdr + ktrstr)
+
+ # XXX: Spin lock traces don't have lock name or file/line
+
+ ktrstr = "_rw_wlock_hard: (.*) contested \(lock=0x?[0-9a-f]*\)"
+ ktrstr += " at (?:\.\./)*(.*):([0-9]+)"
+ rw_contested_re = re.compile(ktrhdr + ktrstr)
+
+ # XXX: Read lock traces for rwlocks contesting don't have
+ # lock name or file/line
+
parsers = [[cpuload_re, self.cpuload],
[cpuload2_re, self.cpuload2],
[loadglobal_re, self.loadglobal],
@@ -973,6 +1118,15 @@ class KTRFile:
[sched_exit_re, self.sched_exit],
[sched_clock_re, self.sched_clock],
[critsec_re, self.critsec],
+ [callout_start_re, self.callout_start],
+ [callout_mpsafe_re, self.callout_start],
+ [callout_mtx_re, self.callout_start],
+ [callout_stop_re, self.callout_stop],
+ [lock_try_re, self.lock_try],
+ [lock_release_re, self.lock_release],
+ [lock_acquire_re, self.lock_acquire],
+ [mtx_contested_re, self.lock_contest],
+ [rw_contested_re, self.lock_contest],
[idled_re, self.idled]]
global lineno
@@ -1162,6 +1316,74 @@ class KTRFile:
self.sources.append(crit)
Count(crit, cpu, timestamp, to)
+ def callout_start(self, cpu, timestamp, func, arg):
+ timestamp = self.checkstamp(cpu, timestamp)
+ if (timestamp == 0):
+ return
+ wheel = self.findwheel(cpu)
+ CalloutRunning(wheel, cpu, timestamp, func, arg)
+
+ def callout_stop(self, cpu, timestamp):
+ timestamp = self.checkstamp(cpu, timestamp)
+ if (timestamp == 0):
+ return
+ wheel = self.findwheel(cpu)
+ CalloutIdle(wheel, cpu, timestamp)
+
+ def lock_try(self, cpu, timestamp, op, name, result, file, line):
+ timestamp = self.checkstamp(cpu, timestamp)
+ if (timestamp == 0):
+ return
+ lock = self.findlock(name)
+ if (int(result) == 0):
+ LockFailedTry(lock, cpu, timestamp, file, line)
+ else:
+ LockAcquire(lock, cpu, timestamp, file, line)
+
+ def lock_acquire(self, cpu, timestamp, op, name, recurse, file, line):
+ if (int(recurse) != 0):
+ return
+ timestamp = self.checkstamp(cpu, timestamp)
+ if (timestamp == 0):
+ return
+ lock = self.findlock(name)
+ LockAcquire(lock, cpu, timestamp, file, line)
+
+ def lock_release(self, cpu, timestamp, op, name, recurse, file, line):
+ if (int(recurse) != 0):
+ return
+ timestamp = self.checkstamp(cpu, timestamp)
+ if (timestamp == 0):
+ return
+ lock = self.findlock(name)
+ LockRelease(lock, cpu, timestamp, file, line)
+
+ def lock_contest(self, cpu, timestamp, name, file, line):
+ timestamp = self.checkstamp(cpu, timestamp)
+ if (timestamp == 0):
+ return
+ lock = self.findlock(name)
+ LockContest(lock, cpu, timestamp, file, line)
+
+ def findlock(self, name):
+ try:
+ lock = self.locks[name]
+ except:
+ lock = Lock(name)
+ self.locks[name] = lock
+ self.sources.append(lock)
+ return (lock)
+
+ def findwheel(self, cpu):
+ cpu = int(cpu)
+ try:
+ wheel = self.callwheels[cpu]
+ except:
+ wheel = Callwheel(cpu)
+ self.callwheels[cpu] = wheel
+ self.sources.append(wheel)
+ return (wheel)
+
def findtd(self, td, pcomm):
for thread in self.threads:
if (thread.str == td and thread.name == pcomm):
@@ -1325,7 +1547,7 @@ class SchedGraph(Frame):
self.menu = GraphMenu(self)
self.display = SchedDisplay(self)
self.names = Canvas(self,
- width=100, height=self.display["height"],
+ width=120, height=self.display["height"],
bg='grey', scrollregion=(0, 0, 50, 100))
self.scale = Scaler(self, self.display)
status = self.status = Status(self)