Skip to content

Commit

Permalink
toplev: Filter out nodes that need events with Errata
Browse files Browse the repository at this point in the history
  • Loading branch information
Andi Kleen committed Apr 17, 2016
1 parent bb51975 commit ff26933
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
6 changes: 6 additions & 0 deletions ocperf.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ def __init__(self, name, row):
e.msr = None
e.overflow = 0
e.counter = "1" # dummy for toplev
if 'Errata' in row:
e.errata = row['Errata']
else:
e.errata = None

# {
# "Unit": "CBO",
Expand Down Expand Up @@ -464,9 +468,11 @@ def read_table(self, r, m):
d += " (Uses PEBS)"
else:
d = d.replace("(Precise Event)","") + " (Supports PEBS)"
e.errata = None
try:
if get('errata') != "null":
d += " Errata: " + get('errata')
e.errata = get('errata')
except KeyError:
pass
e.desc = d
Expand Down
3 changes: 3 additions & 0 deletions tl-tester
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ EVENTMAP=${cpus[$DCPU]} FORCECPU=$DCPU $WRAP ./toplev.py --no-desc --stats -d $A
grep :k log
grep /k log
EVENTMAP=${cpus[$DCPU]} FORCECPU=simple $WRAP ./toplev.py --no-desc -l1 $LOAD
# check errata handling
EVENTMAP=GenuineIntel-6-56 FORCECPU=bdw $WRAP ./toplev.py --no-desc --all $LOAD | tee log
grep BDE70 log

# test L1 uses a single group
onegroup() {
Expand Down
46 changes: 35 additions & 11 deletions toplev.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@

smt_mode = False

errata_events = dict()

perf = os.getenv("PERF")
if not perf:
perf = "perf"
Expand Down Expand Up @@ -303,6 +305,7 @@ def exe_dir():
p.add_argument('--nodes', help='Include or exclude nodes (with + to add, ^ to remove, comma separated list, wildcards allowed)')
p.add_argument('--quiet', help='Avoid unnecessary status output', action='store_true')
p.add_argument('--bottleneck', help='Show critical bottleneck', action='store_true')
p.add_argument('--ignore-errata', help='Do not disable events with errata', action='store_true')
args, rest = p.parse_known_args()

rest = [x for x in rest if x != "--"]
Expand Down Expand Up @@ -432,6 +435,7 @@ def add_filter(s):
notfound_cache = set()

def raw_event(i, name="", period=False):
orig_i = i
if i.count(".") > 0:
if i in fixed_counters:
return fixed_counters[i]
Expand All @@ -450,7 +454,7 @@ def raw_event(i, name="", period=False):
print "Event", oi, "maps to multiple units. Ignored."
return "dummy" # FIXME
emap.update_event(e.output(noname=True), e)
# next two things should be moved somewhere else
# next three things should be moved somewhere else
if i.startswith("uncore"):
outgroup_events.add(i)
if e.counter != cpu.standard_counters and not e.counter.startswith("Fixed"):
Expand All @@ -459,6 +463,8 @@ def raw_event(i, name="", period=False):
# CPUs
limited_counters[i] = int(e.counter.split(",")[0])
limited_set.add(i)
if e.errata:
errata_events[orig_i] = e.errata
return i

# generate list of converted raw events from events string
Expand All @@ -471,9 +477,13 @@ def mark_fixed(s):
return "%s[F]" % s
return s

def pwrap(s, linelen=60, indent=""):
def pwrap(s, linelen=70, indent=""):
print indent + ("\n" + indent).join(textwrap.wrap(s, linelen, break_long_words=False))

def pwrap_not_quiet(s, linelen=70, indent=""):
if not args.quiet:
pwrap(s, linelen, indent)

def has(obj, name):
return name in obj.__class__.__dict__

Expand Down Expand Up @@ -1156,36 +1166,50 @@ def collect(self):
bad_nodes = set()
bad_events = set()
unsup_nodes = set()
errata_nodes = set()
errata_names = set()
min_kernel = []
for obj in self.olist:
obj.evlevels = []
obj.compute(lambda ev, level: ev_append(ev, level, obj))
obj.evlist = [x[0] for x in obj.evlevels]
obj.evnum = raw_events(obj.evlist)
obj.nc = needed_counters(obj.evnum)

# work arounds for lots of different problems
unsup = [x for x in obj.evlist if unsup_event(x, unsup_events, min_kernel)]
if any(unsup):
bad_nodes.add(obj)
bad_events |= set(unsup)
unsup = [x for x in obj.evlist if missing_pmu(x)]
if any(unsup):
unsup_nodes.add(obj)
if len(bad_nodes) > 0 and not args.quiet:
errata = [errata_events[x] for x in obj.evlist if x in errata_events]
if any(errata):
errata_nodes.add(obj)
errata_names |= set(errata)
if bad_nodes:
if args.force_events:
pwrap("warning: Using --force-events. Nodes: " +
" ".join([x.name for x in bad_nodes]) + " may be unreliable")
pwrap_not_quiet("warning: Using --force-events. Nodes: " +
" ".join([x.name for x in bad_nodes]) + " may be unreliable")
else:
pwrap("warning: removing " +
if not args.quiet:
pwrap("warning: removing " +
" ".join([x.name for x in bad_nodes]) +
" due to unsupported events in kernel: " +
" ".join(sorted(bad_events)), 80, "")
if min_kernel:
print "Fixed in kernel %d.%d" % (sorted(min_kernel, key=kv_to_key, reverse=True)[0])
print "Use --force-events to override (may result in wrong measurements)"
if min_kernel:
print "Fixed in kernel %d.%d" % (sorted(min_kernel, key=kv_to_key, reverse=True)[0])
print "Use --force-events to override (may result in wrong measurements)"
self.olist = [x for x in self.olist if x not in bad_nodes]
if len(unsup_nodes) > 0 and not args.quiet:
pwrap("Nodes " + " ".join(x.name for x in unsup_nodes) + " has unsupported PMUs")
if unsup_nodes:
pwrap_not_quiet("Nodes " + " ".join(x.name for x in unsup_nodes) + " has unsupported PMUs")
self.olist = [x for x in self.olist if x not in unsup_nodes]
if errata_nodes and not args.ignore_errata:
pwrap_not_quiet("Nodes " + " ".join(x.name for x in errata_nodes) + " have errata " +
" ".join(errata_names) + " and were disabled. " +
"Override with --ignore-errata")
self.olist = [x for x in self.olist if x in errata_nodes]

# fit events into available counters
# simple first fit algorithm
Expand Down

0 comments on commit ff26933

Please sign in to comment.