aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/bpf/resolve_btfids/main.c2
-rw-r--r--tools/include/uapi/linux/netdev.h1
-rw-r--r--tools/lib/bpf/features.c31
-rwxr-xr-xtools/power/pm-graph/bootgraph.py16
-rwxr-xr-xtools/power/pm-graph/sleepgraph.py1098
-rw-r--r--tools/testing/cxl/test/mem.c1
-rw-r--r--tools/testing/selftests/alsa/Makefile2
-rw-r--r--tools/testing/selftests/bpf/prog_tests/tc_netkit.c94
-rw-r--r--tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c134
-rw-r--r--tools/testing/selftests/bpf/prog_tests/verifier.c2
-rw-r--r--tools/testing/selftests/bpf/progs/test_tc_link.c35
-rw-r--r--tools/testing/selftests/bpf/progs/uprobe_multi.c50
-rw-r--r--tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c187
-rw-r--r--tools/testing/selftests/cachestat/test_cachestat.c1
-rw-r--r--tools/testing/selftests/filesystems/overlayfs/dev_in_maps.c1
-rw-r--r--tools/testing/selftests/ftrace/config26
-rw-r--r--tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc2
-rw-r--r--tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc20
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc3
-rw-r--r--tools/testing/selftests/futex/Makefile2
-rw-r--r--tools/testing/selftests/futex/functional/Makefile2
-rw-r--r--tools/testing/selftests/futex/functional/futex_requeue_pi.c2
-rw-r--r--tools/testing/selftests/landlock/fs_test.c45
-rwxr-xr-xtools/testing/selftests/net/hsr/hsr_ping.sh2
-rwxr-xr-xtools/testing/selftests/net/mptcp/mptcp_join.sh10
-rw-r--r--tools/testing/selftests/net/mptcp/mptcp_lib.sh30
-rwxr-xr-xtools/testing/selftests/net/mptcp/simult_flows.sh6
-rw-r--r--tools/testing/selftests/openat2/openat2_test.c1
-rw-r--r--tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json44
29 files changed, 1271 insertions, 579 deletions
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index d9520cb826b3..af393c7dee1f 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -728,7 +728,7 @@ static int sets_patch(struct object *obj)
static int symbols_patch(struct object *obj)
{
- int err;
+ off_t err;
if (__symbols_patch(obj, &obj->structs) ||
__symbols_patch(obj, &obj->unions) ||
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index a8188202413e..43742ac5b00d 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -148,6 +148,7 @@ enum {
NETDEV_A_QSTATS_RX_ALLOC_FAIL,
NETDEV_A_QSTATS_RX_HW_DROPS,
NETDEV_A_QSTATS_RX_HW_DROP_OVERRUNS,
+ NETDEV_A_QSTATS_RX_CSUM_COMPLETE,
NETDEV_A_QSTATS_RX_CSUM_UNNECESSARY,
NETDEV_A_QSTATS_RX_CSUM_NONE,
NETDEV_A_QSTATS_RX_CSUM_BAD,
diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c
index a336786a22a3..3df0125ed5fa 100644
--- a/tools/lib/bpf/features.c
+++ b/tools/lib/bpf/features.c
@@ -392,11 +392,40 @@ static int probe_uprobe_multi_link(int token_fd)
link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts);
err = -errno; /* close() can clobber errno */
+ if (link_fd >= 0 || err != -EBADF) {
+ close(link_fd);
+ close(prog_fd);
+ return 0;
+ }
+
+ /* Initial multi-uprobe support in kernel didn't handle PID filtering
+ * correctly (it was doing thread filtering, not process filtering).
+ * So now we'll detect if PID filtering logic was fixed, and, if not,
+ * we'll pretend multi-uprobes are not supported, if not.
+ * Multi-uprobes are used in USDT attachment logic, and we need to be
+ * conservative here, because multi-uprobe selection happens early at
+ * load time, while the use of PID filtering is known late at
+ * attachment time, at which point it's too late to undo multi-uprobe
+ * selection.
+ *
+ * Creating uprobe with pid == -1 for (invalid) '/' binary will fail
+ * early with -EINVAL on kernels with fixed PID filtering logic;
+ * otherwise -ESRCH would be returned if passed correct binary path
+ * (but we'll just get -BADF, of course).
+ */
+ link_opts.uprobe_multi.pid = -1; /* invalid PID */
+ link_opts.uprobe_multi.path = "/"; /* invalid path */
+ link_opts.uprobe_multi.offsets = &offset;
+ link_opts.uprobe_multi.cnt = 1;
+
+ link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts);
+ err = -errno; /* close() can clobber errno */
+
if (link_fd >= 0)
close(link_fd);
close(prog_fd);
- return link_fd < 0 && err == -EBADF;
+ return link_fd < 0 && err == -EINVAL;
}
static int probe_kern_bpf_cookie(int token_fd)
diff --git a/tools/power/pm-graph/bootgraph.py b/tools/power/pm-graph/bootgraph.py
index f96f50e0c336..8a3ef94fe88f 100755
--- a/tools/power/pm-graph/bootgraph.py
+++ b/tools/power/pm-graph/bootgraph.py
@@ -77,12 +77,12 @@ class SystemValues(aslib.SystemValues):
fp.close()
self.testdir = datetime.now().strftime('boot-%y%m%d-%H%M%S')
def kernelVersion(self, msg):
- m = re.match('^[Ll]inux *[Vv]ersion *(?P<v>\S*) .*', msg)
+ m = re.match(r'^[Ll]inux *[Vv]ersion *(?P<v>\S*) .*', msg)
if m:
return m.group('v')
return 'unknown'
def checkFtraceKernelVersion(self):
- m = re.match('^(?P<x>[0-9]*)\.(?P<y>[0-9]*)\.(?P<z>[0-9]*).*', self.kernel)
+ m = re.match(r'^(?P<x>[0-9]*)\.(?P<y>[0-9]*)\.(?P<z>[0-9]*).*', self.kernel)
if m:
val = tuple(map(int, m.groups()))
if val >= (4, 10, 0):
@@ -324,7 +324,7 @@ def parseKernelLog():
idx = line.find('[')
if idx > 1:
line = line[idx:]
- m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
+ m = re.match(r'[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if(not m):
continue
ktime = float(m.group('ktime'))
@@ -332,24 +332,24 @@ def parseKernelLog():
break
msg = m.group('msg')
data.dmesgtext.append(line)
- if(ktime == 0.0 and re.match('^Linux version .*', msg)):
+ if(ktime == 0.0 and re.match(r'^Linux version .*', msg)):
if(not sysvals.stamp['kernel']):
sysvals.stamp['kernel'] = sysvals.kernelVersion(msg)
continue
- m = re.match('.* setting system clock to (?P<d>[0-9\-]*)[ A-Z](?P<t>[0-9:]*) UTC.*', msg)
+ m = re.match(r'.* setting system clock to (?P<d>[0-9\-]*)[ A-Z](?P<t>[0-9:]*) UTC.*', msg)
if(m):
bt = datetime.strptime(m.group('d')+' '+m.group('t'), '%Y-%m-%d %H:%M:%S')
bt = bt - timedelta(seconds=int(ktime))
data.boottime = bt.strftime('%Y-%m-%d_%H:%M:%S')
sysvals.stamp['time'] = bt.strftime('%B %d %Y, %I:%M:%S %p')
continue
- m = re.match('^calling *(?P<f>.*)\+.* @ (?P<p>[0-9]*)', msg)
+ m = re.match(r'^calling *(?P<f>.*)\+.* @ (?P<p>[0-9]*)', msg)
if(m):
func = m.group('f')
pid = int(m.group('p'))
devtemp[func] = (ktime, pid)
continue
- m = re.match('^initcall *(?P<f>.*)\+.* returned (?P<r>.*) after (?P<t>.*) usecs', msg)
+ m = re.match(r'^initcall *(?P<f>.*)\+.* returned (?P<r>.*) after (?P<t>.*) usecs', msg)
if(m):
data.valid = True
data.end = ktime
@@ -359,7 +359,7 @@ def parseKernelLog():
data.newAction(phase, f, pid, start, ktime, int(r), int(t))
del devtemp[f]
continue
- if(re.match('^Freeing unused kernel .*', msg)):
+ if(re.match(r'^Freeing unused kernel .*', msg)):
data.tUserMode = ktime
data.dmesg['kernel']['end'] = ktime
data.dmesg['user']['start'] = ktime
diff --git a/tools/power/pm-graph/sleepgraph.py b/tools/power/pm-graph/sleepgraph.py
index 40ad221e8881..ef87e63c05c7 100755
--- a/tools/power/pm-graph/sleepgraph.py
+++ b/tools/power/pm-graph/sleepgraph.py
@@ -86,7 +86,7 @@ def ascii(text):
# store system values and test parameters
class SystemValues:
title = 'SleepGraph'
- version = '5.11'
+ version = '5.12'
ansi = False
rs = 0
display = ''
@@ -420,11 +420,11 @@ class SystemValues:
return value.format(**args)
def setOutputFile(self):
if self.dmesgfile != '':
- m = re.match('(?P<name>.*)_dmesg\.txt.*', self.dmesgfile)
+ m = re.match(r'(?P<name>.*)_dmesg\.txt.*', self.dmesgfile)
if(m):
self.htmlfile = m.group('name')+'.html'
if self.ftracefile != '':
- m = re.match('(?P<name>.*)_ftrace\.txt.*', self.ftracefile)
+ m = re.match(r'(?P<name>.*)_ftrace\.txt.*', self.ftracefile)
if(m):
self.htmlfile = m.group('name')+'.html'
def systemInfo(self, info):
@@ -464,15 +464,15 @@ class SystemValues:
if os.path.exists('/proc/cpuinfo'):
with open('/proc/cpuinfo', 'r') as fp:
for line in fp:
- if re.match('^processor[ \t]*:[ \t]*[0-9]*', line):
+ if re.match(r'^processor[ \t]*:[ \t]*[0-9]*', line):
self.cpucount += 1
if os.path.exists('/proc/meminfo'):
with open('/proc/meminfo', 'r') as fp:
for line in fp:
- m = re.match('^MemTotal:[ \t]*(?P<sz>[0-9]*) *kB', line)
+ m = re.match(r'^MemTotal:[ \t]*(?P<sz>[0-9]*) *kB', line)
if m:
self.memtotal = int(m.group('sz'))
- m = re.match('^MemFree:[ \t]*(?P<sz>[0-9]*) *kB', line)
+ m = re.match(r'^MemFree:[ \t]*(?P<sz>[0-9]*) *kB', line)
if m:
self.memfree = int(m.group('sz'))
if os.path.exists('/etc/os-release'):
@@ -539,7 +539,7 @@ class SystemValues:
idx = line.find('[')
if idx > 1:
line = line[idx:]
- m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
+ m = re.match(r'[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if(m):
ktime = m.group('ktime')
break
@@ -553,7 +553,7 @@ class SystemValues:
idx = line.find('[')
if idx > 1:
line = line[idx:]
- m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
+ m = re.match(r'[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if(not m):
continue
ktime = float(m.group('ktime'))
@@ -636,11 +636,11 @@ class SystemValues:
# now process the args
for arg in sorted(args):
arglist[arg] = ''
- m = re.match('.* '+arg+'=(?P<arg>.*) ', data);
+ m = re.match(r'.* '+arg+'=(?P<arg>.*) ', data);
if m:
arglist[arg] = m.group('arg')
else:
- m = re.match('.* '+arg+'=(?P<arg>.*)', data);
+ m = re.match(r'.* '+arg+'=(?P<arg>.*)', data);
if m:
arglist[arg] = m.group('arg')
out = fmt.format(**arglist)
@@ -989,7 +989,7 @@ class SystemValues:
m = re.match(tp.ftrace_line_fmt, line)
if(not m or 'device_pm_callback_start' not in line):
continue
- m = re.match('.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg'));
+ m = re.match(r'.*: (?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*', m.group('msg'));
if(not m):
continue
dev = m.group('d')
@@ -999,7 +999,7 @@ class SystemValues:
# now get the syspath for each target device
for dirname, dirnames, filenames in os.walk('/sys/devices'):
- if(re.match('.*/power', dirname) and 'async' in filenames):
+ if(re.match(r'.*/power', dirname) and 'async' in filenames):
dev = dirname.split('/')[-2]
if dev in props and (not props[dev].syspath or len(dirname) < len(props[dev].syspath)):
props[dev].syspath = dirname[:-6]
@@ -1143,12 +1143,12 @@ class SystemValues:
elif value and os.path.exists(file):
fp = open(file, 'r+')
if fmt == 'radio':
- m = re.match('.*\[(?P<v>.*)\].*', fp.read())
+ m = re.match(r'.*\[(?P<v>.*)\].*', fp.read())
if m:
self.cfgdef[file] = m.group('v')
elif fmt == 'acpi':
line = fp.read().strip().split('\n')[-1]
- m = re.match('.* (?P<v>[0-9A-Fx]*) .*', line)
+ m = re.match(r'.* (?P<v>[0-9A-Fx]*) .*', line)
if m:
self.cfgdef[file] = m.group('v')
else:
@@ -1173,7 +1173,7 @@ class SystemValues:
fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr
out = ascii(fp.read()).strip()
fp.close()
- if re.match('turbostat version .*', out):
+ if re.match(r'turbostat version .*', out):
self.vprint(out)
return True
return False
@@ -1181,33 +1181,33 @@ class SystemValues:
cmd = self.getExec('turbostat')
rawout = keyline = valline = ''
fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile)
- fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE).stderr
- for line in fp:
+ fp = Popen(['sh', '-c', fullcmd], stdout=PIPE, stderr=PIPE)
+ for line in fp.stderr:
line = ascii(line)
rawout += line
if keyline and valline:
continue
- if re.match('(?i)Avg_MHz.*', line):
+ if re.match(r'(?i)Avg_MHz.*', line):
keyline = line.strip().split()
elif keyline:
valline = line.strip().split()
- fp.close()
+ fp.wait()
if not keyline or not valline or len(keyline) != len(valline):
errmsg = 'unrecognized turbostat output:\n'+rawout.strip()
self.vprint(errmsg)
if not self.verbose:
pprint(errmsg)
- return ''
+ return (fp.returncode, '')
if self.verbose:
pprint(rawout.strip())
out = []
for key in keyline:
idx = keyline.index(key)
val = valline[idx]
- if key == 'SYS%LPI' and not s0ixready and re.match('^[0\.]*$', val):
+ if key == 'SYS%LPI' and not s0ixready and re.match(r'^[0\.]*$', val):
continue
out.append('%s=%s' % (key, val))
- return '|'.join(out)
+ return (fp.returncode, '|'.join(out))
def netfixon(self, net='both'):
cmd = self.getExec('netfix')
if not cmd:
@@ -1232,7 +1232,7 @@ class SystemValues:
except:
return ''
for line in reversed(w.split('\n')):
- m = re.match(' *(?P<dev>.*): (?P<stat>[0-9a-f]*) .*', line)
+ m = re.match(r' *(?P<dev>.*): (?P<stat>[0-9a-f]*) .*', line)
if not m or (dev and dev != m.group('dev')):
continue
return m.group('dev')
@@ -1261,14 +1261,14 @@ class SystemValues:
return
arr = msg.split()
for j in range(len(arr)):
- if re.match('^[0-9,\-\.]*$', arr[j]):
- arr[j] = '[0-9,\-\.]*'
+ if re.match(r'^[0-9,\-\.]*$', arr[j]):
+ arr[j] = r'[0-9,\-\.]*'
else:
arr[j] = arr[j]\
- .replace('\\', '\\\\').replace(']', '\]').replace('[', '\[')\
- .replace('.', '\.').replace('+', '\+').replace('*', '\*')\
- .replace('(', '\(').replace(')', '\)').replace('}', '\}')\
- .replace('{', '\{')
+ .replace('\\', r'\\\\').replace(']', r'\]').replace('[', r'\[')\
+ .replace('.', r'\.').replace('+', r'\+').replace('*', r'\*')\
+ .replace('(', r'\(').replace(')', r'\)').replace('}', r'\}')\
+ .replace('{', r'\{')
mstr = ' *'.join(arr)
entry = {
'line': msg,
@@ -1340,7 +1340,7 @@ class SystemValues:
fp = Popen(xset.format('q').split(' '), stdout=PIPE).stdout
ret = 'unknown'
for line in fp:
- m = re.match('[\s]*Monitor is (?P<m>.*)', ascii(line))
+ m = re.match(r'[\s]*Monitor is (?P<m>.*)', ascii(line))
if(m and len(m.group('m')) >= 2):
out = m.group('m').lower()
ret = out[3:] if out[0:2] == 'in' else out
@@ -1566,7 +1566,7 @@ class Data:
i += 1
if tp.stampInfo(line, sysvals):
continue
- m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
+ m = re.match(r'[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if not m:
continue
t = float(m.group('ktime'))
@@ -1574,7 +1574,7 @@ class Data:
continue
dir = 'suspend' if t < self.tSuspended else 'resume'
msg = m.group('msg')
- if re.match('capability: warning: .*', msg):
+ if re.match(r'capability: warning: .*', msg):
continue
for err in self.errlist:
if re.match(self.errlist[err], msg):
@@ -1679,8 +1679,8 @@ class Data:
ubiquitous = False
if kprobename in dtf and 'ub' in dtf[kprobename]:
ubiquitous = True
- mc = re.match('\(.*\) *(?P<args>.*)', cdata)
- mr = re.match('\((?P<caller>\S*).* arg1=(?P<ret>.*)', rdata)
+ mc = re.match(r'\(.*\) *(?P<args>.*)', cdata)
+ mr = re.match(r'\((?P<caller>\S*).* arg1=(?P<ret>.*)', rdata)
if mc and mr:
c = mr.group('caller').split('+')[0]
a = mc.group('args').strip()
@@ -1997,7 +1997,7 @@ class Data:
list = self.dmesg[phase]['list']
mydev = ''
for devname in sorted(list):
- if name == devname or re.match('^%s\[(?P<num>[0-9]*)\]$' % name, devname):
+ if name == devname or re.match(r'^%s\[(?P<num>[0-9]*)\]$' % name, devname):
mydev = devname
if mydev:
return list[mydev]
@@ -2099,7 +2099,7 @@ class Data:
for dev in sorted(list):
pdev = list[dev]['par']
pid = list[dev]['pid']
- if(pid < 0 or re.match('[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)):
+ if(pid < 0 or re.match(r'[0-9]*-[0-9]*\.[0-9]*[\.0-9]*\:[\.0-9]*$', pdev)):
continue
if pdev and pdev not in real and pdev not in rootlist:
rootlist.append(pdev)
@@ -2190,26 +2190,26 @@ class Data:
if 'resume_complete' in dm:
dm['resume_complete']['end'] = time
def initcall_debug_call(self, line, quick=False):
- m = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: '+\
- 'PM: *calling .* @ (?P<n>.*), parent: (?P<p>.*)', line)
+ m = re.match(r'.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: '+\
+ r'PM: *calling .* @ (?P<n>.*), parent: (?P<p>.*)', line)
if not m:
- m = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: '+\
- 'calling .* @ (?P<n>.*), parent: (?P<p>.*)', line)
+ m = re.match(r'.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: '+\
+ r'calling .* @ (?P<n>.*), parent: (?P<p>.*)', line)
if not m:
- m = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) calling '+\
- '(?P<f>.*)\+ @ (?P<n>.*), parent: (?P<p>.*)', line)
+ m = re.match(r'.*(\[ *)(?P<t>[0-9\.]*)(\]) calling '+\
+ r'(?P<f>.*)\+ @ (?P<n>.*), parent: (?P<p>.*)', line)
if m:
return True if quick else m.group('t', 'f', 'n', 'p')
return False if quick else ('', '', '', '')
def initcall_debug_return(self, line, quick=False):
- m = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: PM: '+\
- '.* returned (?P<r>[0-9]*) after (?P<dt>[0-9]*) usecs', line)
+ m = re.match(r'.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: PM: '+\
+ r'.* returned (?P<r>[0-9]*) after (?P<dt>[0-9]*) usecs', line)
if not m:
- m = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: '+\
- '.* returned (?P<r>[0-9]*) after (?P<dt>[0-9]*) usecs', line)
+ m = re.match(r'.*(\[ *)(?P<t>[0-9\.]*)(\]) .* (?P<f>.*)\: '+\
+ r'.* returned (?P<r>[0-9]*) after (?P<dt>[0-9]*) usecs', line)
if not m:
- m = re.match('.*(\[ *)(?P<t>[0-9\.]*)(\]) call '+\
- '(?P<f>.*)\+ returned .* after (?P<dt>.*) usecs', line)
+ m = re.match(r'.*(\[ *)(?P<t>[0-9\.]*)(\]) call '+\
+ r'(?P<f>.*)\+ returned .* after (?P<dt>.*) usecs', line)
if m:
return True if quick else m.group('t', 'f', 'dt')
return False if quick else ('', '', '')
@@ -2294,28 +2294,28 @@ class FTraceLine:
if not m and not d:
return
# is this a trace event
- if(d == 'traceevent' or re.match('^ *\/\* *(?P<msg>.*) \*\/ *$', m)):
+ if(d == 'traceevent' or re.match(r'^ *\/\* *(?P<msg>.*) \*\/ *$', m)):
if(d == 'traceevent'):
# nop format trace event
msg = m
else:
# function_graph format trace event
- em = re.match('^ *\/\* *(?P<msg>.*) \*\/ *$', m)
+ em = re.match(r'^ *\/\* *(?P<msg>.*) \*\/ *$', m)
msg = em.group('msg')
- emm = re.match('^(?P<call>.*?): (?P<msg>.*)', msg)
+ emm = re.match(r'^(?P<call>.*?): (?P<msg>.*)', msg)
if(emm):
self.name = emm.group('msg')
self.type = emm.group('call')
else:
self.name = msg
- km = re.match('^(?P<n>.*)_cal$', self.type)
+ km = re.match(r'^(?P<n>.*)_cal$', self.type)
if km:
self.fcall = True
self.fkprobe = True
self.type = km.group('n')
return
- km = re.match('^(?P<n>.*)_ret$', self.type)
+ km = re.match(r'^(?P<n>.*)_ret$', self.type)
if km:
self.freturn = True
self.fkprobe = True
@@ -2327,7 +2327,7 @@ class FTraceLine:
if(d):
self.length = float(d)/1000000
# the indentation determines the depth
- match = re.match('^(?P<d> *)(?P<o>.*)$', m)
+ match = re.match(r'^(?P<d> *)(?P<o>.*)$', m)
if(not match):
return
self.depth = self.getDepth(match.group('d'))
@@ -2337,7 +2337,7 @@ class FTraceLine:
self.freturn = True
if(len(m) > 1):
# includes comment with function name
- match = re.match('^} *\/\* *(?P<n>.*) *\*\/$', m)
+ match = re.match(r'^} *\/\* *(?P<n>.*) *\*\/$', m)
if(match):
self.name = match.group('n').strip()
# function call
@@ -2345,13 +2345,13 @@ class FTraceLine:
self.fcall = True
# function call with children
if(m[-1] == '{'):
- match = re.match('^(?P<n>.*) *\(.*', m)
+ match = re.match(r'^(?P<n>.*) *\(.*', m)
if(match):
self.name = match.group('n').strip()
# function call with no children (leaf)
elif(m[-1] == ';'):
self.freturn = True
- match = re.match('^(?P<n>.*) *\(.*', m)
+ match = re.match(r'^(?P<n>.*) *\(.*', m)
if(match):
self.name = match.group('n').strip()
# something else (possibly a trace marker)
@@ -2385,7 +2385,7 @@ class FTraceLine:
return False
else:
if(self.type == 'suspend_resume' and
- re.match('suspend_enter\[.*\] begin', self.name)):
+ re.match(r'suspend_enter\[.*\] begin', self.name)):
return True
return False
def endMarker(self):
@@ -2398,7 +2398,7 @@ class FTraceLine:
return False
else:
if(self.type == 'suspend_resume' and
- re.match('thaw_processes\[.*\] end', self.name)):
+ re.match(r'thaw_processes\[.*\] end', self.name)):
return True
return False
@@ -2976,30 +2976,30 @@ class Timeline:
# Description:
# A list of values describing the properties of these test runs
class TestProps:
- stampfmt = '# [a-z]*-(?P<m>[0-9]{2})(?P<d>[0-9]{2})(?P<y>[0-9]{2})-'+\
- '(?P<H>[0-9]{2})(?P<M>[0-9]{2})(?P<S>[0-9]{2})'+\
- ' (?P<host>.*) (?P<mode>.*) (?P<kernel>.*)$'
- wififmt = '^# wifi *(?P<d>\S*) *(?P<s>\S*) *(?P<t>[0-9\.]+).*'
- tstatfmt = '^# turbostat (?P<t>\S*)'
- testerrfmt = '^# enter_sleep_error (?P<e>.*)'
- sysinfofmt = '^# sysinfo .*'
- cmdlinefmt = '^# command \| (?P<cmd>.*)'
- kparamsfmt = '^# kparams \| (?P<kp>.*)'
- devpropfmt = '# Device Properties: .*'
- pinfofmt = '# platform-(?P<val>[a-z,A-Z,0-9,_]*): (?P<info>.*)'
- tracertypefmt = '# tracer: (?P<t>.*)'
- firmwarefmt = '# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$'
- procexecfmt = 'ps - (?P<ps>.*)$'
- procmultifmt = '@(?P<n>[0-9]*)\|(?P<ps>.*)$'
+ stampfmt = r'# [a-z]*-(?P<m>[0-9]{2})(?P<d>[0-9]{2})(?P<y>[0-9]{2})-'+\
+ r'(?P<H>[0-9]{2})(?P<M>[0-9]{2})(?P<S>[0-9]{2})'+\
+ r' (?P<host>.*) (?P<mode>.*) (?P<kernel>.*)$'
+ wififmt = r'^# wifi *(?P<d>\S*) *(?P<s>\S*) *(?P<t>[0-9\.]+).*'
+ tstatfmt = r'^# turbostat (?P<t>\S*)'
+ testerrfmt = r'^# enter_sleep_error (?P<e>.*)'
+ sysinfofmt = r'^# sysinfo .*'
+ cmdlinefmt = r'^# command \| (?P<cmd>.*)'
+ kparamsfmt = r'^# kparams \| (?P<kp>.*)'
+ devpropfmt = r'# Device Properties: .*'
+ pinfofmt = r'# platform-(?P<val>[a-z,A-Z,0-9,_]*): (?P<info>.*)'
+ tracertypefmt = r'# tracer: (?P<t>.*)'
+ firmwarefmt = r'# fwsuspend (?P<s>[0-9]*) fwresume (?P<r>[0-9]*)$'
+ procexecfmt = r'ps - (?P<ps>.*)$'
+ procmultifmt = r'@(?P<n>[0-9]*)\|(?P<ps>.*)$'
ftrace_line_fmt_fg = \
- '^ *(?P<time>[0-9\.]*) *\| *(?P<cpu>[0-9]*)\)'+\
- ' *(?P<proc>.*)-(?P<pid>[0-9]*) *\|'+\
- '[ +!#\*@$]*(?P<dur>[0-9\.]*) .*\| (?P<msg>.*)'
+ r'^ *(?P<time>[0-9\.]*) *\| *(?P<cpu>[0-9]*)\)'+\
+ r' *(?P<proc>.*)-(?P<pid>[0-9]*) *\|'+\
+ r'[ +!#\*@$]*(?P<dur>[0-9\.]*) .*\| (?P<msg>.*)'
ftrace_line_fmt_nop = \
- ' *(?P<proc>.*)-(?P<pid>[0-9]*) *\[(?P<cpu>[0-9]*)\] *'+\
- '(?P<flags>\S*) *(?P<time>[0-9\.]*): *'+\
- '(?P<msg>.*)'
- machinesuspend = 'machine_suspend\[.*'
+ r' *(?P<proc>.*)-(?P<pid>[0-9]*) *\[(?P<cpu>[0-9]*)\] *'+\
+ r'(?P<flags>\S*) *(?P<time>[0-9\.]*): *'+\
+ r'(?P<msg>.*)'
+ machinesuspend = r'machine_suspend\[.*'
multiproclist = dict()
multiproctime = 0.0
multiproccnt = 0
@@ -3081,14 +3081,14 @@ class TestProps:
sv.hostname = data.stamp['host']
sv.suspendmode = data.stamp['mode']
if sv.suspendmode == 'freeze':
- self.machinesuspend = 'timekeeping_freeze\[.*'
+ self.machinesuspend = r'timekeeping_freeze\[.*'
else:
- self.machinesuspend = 'machine_suspend\[.*'
+ self.machinesuspend = r'machine_suspend\[.*'
if sv.suspendmode == 'command' and sv.ftracefile != '':
modes = ['on', 'freeze', 'standby', 'mem', 'disk']
fp = sv.openlog(sv.ftracefile, 'r')
for line in fp:
- m = re.match('.* machine_suspend\[(?P<mode>.*)\]', line)
+ m = re.match(r'.* machine_suspend\[(?P<mode>.*)\]', line)
if m and m.group('mode') in ['1', '2', '3', '4']:
sv.suspendmode = modes[int(m.group('mode'))]
data.stamp['mode'] = sv.suspendmode
@@ -3401,9 +3401,9 @@ def loadTraceLog():
for i in range(len(blk)):
if 'SUSPEND START' in blk[i][3]:
first.append(i)
- elif re.match('.* timekeeping_freeze.*begin', blk[i][3]):
+ elif re.match(r'.* timekeeping_freeze.*begin', blk[i][3]):
last.append(i)
- elif re.match('.* timekeeping_freeze.*end', blk[i][3]):
+ elif re.match(r'.* timekeeping_freeze.*end', blk[i][3]):
first.append(i)
elif 'RESUME COMPLETE' in blk[i][3]:
last.append(i)
@@ -3514,28 +3514,28 @@ def parseTraceLog(live=False):
if(t.fevent):
if(t.type == 'suspend_resume'):
# suspend_resume trace events have two types, begin and end
- if(re.match('(?P<name>.*) begin$', t.name)):
+ if(re.match(r'(?P<name>.*) begin$', t.name)):
isbegin = True
- elif(re.match('(?P<name>.*) end$', t.name)):
+ elif(re.match(r'(?P<name>.*) end$', t.name)):
isbegin = False
else:
continue
if '[' in t.name:
- m = re.match('(?P<name>.*)\[.*', t.name)
+ m = re.match(r'(?P<name>.*)\[.*', t.name)
else:
- m = re.match('(?P<name>.*) .*', t.name)
+ m = re.match(r'(?P<name>.*) .*', t.name)
name = m.group('name')
# ignore these events
if(name.split('[')[0] in tracewatch):
continue
# -- phase changes --
# start of kernel suspend
- if(re.match('suspend_enter\[.*', t.name)):
+ if(re.match(r'suspend_enter\[.*', t.name)):
if(isbegin and data.tKernSus == 0):
data.tKernSus = t.time
continue
# suspend_prepare start
- elif(re.match('dpm_prepare\[.*', t.name)):
+ elif(re.match(r'dpm_prepare\[.*', t.name)):
if isbegin and data.first_suspend_prepare:
data.first_suspend_prepare = False
if data.tKernSus == 0:
@@ -3544,15 +3544,15 @@ def parseTraceLog(live=False):
phase = data.setPhase('suspend_prepare', t.time, isbegin)
continue
# suspend start
- elif(re.match('dpm_suspend\[.*', t.name)):
+ elif(re.match(r'dpm_suspend\[.*', t.name)):
phase = data.setPhase('suspend', t.time, isbegin)
continue
# suspend_late start
- elif(re.match('dpm_suspend_late\[.*', t.name)):
+ elif(re.match(r'dpm_suspend_late\[.*', t.name)):
phase = data.setPhase('suspend_late', t.time, isbegin)
continue
# suspend_noirq start
- elif(re.match('dpm_suspend_noirq\[.*', t.name)):
+ elif(re.match(r'dpm_suspend_noirq\[.*', t.name)):
phase = data.setPhase('suspend_noirq', t.time, isbegin)
continue
# suspend_machine/resume_machine
@@ -3589,19 +3589,19 @@ def parseTraceLog(live=False):
data.tResumed = t.time
continue
# resume_noirq start
- elif(re.match('dpm_resume_noirq\[.*', t.name)):
+ elif(re.match(r'dpm_resume_noirq\[.*', t.name)):
phase = data.setPhase('resume_noirq', t.time, isbegin)
continue
# resume_early start
- elif(re.match('dpm_resume_early\[.*', t.name)):
+ elif(re.match(r'dpm_resume_early\[.*', t.name)):
phase = data.setPhase('resume_early', t.time, isbegin)
continue
# resume start
- elif(re.match('dpm_resume\[.*', t.name)):
+ elif(re.match(r'dpm_resume\[.*', t.name)):
phase = data.setPhase('resume', t.time, isbegin)
continue
# resume complete start
- elif(re.match('dpm_complete\[.*', t.name)):
+ elif(re.match(r'dpm_complete\[.*', t.name)):
phase = data.setPhase('resume_complete', t.time, isbegin)
continue
# skip trace events inside devices calls
@@ -3635,7 +3635,7 @@ def parseTraceLog(live=False):
elif(t.type == 'device_pm_callback_start'):
if phase not in data.dmesg:
continue
- m = re.match('(?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*',\
+ m = re.match(r'(?P<drv>.*) (?P<d>.*), parent: *(?P<p>.*), .*',\
t.name);
if(not m):
continue
@@ -3650,7 +3650,7 @@ def parseTraceLog(live=False):
elif(t.type == 'device_pm_callback_end'):
if phase not in data.dmesg:
continue
- m = re.match('(?P<drv>.*) (?P<d>.*), err.*', t.name);
+ m = re.match(r'(?P<drv>.*) (?P<d>.*), err.*', t.name);
if(not m):
continue
n = m.group('d')
@@ -3904,24 +3904,24 @@ def loadKernelLog():
line = line[idx:]
if tp.stampInfo(line, sysvals):
continue
- m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
+ m = re.match(r'[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if(not m):
continue
msg = m.group("msg")
- if re.match('PM: Syncing filesystems.*', msg) or \
- re.match('PM: suspend entry.*', msg):
+ if re.match(r'PM: Syncing filesystems.*', msg) or \
+ re.match(r'PM: suspend entry.*', msg):
if(data):
testruns.append(data)
data = Data(len(testruns))
tp.parseStamp(data, sysvals)
if(not data):
continue
- m = re.match('.* *(?P<k>[0-9]\.[0-9]{2}\.[0-9]-.*) .*', msg)
+ m = re.match(r'.* *(?P<k>[0-9]\.[0-9]{2}\.[0-9]-.*) .*', msg)
if(m):
sysvals.stamp['kernel'] = m.group('k')
- m = re.match('PM: Preparing system for (?P<m>.*) sleep', msg)
+ m = re.match(r'PM: Preparing system for (?P<m>.*) sleep', msg)
if not m:
- m = re.match('PM: Preparing system for sleep \((?P<m>.*)\)', msg)
+ m = re.match(r'PM: Preparing system for sleep \((?P<m>.*)\)', msg)
if m:
sysvals.stamp['mode'] = sysvals.suspendmode = m.group('m')
data.dmesgtext.append(line)
@@ -3984,7 +3984,7 @@ def parseKernelLog(data):
'resume_machine': ['[PM: ]*Timekeeping suspended for.*',
'ACPI: Low-level resume complete.*',
'ACPI: resume from mwait',
- 'Suspended for [0-9\.]* seconds'],
+ r'Suspended for [0-9\.]* seconds'],
'resume_noirq': ['PM: resume from suspend-to-idle',
'ACPI: Waking up from system sleep state.*'],
'resume_early': ['PM: noirq resume of devices complete after.*',
@@ -3993,7 +3993,7 @@ def parseKernelLog(data):
'PM: early restore of devices complete after.*'],
'resume_complete': ['PM: resume of devices complete after.*',
'PM: restore of devices complete after.*'],
- 'post_resume': ['.*Restarting tasks \.\.\..*'],
+ 'post_resume': [r'.*Restarting tasks \.\.\..*'],
}
# action table (expected events that occur and show up in dmesg)
@@ -4021,7 +4021,7 @@ def parseKernelLog(data):
actions = dict()
for line in data.dmesgtext:
# parse each dmesg line into the time and message
- m = re.match('[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
+ m = re.match(r'[ \t]*(\[ *)(?P<ktime>[0-9\.]*)(\]) (?P<msg>.*)', line)
if(m):
val = m.group('ktime')
try:
@@ -4145,26 +4145,26 @@ def parseKernelLog(data):
if(a in actions and actions[a][-1]['begin'] == actions[a][-1]['end']):
actions[a][-1]['end'] = ktime
# now look for CPU on/off events
- if(re.match('Disabling non-boot CPUs .*', msg)):
+ if(re.match(r'Disabling non-boot CPUs .*', msg)):
# start of first cpu suspend
cpu_start = ktime
- elif(re.match('Enabling non-boot CPUs .*', msg)):
+ elif(re.match(r'Enabling non-boot CPUs .*', msg)):
# start of first cpu resume
cpu_start = ktime
- elif(re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg) \
- or re.match('psci: CPU(?P<cpu>[0-9]*) killed.*', msg)):
+ elif(re.match(r'smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg) \
+ or re.match(r'psci: CPU(?P<cpu>[0-9]*) killed.*', msg)):
# end of a cpu suspend, start of the next
- m = re.match('smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)
+ m = re.match(r'smpboot: CPU (?P<cpu>[0-9]*) is now offline', msg)
if(not m):
- m = re.match('psci: CPU(?P<cpu>[0-9]*) killed.*', msg)
+ m = re.match(r'psci: CPU(?P<cpu>[0-9]*) killed.*', msg)
cpu = 'CPU'+m.group('cpu')
if(cpu not in actions):
actions[cpu] = []
actions[cpu].append({'begin': cpu_start, 'end': ktime})
cpu_start = ktime
- elif(re.match('CPU(?P<cpu>[0-9]*) is up', msg)):
+ elif(re.match(r'CPU(?P<cpu>[0-9]*) is up', msg)):
# end of a cpu resume, start of the next
- m = re.match('CPU(?P<cpu>[0-9]*) is up', msg)
+ m = re.match(r'CPU(?P<cpu>[0-9]*) is up', msg)
cpu = 'CPU'+m.group('cpu')
if(cpu not in actions):
actions[cpu] = []
@@ -4343,7 +4343,8 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
list[mode]['data'].append([data['host'], data['kernel'],
data['time'], tVal[0], tVal[1], data['url'], res,
data['issues'], data['sus_worst'], data['sus_worsttime'],
- data['res_worst'], data['res_worsttime'], pkgpc10, syslpi, wifi])
+ data['res_worst'], data['res_worsttime'], pkgpc10, syslpi, wifi,
+ (data['fullmode'] if 'fullmode' in data else mode)])
idx = len(list[mode]['data']) - 1
if res.startswith('fail in'):
res = 'fail'
@@ -4449,7 +4450,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
elif idx == iMed[i]:
tHigh[i] = ' id="%smed" class=medval title="Median"' % tag
html += td.format("%d" % (list[mode]['data'].index(d) + 1)) # row
- html += td.format(mode) # mode
+ html += td.format(d[15]) # mode
html += td.format(d[0]) # host
html += td.format(d[1]) # kernel
html += td.format(d[2]) # time
@@ -5061,6 +5062,7 @@ def addCSS(hf, sv, testcount=1, kerror=False, extra=''):
def addScriptCode(hf, testruns):
t0 = testruns[0].start * 1000
tMax = testruns[-1].end * 1000
+ hf.write('<script type="text/javascript">\n');
# create an array in javascript memory with the device details
detail = ' var devtable = [];\n'
for data in testruns:
@@ -5068,384 +5070,383 @@ def addScriptCode(hf, testruns):
detail += ' devtable[%d] = "%s";\n' % (data.testnumber, topo)
detail += ' var bounds = [%f,%f];\n' % (t0, tMax)
# add the code which will manipulate the data in the browser
- script_code = \
- '<script type="text/javascript">\n'+detail+\
- ' var resolution = -1;\n'\
- ' var dragval = [0, 0];\n'\
- ' function redrawTimescale(t0, tMax, tS) {\n'\
- ' var rline = \'<div class="t" style="left:0;border-left:1px solid black;border-right:0;">\';\n'\
- ' var tTotal = tMax - t0;\n'\
- ' var list = document.getElementsByClassName("tblock");\n'\
- ' for (var i = 0; i < list.length; i++) {\n'\
- ' var timescale = list[i].getElementsByClassName("timescale")[0];\n'\
- ' var m0 = t0 + (tTotal*parseFloat(list[i].style.left)/100);\n'\
- ' var mTotal = tTotal*parseFloat(list[i].style.width)/100;\n'\
- ' var mMax = m0 + mTotal;\n'\
- ' var html = "";\n'\
- ' var divTotal = Math.floor(mTotal/tS) + 1;\n'\
- ' if(divTotal > 1000) continue;\n'\
- ' var divEdge = (mTotal - tS*(divTotal-1))*100/mTotal;\n'\
- ' var pos = 0.0, val = 0.0;\n'\
- ' for (var j = 0; j < divTotal; j++) {\n'\
- ' var htmlline = "";\n'\
- ' var mode = list[i].id[5];\n'\
- ' if(mode == "s") {\n'\
- ' pos = 100 - (((j)*tS*100)/mTotal) - divEdge;\n'\
- ' val = (j-divTotal+1)*tS;\n'\
- ' if(j == divTotal - 1)\n'\
- ' htmlline = \'<div class="t" style="right:\'+pos+\'%"><cS>S&rarr;</cS></div>\';\n'\
- ' else\n'\
- ' htmlline = \'<div class="t" style="right:\'+pos+\'%">\'+val+\'ms</div>\';\n'\
- ' } else {\n'\
- ' pos = 100 - (((j)*tS*100)/mTotal);\n'\
- ' val = (j)*tS;\n'\
- ' htmlline = \'<div class="t" style="right:\'+pos+\'%">\'+val+\'ms</div>\';\n'\
- ' if(j == 0)\n'\
- ' if(mode == "r")\n'\
- ' htmlline = rline+"<cS>&larr;R</cS></div>";\n'\
- ' else\n'\
- ' htmlline = rline+"<cS>0ms</div>";\n'\
- ' }\n'\
- ' html += htmlline;\n'\
- ' }\n'\
- ' timescale.innerHTML = html;\n'\
- ' }\n'\
- ' }\n'\
- ' function zoomTimeline() {\n'\
- ' var dmesg = document.getElementById("dmesg");\n'\
- ' var zoombox = document.getElementById("dmesgzoombox");\n'\
- ' var left = zoombox.scrollLeft;\n'\
- ' var val = parseFloat(dmesg.style.width);\n'\
- ' var newval = 100;\n'\
- ' var sh = window.outerWidth / 2;\n'\
- ' if(this.id == "zoomin") {\n'\
- ' newval = val * 1.2;\n'\
- ' if(newval > 910034) newval = 910034;\n'\
- ' dmesg.style.width = newval+"%";\n'\
- ' zoombox.scrollLeft = ((left + sh) * newval / val) - sh;\n'\
- ' } else if (this.id == "zoomout") {\n'\
- ' newval = val / 1.2;\n'\
- ' if(newval < 100) newval = 100;\n'\
- ' dmesg.style.width = newval+"%";\n'\
- ' zoombox.scrollLeft = ((left + sh) * newval / val) - sh;\n'\
- ' } else {\n'\
- ' zoombox.scrollLeft = 0;\n'\
- ' dmesg.style.width = "100%";\n'\
- ' }\n'\
- ' var tS = [10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1];\n'\
- ' var t0 = bounds[0];\n'\
- ' var tMax = bounds[1];\n'\
- ' var tTotal = tMax - t0;\n'\
- ' var wTotal = tTotal * 100.0 / newval;\n'\
- ' var idx = 7*window.innerWidth/1100;\n'\
- ' for(var i = 0; (i < tS.length)&&((wTotal / tS[i]) < idx); i++);\n'\
- ' if(i >= tS.length) i = tS.length - 1;\n'\
- ' if(tS[i] == resolution) return;\n'\
- ' resolution = tS[i];\n'\
- ' redrawTimescale(t0, tMax, tS[i]);\n'\
- ' }\n'\
- ' function deviceName(title) {\n'\
- ' var name = title.slice(0, title.indexOf(" ("));\n'\
- ' return name;\n'\
- ' }\n'\
- ' function deviceHover() {\n'\
- ' var name = deviceName(this.title);\n'\
- ' var dmesg = document.getElementById("dmesg");\n'\
- ' var dev = dmesg.getElementsByClassName("thread");\n'\
- ' var cpu = -1;\n'\
- ' if(name.match("CPU_ON\[[0-9]*\]"))\n'\
- ' cpu = parseInt(name.slice(7));\n'\
- ' else if(name.match("CPU_OFF\[[0-9]*\]"))\n'\
- ' cpu = parseInt(name.slice(8));\n'\
- ' for (var i = 0; i < dev.length; i++) {\n'\
- ' dname = deviceName(dev[i].title);\n'\
- ' var cname = dev[i].className.slice(dev[i].className.indexOf("thread"));\n'\
- ' if((cpu >= 0 && dname.match("CPU_O[NF]*\\\[*"+cpu+"\\\]")) ||\n'\
- ' (name == dname))\n'\
- ' {\n'\
- ' dev[i].className = "hover "+cname;\n'\
- ' } else {\n'\
- ' dev[i].className = cname;\n'\
- ' }\n'\
- ' }\n'\
- ' }\n'\
- ' function deviceUnhover() {\n'\
- ' var dmesg = document.getElementById("dmesg");\n'\
- ' var dev = dmesg.getElementsByClassName("thread");\n'\
- ' for (var i = 0; i < dev.length; i++) {\n'\
- ' dev[i].className = dev[i].className.slice(dev[i].className.indexOf("thread"));\n'\
- ' }\n'\
- ' }\n'\
- ' function deviceTitle(title, total, cpu) {\n'\
- ' var prefix = "Total";\n'\
- ' if(total.length > 3) {\n'\
- ' prefix = "Average";\n'\
- ' total[1] = (total[1]+total[3])/2;\n'\
- ' total[2] = (total[2]+total[4])/2;\n'\
- ' }\n'\
- ' var devtitle = document.getElementById("devicedetailtitle");\n'\
- ' var name = deviceName(title);\n'\
- ' if(cpu >= 0) name = "CPU"+cpu;\n'\
- ' var driver = "";\n'\
- ' var tS = "<t2>(</t2>";\n'\
- ' var tR = "<t2>)</t2>";\n'\
- ' if(total[1] > 0)\n'\
- ' tS = "<t2>("+prefix+" Suspend:</t2><t0> "+total[1].toFixed(3)+" ms</t0> ";\n'\
- ' if(total[2] > 0)\n'\
- ' tR = " <t2>"+prefix+" Resume:</t2><t0> "+total[2].toFixed(3)+" ms<t2>)</t2></t0>";\n'\
- ' var s = title.indexOf("{");\n'\
- ' var e = title.indexOf("}");\n'\
- ' if((s >= 0) && (e >= 0))\n'\
- ' driver = title.slice(s+1, e) + " <t1>@</t1> ";\n'\
- ' if(total[1] > 0 && total[2] > 0)\n'\
- ' devtitle.innerHTML = "<t0>"+driver+name+"</t0> "+tS+tR;\n'\
- ' else\n'\
- ' devtitle.innerHTML = "<t0>"+title+"</t0>";\n'\
- ' return name;\n'\
- ' }\n'\
- ' function deviceDetail() {\n'\
- ' var devinfo = document.getElementById("devicedetail");\n'\
- ' devinfo.style.display = "block";\n'\
- ' var name = deviceName(this.title);\n'\
- ' var cpu = -1;\n'\
- ' if(name.match("CPU_ON\[[0-9]*\]"))\n'\
- ' cpu = parseInt(name.slice(7));\n'\
- ' else if(name.match("CPU_OFF\[[0-9]*\]"))\n'\
- ' cpu = parseInt(name.slice(8));\n'\
- ' var dmesg = document.getElementById("dmesg");\n'\
- ' var dev = dmesg.getElementsByClassName("thread");\n'\
- ' var idlist = [];\n'\
- ' var pdata = [[]];\n'\
- ' if(document.getElementById("devicedetail1"))\n'\
- ' pdata = [[], []];\n'\
- ' var pd = pdata[0];\n'\
- ' var total = [0.0, 0.0, 0.0];\n'\
- ' for (var i = 0; i < dev.length; i++) {\n'\
- ' dname = deviceName(dev[i].title);\n'\
- ' if((cpu >= 0 && dname.match("CPU_O[NF]*\\\[*"+cpu+"\\\]")) ||\n'\
- ' (name == dname))\n'\
- ' {\n'\
- ' idlist[idlist.length] = dev[i].id;\n'\
- ' var tidx = 1;\n'\
- ' if(dev[i].id[0] == "a") {\n'\
- ' pd = pdata[0];\n'\
- ' } else {\n'\
- ' if(pdata.length == 1) pdata[1] = [];\n'\
- ' if(total.length == 3) total[3]=total[4]=0.0;\n'\
- ' pd = pdata[1];\n'\
- ' tidx = 3;\n'\
- ' }\n'\
- ' var info = dev[i].title.split(" ");\n'\
- ' var pname = info[info.length-1];\n'\
- ' pd[pname] = parseFloat(info[info.length-3].slice(1));\n'\
- ' total[0] += pd[pname];\n'\
- ' if(pname.indexOf("suspend") >= 0)\n'\
- ' total[tidx] += pd[pname];\n'\
- ' else\n'\
- ' total[tidx+1] += pd[pname];\n'\
- ' }\n'\
- ' }\n'\
- ' var devname = deviceTitle(this.title, total, cpu);\n'\
- ' var left = 0.0;\n'\
- ' for (var t = 0; t < pdata.length; t++) {\n'\
- ' pd = pdata[t];\n'\
- ' devinfo = document.getElementById("devicedetail"+t);\n'\
- ' var phases = devinfo.getElementsByClassName("phaselet");\n'\
- ' for (var i = 0; i < phases.length; i++) {\n'\
- ' if(phases[i].id in pd) {\n'\
- ' var w = 100.0*pd[phases[i].id]/total[0];\n'\
- ' var fs = 32;\n'\
- ' if(w < 8) fs = 4*w | 0;\n'\
- ' var fs2 = fs*3/4;\n'\
- ' phases[i].style.width = w+"%";\n'\
- ' phases[i].style.left = left+"%";\n'\
- ' phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms";\n'\
- ' left += w;\n'\
- ' var time = "<t4 style=\\"font-size:"+fs+"px\\">"+pd[phases[i].id]+" ms<br></t4>";\n'\
- ' var pname = "<t3 style=\\"font-size:"+fs2+"px\\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>";\n'\
- ' phases[i].innerHTML = time+pname;\n'\
- ' } else {\n'\
- ' phases[i].style.width = "0%";\n'\
- ' phases[i].style.left = left+"%";\n'\
- ' }\n'\
- ' }\n'\
- ' }\n'\
- ' if(typeof devstats !== \'undefined\')\n'\
- ' callDetail(this.id, this.title);\n'\
- ' var cglist = document.getElementById("callgraphs");\n'\
- ' if(!cglist) return;\n'\
- ' var cg = cglist.getElementsByClassName("atop");\n'\
- ' if(cg.length < 10) return;\n'\
- ' for (var i = 0; i < cg.length; i++) {\n'\
- ' cgid = cg[i].id.split("x")[0]\n'\
- ' if(idlist.indexOf(cgid) >= 0) {\n'\
- ' cg[i].style.display = "block";\n'\
- ' } else {\n'\
- ' cg[i].style.display = "none";\n'\
- ' }\n'\
- ' }\n'\
- ' }\n'\
- ' function callDetail(devid, devtitle) {\n'\
- ' if(!(devid in devstats) || devstats[devid].length < 1)\n'\
- ' return;\n'\
- ' var list = devstats[devid];\n'\
- ' var tmp = devtitle.split(" ");\n'\
- ' var name = tmp[0], phase = tmp[tmp.length-1];\n'\
- ' var dd = document.getElementById(phase);\n'\
- ' var total = parseFloat(tmp[1].slice(1));\n'\
- ' var mlist = [];\n'\
- ' var maxlen = 0;\n'\
- ' var info = []\n'\
- ' for(var i in list) {\n'\
- ' if(list[i][0] == "@") {\n'\
- ' info = list[i].split("|");\n'\
- ' continue;\n'\
- ' }\n'\
- ' var tmp = list[i].split("|");\n'\
- ' var t = parseFloat(tmp[0]), f = tmp[1], c = parseInt(tmp[2]);\n'\
- ' var p = (t*100.0/total).toFixed(2);\n'\
- ' mlist[mlist.length] = [f, c, t.toFixed(2), p+"%"];\n'\
- ' if(f.length > maxlen)\n'\
- ' maxlen = f.length;\n'\
- ' }\n'\
- ' var pad = 5;\n'\
- ' if(mlist.length == 0) pad = 30;\n'\
- ' var html = \'<div style="padding-top:\'+pad+\'px"><t3> <b>\'+name+\':</b>\';\n'\
- ' if(info.length > 2)\n'\
- ' html += " start=<b>"+info[1]+"</b>, end=<b>"+info[2]+"</b>";\n'\
- ' if(info.length > 3)\n'\
- ' html += ", length<i>(w/o overhead)</i>=<b>"+info[3]+" ms</b>";\n'\
- ' if(info.length > 4)\n'\
- ' html += ", return=<b>"+info[4]+"</b>";\n'\
- ' html += "</t3></div>";\n'\
- ' if(mlist.length > 0) {\n'\
- ' html += \'<table class=fstat style="padding-top:\'+(maxlen*5)+\'px;"><tr><th>Function</th>\';\n'\
- ' for(var i in mlist)\n'\
- ' html += "<td class=vt>"+mlist[i][0]+"</td>";\n'\
- ' html += "</tr><tr><th>Calls</th>";\n'\
- ' for(var i in mlist)\n'\
- ' html += "<td>"+mlist[i][1]+"</td>";\n'\
- ' html += "</tr><tr><th>Time(ms)</th>";\n'\
- ' for(var i in mlist)\n'\
- ' html += "<td>"+mlist[i][2]+"</td>";\n'\
- ' html += "</tr><tr><th>Percent</th>";\n'\
- ' for(var i in mlist)\n'\
- ' html += "<td>"+mlist[i][3]+"</td>";\n'\
- ' html += "</tr></table>";\n'\
- ' }\n'\
- ' dd.innerHTML = html;\n'\
- ' var height = (maxlen*5)+100;\n'\
- ' dd.style.height = height+"px";\n'\
- ' document.getElementById("devicedetail").style.height = height+"px";\n'\
- ' }\n'\
- ' function callSelect() {\n'\
- ' var cglist = document.getElementById("callgraphs");\n'\
- ' if(!cglist) return;\n'\
- ' var cg = cglist.getElementsByClassName("atop");\n'\
- ' for (var i = 0; i < cg.length; i++) {\n'\
- ' if(this.id == cg[i].id) {\n'\
- ' cg[i].style.display = "block";\n'\
- ' } else {\n'\
- ' cg[i].style.display = "none";\n'\
- ' }\n'\
- ' }\n'\
- ' }\n'\
- ' function devListWindow(e) {\n'\
- ' var win = window.open();\n'\
- ' var html = "<title>"+e.target.innerHTML+"</title>"+\n'\
- ' "<style type=\\"text/css\\">"+\n'\
- ' " ul {list-style-type:circle;padding-left:10px;margin-left:10px;}"+\n'\
- ' "</style>"\n'\
- ' var dt = devtable[0];\n'\
- ' if(e.target.id != "devlist1")\n'\
- ' dt = devtable[1];\n'\
- ' win.document.write(html+dt);\n'\
- ' }\n'\
- ' function errWindow() {\n'\
- ' var range = this.id.split("_");\n'\
- ' var idx1 = parseInt(range[0]);\n'\
- ' var idx2 = parseInt(range[1]);\n'\
- ' var win = window.open();\n'\
- ' var log = document.getElementById("dmesglog");\n'\
- ' var title = "<title>dmesg log</title>";\n'\
- ' var text = log.innerHTML.split("\\n");\n'\
- ' var html = "";\n'\
- ' for(var i = 0; i < text.length; i++) {\n'\
- ' if(i == idx1) {\n'\
- ' html += "<e id=target>"+text[i]+"</e>\\n";\n'\
- ' } else if(i > idx1 && i <= idx2) {\n'\
- ' html += "<e>"+text[i]+"</e>\\n";\n'\
- ' } else {\n'\
- ' html += text[i]+"\\n";\n'\
- ' }\n'\
- ' }\n'\
- ' win.document.write("<style>e{color:red}</style>"+title+"<pre>"+html+"</pre>");\n'\
- ' win.location.hash = "#target";\n'\
- ' win.document.close();\n'\
- ' }\n'\
- ' function logWindow(e) {\n'\
- ' var name = e.target.id.slice(4);\n'\
- ' var win = window.open();\n'\
- ' var log = document.getElementById(name+"log");\n'\
- ' var title = "<title>"+document.title.split(" ")[0]+" "+name+" log</title>";\n'\
- ' win.document.write(title+"<pre>"+log.innerHTML+"</pre>");\n'\
- ' win.document.close();\n'\
- ' }\n'\
- ' function onMouseDown(e) {\n'\
- ' dragval[0] = e.clientX;\n'\
- ' dragval[1] = document.getElementById("dmesgzoombox").scrollLeft;\n'\
- ' document.onmousemove = onMouseMove;\n'\
- ' }\n'\
- ' function onMouseMove(e) {\n'\
- ' var zoombox = document.getElementById("dmesgzoombox");\n'\
- ' zoombox.scrollLeft = dragval[1] + dragval[0] - e.clientX;\n'\
- ' }\n'\
- ' function onMouseUp(e) {\n'\
- ' document.onmousemove = null;\n'\
- ' }\n'\
- ' function onKeyPress(e) {\n'\
- ' var c = e.charCode;\n'\
- ' if(c != 42 && c != 43 && c != 45) return;\n'\
- ' var click = document.createEvent("Events");\n'\
- ' click.initEvent("click", true, false);\n'\
- ' if(c == 43) \n'\
- ' document.getElementById("zoomin").dispatchEvent(click);\n'\
- ' else if(c == 45)\n'\
- ' document.getElementById("zoomout").dispatchEvent(click);\n'\
- ' else if(c == 42)\n'\
- ' document.getElementById("zoomdef").dispatchEvent(click);\n'\
- ' }\n'\
- ' window.addEventListener("resize", function () {zoomTimeline();});\n'\
- ' window.addEventListener("load", function () {\n'\
- ' var dmesg = document.getElementById("dmesg");\n'\
- ' dmesg.style.width = "100%"\n'\
- ' dmesg.onmousedown = onMouseDown;\n'\
- ' document.onmouseup = onMouseUp;\n'\
- ' document.onkeypress = onKeyPress;\n'\
- ' document.getElementById("zoomin").onclick = zoomTimeline;\n'\
- ' document.getElementById("zoomout").onclick = zoomTimeline;\n'\
- ' document.getElementById("zoomdef").onclick = zoomTimeline;\n'\
- ' var list = document.getElementsByClassName("err");\n'\
- ' for (var i = 0; i < list.length; i++)\n'\
- ' list[i].onclick = errWindow;\n'\
- ' var list = document.getElementsByClassName("logbtn");\n'\
- ' for (var i = 0; i < list.length; i++)\n'\
- ' list[i].onclick = logWindow;\n'\
- ' list = document.getElementsByClassName("devlist");\n'\
- ' for (var i = 0; i < list.length; i++)\n'\
- ' list[i].onclick = devListWindow;\n'\
- ' var dev = dmesg.getElementsByClassName("thread");\n'\
- ' for (var i = 0; i < dev.length; i++) {\n'\
- ' dev[i].onclick = deviceDetail;\n'\
- ' dev[i].onmouseover = deviceHover;\n'\
- ' dev[i].onmouseout = deviceUnhover;\n'\
- ' }\n'\
- ' var dev = dmesg.getElementsByClassName("srccall");\n'\
- ' for (var i = 0; i < dev.length; i++)\n'\
- ' dev[i].onclick = callSelect;\n'\
- ' zoomTimeline();\n'\
- ' });\n'\
- '</script>\n'
+ hf.write(detail);
+ script_code = r""" var resolution = -1;
+ var dragval = [0, 0];
+ function redrawTimescale(t0, tMax, tS) {
+ var rline = '<div class="t" style="left:0;border-left:1px solid black;border-right:0;">';
+ var tTotal = tMax - t0;
+ var list = document.getElementsByClassName("tblock");
+ for (var i = 0; i < list.length; i++) {
+ var timescale = list[i].getElementsByClassName("timescale")[0];
+ var m0 = t0 + (tTotal*parseFloat(list[i].style.left)/100);
+ var mTotal = tTotal*parseFloat(list[i].style.width)/100;
+ var mMax = m0 + mTotal;
+ var html = "";
+ var divTotal = Math.floor(mTotal/tS) + 1;
+ if(divTotal > 1000) continue;
+ var divEdge = (mTotal - tS*(divTotal-1))*100/mTotal;
+ var pos = 0.0, val = 0.0;
+ for (var j = 0; j < divTotal; j++) {
+ var htmlline = "";
+ var mode = list[i].id[5];
+ if(mode == "s") {
+ pos = 100 - (((j)*tS*100)/mTotal) - divEdge;
+ val = (j-divTotal+1)*tS;
+ if(j == divTotal - 1)
+ htmlline = '<div class="t" style="right:'+pos+'%"><cS>S&rarr;</cS></div>';
+ else
+ htmlline = '<div class="t" style="right:'+pos+'%">'+val+'ms</div>';
+ } else {
+ pos = 100 - (((j)*tS*100)/mTotal);
+ val = (j)*tS;
+ htmlline = '<div class="t" style="right:'+pos+'%">'+val+'ms</div>';
+ if(j == 0)
+ if(mode == "r")
+ htmlline = rline+"<cS>&larr;R</cS></div>";
+ else
+ htmlline = rline+"<cS>0ms</div>";
+ }
+ html += htmlline;
+ }
+ timescale.innerHTML = html;
+ }
+ }
+ function zoomTimeline() {
+ var dmesg = document.getElementById("dmesg");
+ var zoombox = document.getElementById("dmesgzoombox");
+ var left = zoombox.scrollLeft;
+ var val = parseFloat(dmesg.style.width);
+ var newval = 100;
+ var sh = window.outerWidth / 2;
+ if(this.id == "zoomin") {
+ newval = val * 1.2;
+ if(newval > 910034) newval = 910034;
+ dmesg.style.width = newval+"%";
+ zoombox.scrollLeft = ((left + sh) * newval / val) - sh;
+ } else if (this.id == "zoomout") {
+ newval = val / 1.2;
+ if(newval < 100) newval = 100;
+ dmesg.style.width = newval+"%";
+ zoombox.scrollLeft = ((left + sh) * newval / val) - sh;
+ } else {
+ zoombox.scrollLeft = 0;
+ dmesg.style.width = "100%";
+ }
+ var tS = [10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1];
+ var t0 = bounds[0];
+ var tMax = bounds[1];
+ var tTotal = tMax - t0;
+ var wTotal = tTotal * 100.0 / newval;
+ var idx = 7*window.innerWidth/1100;
+ for(var i = 0; (i < tS.length)&&((wTotal / tS[i]) < idx); i++);
+ if(i >= tS.length) i = tS.length - 1;
+ if(tS[i] == resolution) return;
+ resolution = tS[i];
+ redrawTimescale(t0, tMax, tS[i]);
+ }
+ function deviceName(title) {
+ var name = title.slice(0, title.indexOf(" ("));
+ return name;
+ }
+ function deviceHover() {
+ var name = deviceName(this.title);
+ var dmesg = document.getElementById("dmesg");
+ var dev = dmesg.getElementsByClassName("thread");
+ var cpu = -1;
+ if(name.match("CPU_ON\[[0-9]*\]"))
+ cpu = parseInt(name.slice(7));
+ else if(name.match("CPU_OFF\[[0-9]*\]"))
+ cpu = parseInt(name.slice(8));
+ for (var i = 0; i < dev.length; i++) {
+ dname = deviceName(dev[i].title);
+ var cname = dev[i].className.slice(dev[i].className.indexOf("thread"));
+ if((cpu >= 0 && dname.match("CPU_O[NF]*\\[*"+cpu+"\\]")) ||
+ (name == dname))
+ {
+ dev[i].className = "hover "+cname;
+ } else {
+ dev[i].className = cname;
+ }
+ }
+ }
+ function deviceUnhover() {
+ var dmesg = document.getElementById("dmesg");
+ var dev = dmesg.getElementsByClassName("thread");
+ for (var i = 0; i < dev.length; i++) {
+ dev[i].className = dev[i].className.slice(dev[i].className.indexOf("thread"));
+ }
+ }
+ function deviceTitle(title, total, cpu) {
+ var prefix = "Total";
+ if(total.length > 3) {
+ prefix = "Average";
+ total[1] = (total[1]+total[3])/2;
+ total[2] = (total[2]+total[4])/2;
+ }
+ var devtitle = document.getElementById("devicedetailtitle");
+ var name = deviceName(title);
+ if(cpu >= 0) name = "CPU"+cpu;
+ var driver = "";
+ var tS = "<t2>(</t2>";
+ var tR = "<t2>)</t2>";
+ if(total[1] > 0)
+ tS = "<t2>("+prefix+" Suspend:</t2><t0> "+total[1].toFixed(3)+" ms</t0> ";
+ if(total[2] > 0)
+ tR = " <t2>"+prefix+" Resume:</t2><t0> "+total[2].toFixed(3)+" ms<t2>)</t2></t0>";
+ var s = title.indexOf("{");
+ var e = title.indexOf("}");
+ if((s >= 0) && (e >= 0))
+ driver = title.slice(s+1, e) + " <t1>@</t1> ";
+ if(total[1] > 0 && total[2] > 0)
+ devtitle.innerHTML = "<t0>"+driver+name+"</t0> "+tS+tR;
+ else
+ devtitle.innerHTML = "<t0>"+title+"</t0>";
+ return name;
+ }
+ function deviceDetail() {
+ var devinfo = document.getElementById("devicedetail");
+ devinfo.style.display = "block";
+ var name = deviceName(this.title);
+ var cpu = -1;
+ if(name.match("CPU_ON\[[0-9]*\]"))
+ cpu = parseInt(name.slice(7));
+ else if(name.match("CPU_OFF\[[0-9]*\]"))
+ cpu = parseInt(name.slice(8));
+ var dmesg = document.getElementById("dmesg");
+ var dev = dmesg.getElementsByClassName("thread");
+ var idlist = [];
+ var pdata = [[]];
+ if(document.getElementById("devicedetail1"))
+ pdata = [[], []];
+ var pd = pdata[0];
+ var total = [0.0, 0.0, 0.0];
+ for (var i = 0; i < dev.length; i++) {
+ dname = deviceName(dev[i].title);
+ if((cpu >= 0 && dname.match("CPU_O[NF]*\\[*"+cpu+"\\]")) ||
+ (name == dname))
+ {
+ idlist[idlist.length] = dev[i].id;
+ var tidx = 1;
+ if(dev[i].id[0] == "a") {
+ pd = pdata[0];
+ } else {
+ if(pdata.length == 1) pdata[1] = [];
+ if(total.length == 3) total[3]=total[4]=0.0;
+ pd = pdata[1];
+ tidx = 3;
+ }
+ var info = dev[i].title.split(" ");
+ var pname = info[info.length-1];
+ pd[pname] = parseFloat(info[info.length-3].slice(1));
+ total[0] += pd[pname];
+ if(pname.indexOf("suspend") >= 0)
+ total[tidx] += pd[pname];
+ else
+ total[tidx+1] += pd[pname];
+ }
+ }
+ var devname = deviceTitle(this.title, total, cpu);
+ var left = 0.0;
+ for (var t = 0; t < pdata.length; t++) {
+ pd = pdata[t];
+ devinfo = document.getElementById("devicedetail"+t);
+ var phases = devinfo.getElementsByClassName("phaselet");
+ for (var i = 0; i < phases.length; i++) {
+ if(phases[i].id in pd) {
+ var w = 100.0*pd[phases[i].id]/total[0];
+ var fs = 32;
+ if(w < 8) fs = 4*w | 0;
+ var fs2 = fs*3/4;
+ phases[i].style.width = w+"%";
+ phases[i].style.left = left+"%";
+ phases[i].title = phases[i].id+" "+pd[phases[i].id]+" ms";
+ left += w;
+ var time = "<t4 style=\"font-size:"+fs+"px\">"+pd[phases[i].id]+" ms<br></t4>";
+ var pname = "<t3 style=\"font-size:"+fs2+"px\">"+phases[i].id.replace(new RegExp("_", "g"), " ")+"</t3>";
+ phases[i].innerHTML = time+pname;
+ } else {
+ phases[i].style.width = "0%";
+ phases[i].style.left = left+"%";
+ }
+ }
+ }
+ if(typeof devstats !== 'undefined')
+ callDetail(this.id, this.title);
+ var cglist = document.getElementById("callgraphs");
+ if(!cglist) return;
+ var cg = cglist.getElementsByClassName("atop");
+ if(cg.length < 10) return;
+ for (var i = 0; i < cg.length; i++) {
+ cgid = cg[i].id.split("x")[0]
+ if(idlist.indexOf(cgid) >= 0) {
+ cg[i].style.display = "block";
+ } else {
+ cg[i].style.display = "none";
+ }
+ }
+ }
+ function callDetail(devid, devtitle) {
+ if(!(devid in devstats) || devstats[devid].length < 1)
+ return;
+ var list = devstats[devid];
+ var tmp = devtitle.split(" ");
+ var name = tmp[0], phase = tmp[tmp.length-1];
+ var dd = document.getElementById(phase);
+ var total = parseFloat(tmp[1].slice(1));
+ var mlist = [];
+ var maxlen = 0;
+ var info = []
+ for(var i in list) {
+ if(list[i][0] == "@") {
+ info = list[i].split("|");
+ continue;
+ }
+ var tmp = list[i].split("|");
+ var t = parseFloat(tmp[0]), f = tmp[1], c = parseInt(tmp[2]);
+ var p = (t*100.0/total).toFixed(2);
+ mlist[mlist.length] = [f, c, t.toFixed(2), p+"%"];
+ if(f.length > maxlen)
+ maxlen = f.length;
+ }
+ var pad = 5;
+ if(mlist.length == 0) pad = 30;
+ var html = '<div style="padding-top:'+pad+'px"><t3> <b>'+name+':</b>';
+ if(info.length > 2)
+ html += " start=<b>"+info[1]+"</b>, end=<b>"+info[2]+"</b>";
+ if(info.length > 3)
+ html += ", length<i>(w/o overhead)</i>=<b>"+info[3]+" ms</b>";
+ if(info.length > 4)
+ html += ", return=<b>"+info[4]+"</b>";
+ html += "</t3></div>";
+ if(mlist.length > 0) {
+ html += '<table class=fstat style="padding-top:'+(maxlen*5)+'px;"><tr><th>Function</th>';
+ for(var i in mlist)
+ html += "<td class=vt>"+mlist[i][0]+"</td>";
+ html += "</tr><tr><th>Calls</th>";
+ for(var i in mlist)
+ html += "<td>"+mlist[i][1]+"</td>";
+ html += "</tr><tr><th>Time(ms)</th>";
+ for(var i in mlist)
+ html += "<td>"+mlist[i][2]+"</td>";
+ html += "</tr><tr><th>Percent</th>";
+ for(var i in mlist)
+ html += "<td>"+mlist[i][3]+"</td>";
+ html += "</tr></table>";
+ }
+ dd.innerHTML = html;
+ var height = (maxlen*5)+100;
+ dd.style.height = height+"px";
+ document.getElementById("devicedetail").style.height = height+"px";
+ }
+ function callSelect() {
+ var cglist = document.getElementById("callgraphs");
+ if(!cglist) return;
+ var cg = cglist.getElementsByClassName("atop");
+ for (var i = 0; i < cg.length; i++) {
+ if(this.id == cg[i].id) {
+ cg[i].style.display = "block";
+ } else {
+ cg[i].style.display = "none";
+ }
+ }
+ }
+ function devListWindow(e) {
+ var win = window.open();
+ var html = "<title>"+e.target.innerHTML+"</title>"+
+ "<style type=\"text/css\">"+
+ " ul {list-style-type:circle;padding-left:10px;margin-left:10px;}"+
+ "</style>"
+ var dt = devtable[0];
+ if(e.target.id != "devlist1")
+ dt = devtable[1];
+ win.document.write(html+dt);
+ }
+ function errWindow() {
+ var range = this.id.split("_");
+ var idx1 = parseInt(range[0]);
+ var idx2 = parseInt(range[1]);
+ var win = window.open();
+ var log = document.getElementById("dmesglog");
+ var title = "<title>dmesg log</title>";
+ var text = log.innerHTML.split("\n");
+ var html = "";
+ for(var i = 0; i < text.length; i++) {
+ if(i == idx1) {
+ html += "<e id=target>"+text[i]+"</e>\n";
+ } else if(i > idx1 && i <= idx2) {
+ html += "<e>"+text[i]+"</e>\n";
+ } else {
+ html += text[i]+"\n";
+ }
+ }
+ win.document.write("<style>e{color:red}</style>"+title+"<pre>"+html+"</pre>");
+ win.location.hash = "#target";
+ win.document.close();
+ }
+ function logWindow(e) {
+ var name = e.target.id.slice(4);
+ var win = window.open();
+ var log = document.getElementById(name+"log");
+ var title = "<title>"+document.title.split(" ")[0]+" "+name+" log</title>";
+ win.document.write(title+"<pre>"+log.innerHTML+"</pre>");
+ win.document.close();
+ }
+ function onMouseDown(e) {
+ dragval[0] = e.clientX;
+ dragval[1] = document.getElementById("dmesgzoombox").scrollLeft;
+ document.onmousemove = onMouseMove;
+ }
+ function onMouseMove(e) {
+ var zoombox = document.getElementById("dmesgzoombox");
+ zoombox.scrollLeft = dragval[1] + dragval[0] - e.clientX;
+ }
+ function onMouseUp(e) {
+ document.onmousemove = null;
+ }
+ function onKeyPress(e) {
+ var c = e.charCode;
+ if(c != 42 && c != 43 && c != 45) return;
+ var click = document.createEvent("Events");
+ click.initEvent("click", true, false);
+ if(c == 43)
+ document.getElementById("zoomin").dispatchEvent(click);
+ else if(c == 45)
+ document.getElementById("zoomout").dispatchEvent(click);
+ else if(c == 42)
+ document.getElementById("zoomdef").dispatchEvent(click);
+ }
+ window.addEventListener("resize", function () {zoomTimeline();});
+ window.addEventListener("load", function () {
+ var dmesg = document.getElementById("dmesg");
+ dmesg.style.width = "100%"
+ dmesg.onmousedown = onMouseDown;
+ document.onmouseup = onMouseUp;
+ document.onkeypress = onKeyPress;
+ document.getElementById("zoomin").onclick = zoomTimeline;
+ document.getElementById("zoomout").onclick = zoomTimeline;
+ document.getElementById("zoomdef").onclick = zoomTimeline;
+ var list = document.getElementsByClassName("err");
+ for (var i = 0; i < list.length; i++)
+ list[i].onclick = errWindow;
+ var list = document.getElementsByClassName("logbtn");
+ for (var i = 0; i < list.length; i++)
+ list[i].onclick = logWindow;
+ list = document.getElementsByClassName("devlist");
+ for (var i = 0; i < list.length; i++)
+ list[i].onclick = devListWindow;
+ var dev = dmesg.getElementsByClassName("thread");
+ for (var i = 0; i < dev.length; i++) {
+ dev[i].onclick = deviceDetail;
+ dev[i].onmouseover = deviceHover;
+ dev[i].onmouseout = deviceUnhover;
+ }
+ var dev = dmesg.getElementsByClassName("srccall");
+ for (var i = 0; i < dev.length; i++)
+ dev[i].onclick = callSelect;
+ zoomTimeline();
+ });
+</script> """
hf.write(script_code);
# Function: executeSuspend
@@ -5524,7 +5525,9 @@ def executeSuspend(quiet=False):
if ((mode == 'freeze') or (sv.memmode == 's2idle')) \
and sv.haveTurbostat():
# execution will pause here
- turbo = sv.turbostat(s0ixready)
+ retval, turbo = sv.turbostat(s0ixready)
+ if retval != 0:
+ tdata['error'] ='turbostat returned %d' % retval
if turbo:
tdata['turbo'] = turbo
else:
@@ -5532,6 +5535,7 @@ def executeSuspend(quiet=False):
pf.write(mode)
# execution will pause here
try:
+ pf.flush()
pf.close()
except Exception as e:
tdata['error'] = str(e)
@@ -5633,7 +5637,7 @@ def deviceInfo(output=''):
tgtval = 'runtime_status'
lines = dict()
for dirname, dirnames, filenames in os.walk('/sys/devices'):
- if(not re.match('.*/power', dirname) or
+ if(not re.match(r'.*/power', dirname) or
'control' not in filenames or
tgtval not in filenames):
continue
@@ -5702,6 +5706,40 @@ def getModes():
fp.close()
return modes
+def dmidecode_backup(out, fatal=False):
+ cpath, spath, info = '/proc/cpuinfo', '/sys/class/dmi/id', {
+ 'bios-vendor': 'bios_vendor',
+ 'bios-version': 'bios_version',
+ 'bios-release-date': 'bios_date',
+ 'system-manufacturer': 'sys_vendor',
+ 'system-product-name': 'product_name',
+ 'system-version': 'product_version',
+ 'system-serial-number': 'product_serial',
+ 'baseboard-manufacturer': 'board_vendor',
+ 'baseboard-product-name': 'board_name',
+ 'baseboard-version': 'board_version',
+ 'baseboard-serial-number': 'board_serial',
+ 'chassis-manufacturer': 'chassis_vendor',
+ 'chassis-version': 'chassis_version',
+ 'chassis-serial-number': 'chassis_serial',
+ }
+ for key in info:
+ if key not in out:
+ val = sysvals.getVal(os.path.join(spath, info[key])).strip()
+ if val and val.lower() != 'to be filled by o.e.m.':
+ out[key] = val
+ if 'processor-version' not in out and os.path.exists(cpath):
+ with open(cpath, 'r') as fp:
+ for line in fp:
+ m = re.match(r'^model\s*name\s*\:\s*(?P<c>.*)', line)
+ if m:
+ out['processor-version'] = m.group('c').strip()
+ break
+ if fatal and len(out) < 1:
+ doError('dmidecode failed to get info from %s or %s' % \
+ (sysvals.mempath, spath))
+ return out
+
# Function: dmidecode
# Description:
# Read the bios tables and pull out system info
@@ -5712,6 +5750,8 @@ def getModes():
# A dict object with all available key/values
def dmidecode(mempath, fatal=False):
out = dict()
+ if(not (os.path.exists(mempath) and os.access(mempath, os.R_OK))):
+ return dmidecode_backup(out, fatal)
# the list of values to retrieve, with hardcoded (type, idx)
info = {
@@ -5727,24 +5767,14 @@ def dmidecode(mempath, fatal=False):
'baseboard-version': (2, 6),
'baseboard-serial-number': (2, 7),
'chassis-manufacturer': (3, 4),
- 'chassis-type': (3, 5),
'chassis-version': (3, 6),
'chassis-serial-number': (3, 7),
'processor-manufacturer': (4, 7),
'processor-version': (4, 16),
}
- if(not os.path.exists(mempath)):
- if(fatal):
- doError('file does not exist: %s' % mempath)
- return out
- if(not os.access(mempath, os.R_OK)):
- if(fatal):
- doError('file is not readable: %s' % mempath)
- return out
# by default use legacy scan, but try to use EFI first
- memaddr = 0xf0000
- memsize = 0x10000
+ memaddr, memsize = 0xf0000, 0x10000
for ep in ['/sys/firmware/efi/systab', '/proc/efi/systab']:
if not os.path.exists(ep) or not os.access(ep, os.R_OK):
continue
@@ -5765,11 +5795,7 @@ def dmidecode(mempath, fatal=False):
fp.seek(memaddr)
buf = fp.read(memsize)
except:
- if(fatal):
- doError('DMI table is unreachable, sorry')
- else:
- pprint('WARNING: /dev/mem is not readable, ignoring DMI data')
- return out
+ return dmidecode_backup(out, fatal)
fp.close()
# search for either an SM table or DMI table
@@ -5785,10 +5811,7 @@ def dmidecode(mempath, fatal=False):
break
i += 16
if base == 0 and length == 0 and num == 0:
- if(fatal):
- doError('Neither SMBIOS nor DMI were found')
- else:
- return out
+ return dmidecode_backup(out, fatal)
# read in the SM or DMI table
try:
@@ -5796,11 +5819,7 @@ def dmidecode(mempath, fatal=False):
fp.seek(base)
buf = fp.read(length)
except:
- if(fatal):
- doError('DMI table is unreachable, sorry')
- else:
- pprint('WARNING: /dev/mem is not readable, ignoring DMI data')
- return out
+ return dmidecode_backup(out, fatal)
fp.close()
# scan the table for the values we want
@@ -6272,7 +6291,10 @@ def find_in_html(html, start, end, firstonly=True):
return out
def data_from_html(file, outpath, issues, fulldetail=False):
- html = open(file, 'r').read()
+ try:
+ html = open(file, 'r').read()
+ except:
+ html = ascii(open(file, 'rb').read())
sysvals.htmlfile = os.path.relpath(file, outpath)
# extract general info
suspend = find_in_html(html, 'Kernel Suspend', 'ms')
@@ -6290,7 +6312,7 @@ def data_from_html(file, outpath, issues, fulldetail=False):
tstr = dt.strftime('%Y/%m/%d %H:%M:%S')
error = find_in_html(html, '<table class="testfail"><tr><td>', '</td>')
if error:
- m = re.match('[a-z0-9]* failed in (?P<p>\S*).*', error)
+ m = re.match(r'[a-z0-9]* failed in (?P<p>\S*).*', error)
if m:
result = 'fail in %s' % m.group('p')
else:
@@ -6307,8 +6329,9 @@ def data_from_html(file, outpath, issues, fulldetail=False):
d.end = 999999999
d.dmesgtext = log.split('\n')
tp = d.extractErrorInfo()
- for msg in tp.msglist:
- sysvals.errorSummary(issues, msg)
+ if len(issues) < 100:
+ for msg in tp.msglist:
+ sysvals.errorSummary(issues, msg)
if stmp[2] == 'freeze':
extra = d.turbostatInfo()
elist = dict()
@@ -6325,6 +6348,11 @@ def data_from_html(file, outpath, issues, fulldetail=False):
line = find_in_html(log, '# netfix ', '\n')
if line:
extra['netfix'] = line
+ line = find_in_html(log, '# command ', '\n')
+ if line:
+ m = re.match(r'.* -m (?P<m>\S*).*', line)
+ if m:
+ extra['fullmode'] = m.group('m')
low = find_in_html(html, 'freeze time: <b>', ' ms</b>')
for lowstr in ['waking', '+']:
if not low:
@@ -6334,7 +6362,7 @@ def data_from_html(file, outpath, issues, fulldetail=False):
if lowstr == '+':
issue = 'S2LOOPx%d' % len(low.split('+'))
else:
- m = re.match('.*waking *(?P<n>[0-9]*) *times.*', low)
+ m = re.match(r'.*waking *(?P<n>[0-9]*) *times.*', low)
issue = 'S2WAKEx%s' % m.group('n') if m else 'S2WAKExNaN'
match = [i for i in issues if i['match'] == issue]
if len(match) > 0:
@@ -6352,10 +6380,10 @@ def data_from_html(file, outpath, issues, fulldetail=False):
# extract device info
devices = dict()
for line in html.split('\n'):
- m = re.match(' *<div id=\"[a,0-9]*\" *title=\"(?P<title>.*)\" class=\"thread.*', line)
+ m = re.match(r' *<div id=\"[a,0-9]*\" *title=\"(?P<title>.*)\" class=\"thread.*', line)
if not m or 'thread kth' in line or 'thread sec' in line:
continue
- m = re.match('(?P<n>.*) \((?P<t>[0-9,\.]*) ms\) (?P<p>.*)', m.group('title'))
+ m = re.match(r'(?P<n>.*) \((?P<t>[0-9,\.]*) ms\) (?P<p>.*)', m.group('title'))
if not m:
continue
name, time, phase = m.group('n'), m.group('t'), m.group('p')
@@ -6416,9 +6444,9 @@ def genHtml(subdir, force=False):
for filename in filenames:
file = os.path.join(dirname, filename)
if sysvals.usable(file):
- if(re.match('.*_dmesg.txt', filename)):
+ if(re.match(r'.*_dmesg.txt', filename)):
sysvals.dmesgfile = file
- elif(re.match('.*_ftrace.txt', filename)):
+ elif(re.match(r'.*_ftrace.txt', filename)):
sysvals.ftracefile = file
sysvals.setOutputFile()
if (sysvals.dmesgfile or sysvals.ftracefile) and sysvals.htmlfile and \
@@ -6441,7 +6469,7 @@ def runSummary(subdir, local=True, genhtml=False):
desc = {'host':[],'mode':[],'kernel':[]}
for dirname, dirnames, filenames in os.walk(subdir):
for filename in filenames:
- if(not re.match('.*.html', filename)):
+ if(not re.match(r'.*.html', filename)):
continue
data = data_from_html(os.path.join(dirname, filename), outpath, issues)
if(not data):
diff --git a/tools/testing/cxl/test/mem.c b/tools/testing/cxl/test/mem.c
index 6584443144de..eaf091a3d331 100644
--- a/tools/testing/cxl/test/mem.c
+++ b/tools/testing/cxl/test/mem.c
@@ -3,6 +3,7 @@
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
+#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/sizes.h>
diff --git a/tools/testing/selftests/alsa/Makefile b/tools/testing/selftests/alsa/Makefile
index 5af9ba8a4645..c1ce39874e2b 100644
--- a/tools/testing/selftests/alsa/Makefile
+++ b/tools/testing/selftests/alsa/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
#
-CFLAGS += $(shell pkg-config --cflags alsa)
+CFLAGS += $(shell pkg-config --cflags alsa) $(KHDR_INCLUDES)
LDLIBS += $(shell pkg-config --libs alsa)
ifeq ($(LDLIBS),)
LDLIBS += -lasound
diff --git a/tools/testing/selftests/bpf/prog_tests/tc_netkit.c b/tools/testing/selftests/bpf/prog_tests/tc_netkit.c
index 15ee7b2fc410..b9135720024c 100644
--- a/tools/testing/selftests/bpf/prog_tests/tc_netkit.c
+++ b/tools/testing/selftests/bpf/prog_tests/tc_netkit.c
@@ -73,6 +73,16 @@ static int create_netkit(int mode, int policy, int peer_policy, int *ifindex,
"up primary");
ASSERT_OK(system("ip addr add dev " netkit_name " 10.0.0.1/24"),
"addr primary");
+
+ if (mode == NETKIT_L3) {
+ ASSERT_EQ(system("ip link set dev " netkit_name
+ " addr ee:ff:bb:cc:aa:dd 2> /dev/null"), 512,
+ "set hwaddress");
+ } else {
+ ASSERT_OK(system("ip link set dev " netkit_name
+ " addr ee:ff:bb:cc:aa:dd"),
+ "set hwaddress");
+ }
if (same_netns) {
ASSERT_OK(system("ip link set dev " netkit_peer " up"),
"up peer");
@@ -89,6 +99,16 @@ static int create_netkit(int mode, int policy, int peer_policy, int *ifindex,
return err;
}
+static void move_netkit(void)
+{
+ ASSERT_OK(system("ip link set " netkit_peer " netns foo"),
+ "move peer");
+ ASSERT_OK(system("ip netns exec foo ip link set dev "
+ netkit_peer " up"), "up peer");
+ ASSERT_OK(system("ip netns exec foo ip addr add dev "
+ netkit_peer " 10.0.0.2/24"), "addr peer");
+}
+
static void destroy_netkit(void)
{
ASSERT_OK(system("ip link del dev " netkit_name), "del primary");
@@ -685,3 +705,77 @@ void serial_test_tc_netkit_neigh_links(void)
serial_test_tc_netkit_neigh_links_target(NETKIT_L2, BPF_NETKIT_PRIMARY);
serial_test_tc_netkit_neigh_links_target(NETKIT_L3, BPF_NETKIT_PRIMARY);
}
+
+static void serial_test_tc_netkit_pkt_type_mode(int mode)
+{
+ LIBBPF_OPTS(bpf_netkit_opts, optl_nk);
+ LIBBPF_OPTS(bpf_tcx_opts, optl_tcx);
+ int err, ifindex, ifindex2;
+ struct test_tc_link *skel;
+ struct bpf_link *link;
+
+ err = create_netkit(mode, NETKIT_PASS, NETKIT_PASS,
+ &ifindex, true);
+ if (err)
+ return;
+
+ ifindex2 = if_nametoindex(netkit_peer);
+ ASSERT_NEQ(ifindex, ifindex2, "ifindex_1_2");
+
+ skel = test_tc_link__open();
+ if (!ASSERT_OK_PTR(skel, "skel_open"))
+ goto cleanup;
+
+ ASSERT_EQ(bpf_program__set_expected_attach_type(skel->progs.tc1,
+ BPF_NETKIT_PRIMARY), 0, "tc1_attach_type");
+ ASSERT_EQ(bpf_program__set_expected_attach_type(skel->progs.tc7,
+ BPF_TCX_INGRESS), 0, "tc7_attach_type");
+
+ err = test_tc_link__load(skel);
+ if (!ASSERT_OK(err, "skel_load"))
+ goto cleanup;
+
+ assert_mprog_count_ifindex(ifindex, BPF_NETKIT_PRIMARY, 0);
+ assert_mprog_count_ifindex(ifindex2, BPF_TCX_INGRESS, 0);
+
+ link = bpf_program__attach_netkit(skel->progs.tc1, ifindex, &optl_nk);
+ if (!ASSERT_OK_PTR(link, "link_attach"))
+ goto cleanup;
+
+ skel->links.tc1 = link;
+
+ assert_mprog_count_ifindex(ifindex, BPF_NETKIT_PRIMARY, 1);
+ assert_mprog_count_ifindex(ifindex2, BPF_TCX_INGRESS, 0);
+
+ link = bpf_program__attach_tcx(skel->progs.tc7, ifindex2, &optl_tcx);
+ if (!ASSERT_OK_PTR(link, "link_attach"))
+ goto cleanup;
+
+ skel->links.tc7 = link;
+
+ assert_mprog_count_ifindex(ifindex, BPF_NETKIT_PRIMARY, 1);
+ assert_mprog_count_ifindex(ifindex2, BPF_TCX_INGRESS, 1);
+
+ move_netkit();
+
+ tc_skel_reset_all_seen(skel);
+ skel->bss->set_type = true;
+ ASSERT_EQ(send_icmp(), 0, "icmp_pkt");
+
+ ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
+ ASSERT_EQ(skel->bss->seen_tc7, true, "seen_tc7");
+
+ ASSERT_EQ(skel->bss->seen_host, true, "seen_host");
+ ASSERT_EQ(skel->bss->seen_mcast, true, "seen_mcast");
+cleanup:
+ test_tc_link__destroy(skel);
+
+ assert_mprog_count_ifindex(ifindex, BPF_NETKIT_PRIMARY, 0);
+ destroy_netkit();
+}
+
+void serial_test_tc_netkit_pkt_type(void)
+{
+ serial_test_tc_netkit_pkt_type_mode(NETKIT_L2);
+ serial_test_tc_netkit_pkt_type_mode(NETKIT_L3);
+}
diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
index 8269cdee33ae..bf6ca8e3eb13 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
#include <unistd.h>
+#include <pthread.h>
#include <test_progs.h>
#include "uprobe_multi.skel.h"
#include "uprobe_multi_bench.skel.h"
#include "uprobe_multi_usdt.skel.h"
#include "bpf/libbpf_internal.h"
#include "testing_helpers.h"
+#include "../sdt.h"
static char test_data[] = "test_data";
@@ -25,9 +27,17 @@ noinline void uprobe_multi_func_3(void)
asm volatile ("");
}
+noinline void usdt_trigger(void)
+{
+ STAP_PROBE(test, pid_filter_usdt);
+}
+
struct child {
int go[2];
+ int c2p[2]; /* child -> parent channel */
int pid;
+ int tid;
+ pthread_t thread;
};
static void release_child(struct child *child)
@@ -38,6 +48,10 @@ static void release_child(struct child *child)
return;
close(child->go[1]);
close(child->go[0]);
+ if (child->thread)
+ pthread_join(child->thread, NULL);
+ close(child->c2p[0]);
+ close(child->c2p[1]);
if (child->pid > 0)
waitpid(child->pid, &child_status, 0);
}
@@ -63,7 +77,7 @@ static struct child *spawn_child(void)
if (pipe(child.go))
return NULL;
- child.pid = fork();
+ child.pid = child.tid = fork();
if (child.pid < 0) {
release_child(&child);
errno = EINVAL;
@@ -82,6 +96,7 @@ static struct child *spawn_child(void)
uprobe_multi_func_1();
uprobe_multi_func_2();
uprobe_multi_func_3();
+ usdt_trigger();
exit(errno);
}
@@ -89,6 +104,67 @@ static struct child *spawn_child(void)
return &child;
}
+static void *child_thread(void *ctx)
+{
+ struct child *child = ctx;
+ int c = 0, err;
+
+ child->tid = syscall(SYS_gettid);
+
+ /* let parent know we are ready */
+ err = write(child->c2p[1], &c, 1);
+ if (err != 1)
+ pthread_exit(&err);
+
+ /* wait for parent's kick */
+ err = read(child->go[0], &c, 1);
+ if (err != 1)
+ pthread_exit(&err);
+
+ uprobe_multi_func_1();
+ uprobe_multi_func_2();
+ uprobe_multi_func_3();
+ usdt_trigger();
+
+ err = 0;
+ pthread_exit(&err);
+}
+
+static struct child *spawn_thread(void)
+{
+ static struct child child;
+ int c, err;
+
+ /* pipe to notify child to execute the trigger functions */
+ if (pipe(child.go))
+ return NULL;
+ /* pipe to notify parent that child thread is ready */
+ if (pipe(child.c2p)) {
+ close(child.go[0]);
+ close(child.go[1]);
+ return NULL;
+ }
+
+ child.pid = getpid();
+
+ err = pthread_create(&child.thread, NULL, child_thread, &child);
+ if (err) {
+ err = -errno;
+ close(child.go[0]);
+ close(child.go[1]);
+ close(child.c2p[0]);
+ close(child.c2p[1]);
+ errno = -err;
+ return NULL;
+ }
+
+ err = read(child.c2p[0], &c, 1);
+ if (!ASSERT_EQ(err, 1, "child_thread_ready"))
+ return NULL;
+
+ return &child;
+}
+
static void uprobe_multi_test_run(struct uprobe_multi *skel, struct child *child)
{
skel->bss->uprobe_multi_func_1_addr = (__u64) uprobe_multi_func_1;
@@ -103,15 +179,23 @@ static void uprobe_multi_test_run(struct uprobe_multi *skel, struct child *child
* passed at the probe attach.
*/
skel->bss->pid = child ? 0 : getpid();
+ skel->bss->expect_pid = child ? child->pid : 0;
+
+ /* trigger all probes, if we are testing child *process*, just to make
+ * sure that PID filtering doesn't let through activations from wrong
+ * PIDs; when we test child *thread*, we don't want to do this to
+ * avoid double counting number of triggering events
+ */
+ if (!child || !child->thread) {
+ uprobe_multi_func_1();
+ uprobe_multi_func_2();
+ uprobe_multi_func_3();
+ usdt_trigger();
+ }
if (child)
kick_child(child);
- /* trigger all probes */
- uprobe_multi_func_1();
- uprobe_multi_func_2();
- uprobe_multi_func_3();
-
/*
* There are 2 entry and 2 exit probe called for each uprobe_multi_func_[123]
* function and each slepable probe (6) increments uprobe_multi_sleep_result.
@@ -126,8 +210,12 @@ static void uprobe_multi_test_run(struct uprobe_multi *skel, struct child *child
ASSERT_EQ(skel->bss->uprobe_multi_sleep_result, 6, "uprobe_multi_sleep_result");
- if (child)
+ ASSERT_FALSE(skel->bss->bad_pid_seen, "bad_pid_seen");
+
+ if (child) {
ASSERT_EQ(skel->bss->child_pid, child->pid, "uprobe_multi_child_pid");
+ ASSERT_EQ(skel->bss->child_tid, child->tid, "uprobe_multi_child_tid");
+ }
}
static void test_skel_api(void)
@@ -190,8 +278,24 @@ __test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_mul
if (!ASSERT_OK_PTR(skel->links.uprobe_extra, "bpf_program__attach_uprobe_multi"))
goto cleanup;
+ /* Attach (uprobe-backed) USDTs */
+ skel->links.usdt_pid = bpf_program__attach_usdt(skel->progs.usdt_pid, pid, binary,
+ "test", "pid_filter_usdt", NULL);
+ if (!ASSERT_OK_PTR(skel->links.usdt_pid, "attach_usdt_pid"))
+ goto cleanup;
+
+ skel->links.usdt_extra = bpf_program__attach_usdt(skel->progs.usdt_extra, -1, binary,
+ "test", "pid_filter_usdt", NULL);
+ if (!ASSERT_OK_PTR(skel->links.usdt_extra, "attach_usdt_extra"))
+ goto cleanup;
+
uprobe_multi_test_run(skel, child);
+ ASSERT_FALSE(skel->bss->bad_pid_seen_usdt, "bad_pid_seen_usdt");
+ if (child) {
+ ASSERT_EQ(skel->bss->child_pid_usdt, child->pid, "usdt_multi_child_pid");
+ ASSERT_EQ(skel->bss->child_tid_usdt, child->tid, "usdt_multi_child_tid");
+ }
cleanup:
uprobe_multi__destroy(skel);
}
@@ -210,6 +314,13 @@ test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_multi
return;
__test_attach_api(binary, pattern, opts, child);
+
+ /* pid filter (thread) */
+ child = spawn_thread();
+ if (!ASSERT_OK_PTR(child, "spawn_thread"))
+ return;
+
+ __test_attach_api(binary, pattern, opts, child);
}
static void test_attach_api_pattern(void)
@@ -397,7 +508,7 @@ static void test_attach_api_fails(void)
link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &opts);
if (!ASSERT_ERR(link_fd, "link_fd"))
goto cleanup;
- ASSERT_EQ(link_fd, -ESRCH, "pid_is_wrong");
+ ASSERT_EQ(link_fd, -EINVAL, "pid_is_wrong");
cleanup:
if (link_fd >= 0)
@@ -495,6 +606,13 @@ static void test_link_api(void)
return;
__test_link_api(child);
+
+ /* pid filter (thread) */
+ child = spawn_thread();
+ if (!ASSERT_OK_PTR(child, "spawn_thread"))
+ return;
+
+ __test_link_api(child);
}
static void test_bench_attach_uprobe(void)
diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index c60db8beeb73..1c9c4ec1be11 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -67,6 +67,7 @@
#include "verifier_search_pruning.skel.h"
#include "verifier_sock.skel.h"
#include "verifier_sock_addr.skel.h"
+#include "verifier_sockmap_mutate.skel.h"
#include "verifier_spill_fill.skel.h"
#include "verifier_spin_lock.skel.h"
#include "verifier_stack_ptr.skel.h"
@@ -183,6 +184,7 @@ void test_verifier_sdiv(void) { RUN(verifier_sdiv); }
void test_verifier_search_pruning(void) { RUN(verifier_search_pruning); }
void test_verifier_sock(void) { RUN(verifier_sock); }
void test_verifier_sock_addr(void) { RUN(verifier_sock_addr); }
+void test_verifier_sockmap_mutate(void) { RUN(verifier_sockmap_mutate); }
void test_verifier_spill_fill(void) { RUN(verifier_spill_fill); }
void test_verifier_spin_lock(void) { RUN(verifier_spin_lock); }
void test_verifier_stack_ptr(void) { RUN(verifier_stack_ptr); }
diff --git a/tools/testing/selftests/bpf/progs/test_tc_link.c b/tools/testing/selftests/bpf/progs/test_tc_link.c
index 992400acb957..ab3eae3d6af8 100644
--- a/tools/testing/selftests/bpf/progs/test_tc_link.c
+++ b/tools/testing/selftests/bpf/progs/test_tc_link.c
@@ -4,7 +4,8 @@
#include <linux/bpf.h>
#include <linux/if_ether.h>
-
+#include <linux/stddef.h>
+#include <linux/if_packet.h>
#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>
@@ -16,7 +17,13 @@ bool seen_tc3;
bool seen_tc4;
bool seen_tc5;
bool seen_tc6;
+bool seen_tc7;
+
+bool set_type;
+
bool seen_eth;
+bool seen_host;
+bool seen_mcast;
SEC("tc/ingress")
int tc1(struct __sk_buff *skb)
@@ -28,8 +35,16 @@ int tc1(struct __sk_buff *skb)
if (bpf_skb_load_bytes(skb, 0, &eth, sizeof(eth)))
goto out;
seen_eth = eth.h_proto == bpf_htons(ETH_P_IP);
+ seen_host = skb->pkt_type == PACKET_HOST;
+ if (seen_host && set_type) {
+ eth.h_dest[0] = 4;
+ if (bpf_skb_store_bytes(skb, 0, &eth, sizeof(eth), 0))
+ goto fail;
+ bpf_skb_change_type(skb, PACKET_MULTICAST);
+ }
out:
seen_tc1 = true;
+fail:
return TCX_NEXT;
}
@@ -67,3 +82,21 @@ int tc6(struct __sk_buff *skb)
seen_tc6 = true;
return TCX_PASS;
}
+
+SEC("tc/ingress")
+int tc7(struct __sk_buff *skb)
+{
+ struct ethhdr eth = {};
+
+ if (skb->protocol != __bpf_constant_htons(ETH_P_IP))
+ goto out;
+ if (bpf_skb_load_bytes(skb, 0, &eth, sizeof(eth)))
+ goto out;
+ if (eth.h_dest[0] == 4 && set_type) {
+ seen_mcast = skb->pkt_type == PACKET_MULTICAST;
+ bpf_skb_change_type(skb, PACKET_HOST);
+ }
+out:
+ seen_tc7 = true;
+ return TCX_PASS;
+}
diff --git a/tools/testing/selftests/bpf/progs/uprobe_multi.c b/tools/testing/selftests/bpf/progs/uprobe_multi.c
index 419d9aa28fce..44190efcdba2 100644
--- a/tools/testing/selftests/bpf/progs/uprobe_multi.c
+++ b/tools/testing/selftests/bpf/progs/uprobe_multi.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
-#include <linux/bpf.h>
+#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
-#include <stdbool.h>
+#include <bpf/usdt.bpf.h>
char _license[] SEC("license") = "GPL";
@@ -22,6 +22,13 @@ __u64 uprobe_multi_sleep_result = 0;
int pid = 0;
int child_pid = 0;
+int child_tid = 0;
+int child_pid_usdt = 0;
+int child_tid_usdt = 0;
+
+int expect_pid = 0;
+bool bad_pid_seen = false;
+bool bad_pid_seen_usdt = false;
bool test_cookie = false;
void *user_ptr = 0;
@@ -36,11 +43,19 @@ static __always_inline bool verify_sleepable_user_copy(void)
static void uprobe_multi_check(void *ctx, bool is_return, bool is_sleep)
{
- child_pid = bpf_get_current_pid_tgid() >> 32;
+ __u64 cur_pid_tgid = bpf_get_current_pid_tgid();
+ __u32 cur_pid;
- if (pid && child_pid != pid)
+ cur_pid = cur_pid_tgid >> 32;
+ if (pid && cur_pid != pid)
return;
+ if (expect_pid && cur_pid != expect_pid)
+ bad_pid_seen = true;
+
+ child_pid = cur_pid_tgid >> 32;
+ child_tid = (__u32)cur_pid_tgid;
+
__u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
__u64 addr = bpf_get_func_ip(ctx);
@@ -97,5 +112,32 @@ int uretprobe_sleep(struct pt_regs *ctx)
SEC("uprobe.multi//proc/self/exe:uprobe_multi_func_*")
int uprobe_extra(struct pt_regs *ctx)
{
+ /* we need this one just to mix PID-filtered and global uprobes */
+ return 0;
+}
+
+SEC("usdt")
+int usdt_pid(struct pt_regs *ctx)
+{
+ __u64 cur_pid_tgid = bpf_get_current_pid_tgid();
+ __u32 cur_pid;
+
+ cur_pid = cur_pid_tgid >> 32;
+ if (pid && cur_pid != pid)
+ return 0;
+
+ if (expect_pid && cur_pid != expect_pid)
+ bad_pid_seen_usdt = true;
+
+ child_pid_usdt = cur_pid_tgid >> 32;
+ child_tid_usdt = (__u32)cur_pid_tgid;
+
+ return 0;
+}
+
+SEC("usdt")
+int usdt_extra(struct pt_regs *ctx)
+{
+ /* we need this one just to mix PID-filtered and global USDT probes */
return 0;
}
diff --git a/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c b/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c
new file mode 100644
index 000000000000..fe4b123187b8
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/verifier_sockmap_mutate.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+#include "bpf_misc.h"
+
+#define __always_unused __attribute__((unused))
+
+char _license[] SEC("license") = "GPL";
+
+struct sock {
+} __attribute__((preserve_access_index));
+
+struct bpf_iter__sockmap {
+ union {
+ struct sock *sk;
+ };
+} __attribute__((preserve_access_index));
+
+struct {
+ __uint(type, BPF_MAP_TYPE_SOCKHASH);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, int);
+} sockhash SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_SOCKMAP);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, int);
+} sockmap SEC(".maps");
+
+enum { CG_OK = 1 };
+
+int zero = 0;
+
+static __always_inline void test_sockmap_delete(void)
+{
+ bpf_map_delete_elem(&sockmap, &zero);
+ bpf_map_delete_elem(&sockhash, &zero);
+}
+
+static __always_inline void test_sockmap_update(void *sk)
+{
+ if (sk) {
+ bpf_map_update_elem(&sockmap, &zero, sk, BPF_ANY);
+ bpf_map_update_elem(&sockhash, &zero, sk, BPF_ANY);
+ }
+}
+
+static __always_inline void test_sockmap_lookup_and_update(void)
+{
+ struct bpf_sock *sk = bpf_map_lookup_elem(&sockmap, &zero);
+
+ if (sk) {
+ test_sockmap_update(sk);
+ bpf_sk_release(sk);
+ }
+}
+
+static __always_inline void test_sockmap_mutate(void *sk)
+{
+ test_sockmap_delete();
+ test_sockmap_update(sk);
+}
+
+static __always_inline void test_sockmap_lookup_and_mutate(void)
+{
+ test_sockmap_delete();
+ test_sockmap_lookup_and_update();
+}
+
+SEC("action")
+__success
+int test_sched_act(struct __sk_buff *skb)
+{
+ test_sockmap_mutate(skb->sk);
+ return 0;
+}
+
+SEC("classifier")
+__success
+int test_sched_cls(struct __sk_buff *skb)
+{
+ test_sockmap_mutate(skb->sk);
+ return 0;
+}
+
+SEC("flow_dissector")
+__success
+int test_flow_dissector_delete(struct __sk_buff *skb __always_unused)
+{
+ test_sockmap_delete();
+ return 0;
+}
+
+SEC("flow_dissector")
+__failure __msg("program of this type cannot use helper bpf_sk_release")
+int test_flow_dissector_update(struct __sk_buff *skb __always_unused)
+{
+ test_sockmap_lookup_and_update(); /* no access to skb->sk */
+ return 0;
+}
+
+SEC("iter/sockmap")
+__success
+int test_trace_iter(struct bpf_iter__sockmap *ctx)
+{
+ test_sockmap_mutate(ctx->sk);
+ return 0;
+}
+
+SEC("raw_tp/kfree")
+__failure __msg("cannot update sockmap in this context")
+int test_raw_tp_delete(const void *ctx __always_unused)
+{
+ test_sockmap_delete();
+ return 0;
+}
+
+SEC("raw_tp/kfree")
+__failure __msg("cannot update sockmap in this context")
+int test_raw_tp_update(const void *ctx __always_unused)
+{
+ test_sockmap_lookup_and_update();
+ return 0;
+}
+
+SEC("sk_lookup")
+__success
+int test_sk_lookup(struct bpf_sk_lookup *ctx)
+{
+ test_sockmap_mutate(ctx->sk);
+ return 0;
+}
+
+SEC("sk_reuseport")
+__success
+int test_sk_reuseport(struct sk_reuseport_md *ctx)
+{
+ test_sockmap_mutate(ctx->sk);
+ return 0;
+}
+
+SEC("socket")
+__success
+int test_socket_filter(struct __sk_buff *skb)
+{
+ test_sockmap_mutate(skb->sk);
+ return 0;
+}
+
+SEC("sockops")
+__success
+int test_sockops_delete(struct bpf_sock_ops *ctx __always_unused)
+{
+ test_sockmap_delete();
+ return CG_OK;
+}
+
+SEC("sockops")
+__failure __msg("cannot update sockmap in this context")
+int test_sockops_update(struct bpf_sock_ops *ctx)
+{
+ test_sockmap_update(ctx->sk);
+ return CG_OK;
+}
+
+SEC("sockops")
+__success
+int test_sockops_update_dedicated(struct bpf_sock_ops *ctx)
+{
+ bpf_sock_map_update(ctx, &sockmap, &zero, BPF_ANY);
+ bpf_sock_hash_update(ctx, &sockhash, &zero, BPF_ANY);
+ return CG_OK;
+}
+
+SEC("xdp")
+__success
+int test_xdp(struct xdp_md *ctx __always_unused)
+{
+ test_sockmap_lookup_and_mutate();
+ return XDP_PASS;
+}
diff --git a/tools/testing/selftests/cachestat/test_cachestat.c b/tools/testing/selftests/cachestat/test_cachestat.c
index b171fd53b004..632ab44737ec 100644
--- a/tools/testing/selftests/cachestat/test_cachestat.c
+++ b/tools/testing/selftests/cachestat/test_cachestat.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
+#define __SANE_USERSPACE_TYPES__ // Use ll64
#include <stdio.h>
#include <stdbool.h>
diff --git a/tools/testing/selftests/filesystems/overlayfs/dev_in_maps.c b/tools/testing/selftests/filesystems/overlayfs/dev_in_maps.c
index 759f86e7d263..2862aae58b79 100644
--- a/tools/testing/selftests/filesystems/overlayfs/dev_in_maps.c
+++ b/tools/testing/selftests/filesystems/overlayfs/dev_in_maps.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
+#define __SANE_USERSPACE_TYPES__ // Use ll64
#include <inttypes.h>
#include <unistd.h>
diff --git a/tools/testing/selftests/ftrace/config b/tools/testing/selftests/ftrace/config
index e59d985eeff0..048a312abf40 100644
--- a/tools/testing/selftests/ftrace/config
+++ b/tools/testing/selftests/ftrace/config
@@ -1,16 +1,28 @@
-CONFIG_KPROBES=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_DEBUG_INFO_BTF=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_EPROBE_EVENTS=y
+CONFIG_FPROBE=y
+CONFIG_FPROBE_EVENTS=y
CONFIG_FTRACE=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_FUNCTION_GRAPH_RETVAL=y
CONFIG_FUNCTION_PROFILER=y
-CONFIG_TRACER_SNAPSHOT=y
-CONFIG_STACK_TRACER=y
CONFIG_HIST_TRIGGERS=y
-CONFIG_SCHED_TRACER=y
-CONFIG_PREEMPT_TRACER=y
CONFIG_IRQSOFF_TRACER=y
-CONFIG_PREEMPTIRQ_DELAY_TEST=m
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KPROBES=y
+CONFIG_KPROBE_EVENTS=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
+CONFIG_PREEMPTIRQ_DELAY_TEST=m
+CONFIG_PREEMPT_TRACER=y
+CONFIG_PROBE_EVENTS_BTF_ARGS=y
CONFIG_SAMPLES=y
CONFIG_SAMPLE_FTRACE_DIRECT=m
CONFIG_SAMPLE_TRACE_PRINTK=m
-CONFIG_KALLSYMS_ALL=y
+CONFIG_SCHED_TRACER=y
+CONFIG_STACK_TRACER=y
+CONFIG_TRACER_SNAPSHOT=y
+CONFIG_UPROBES=y
+CONFIG_UPROBE_EVENTS=y
diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc b/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
index d3a79da215c8..5f72abe6fa79 100644
--- a/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
+++ b/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
@@ -1,7 +1,7 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: Generic dynamic event - check if duplicate events are caught
-# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
+# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README events/syscalls/sys_enter_openat
echo 0 > events/enable
diff --git a/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc b/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc
index 3f74c09c56b6..118247b8dd84 100644
--- a/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc
+++ b/tools/testing/selftests/ftrace/test.d/filter/event-filter-function.tc
@@ -10,7 +10,6 @@ fail() { #msg
}
sample_events() {
- echo > trace
echo 1 > events/kmem/kmem_cache_free/enable
echo 1 > tracing_on
ls > /dev/null
@@ -22,6 +21,7 @@ echo 0 > tracing_on
echo 0 > events/enable
echo "Get the most frequently calling function"
+echo > trace
sample_events
target_func=`cat trace | grep -o 'call_site=\([^+]*\)' | sed 's/call_site=//' | sort | uniq -c | sort | tail -n 1 | sed 's/^[ 0-9]*//'`
@@ -32,7 +32,16 @@ echo > trace
echo "Test event filter function name"
echo "call_site.function == $target_func" > events/kmem/kmem_cache_free/filter
+
+sample_events
+max_retry=10
+while [ `grep kmem_cache_free trace| wc -l` -eq 0 ]; do
sample_events
+max_retry=$((max_retry - 1))
+if [ $max_retry -eq 0 ]; then
+ exit_fail
+fi
+done
hitcnt=`grep kmem_cache_free trace| grep $target_func | wc -l`
misscnt=`grep kmem_cache_free trace| grep -v $target_func | wc -l`
@@ -49,7 +58,16 @@ address=`grep " ${target_func}\$" /proc/kallsyms | cut -d' ' -f1`
echo "Test event filter function address"
echo "call_site.function == 0x$address" > events/kmem/kmem_cache_free/filter
+echo > trace
+sample_events
+max_retry=10
+while [ `grep kmem_cache_free trace| wc -l` -eq 0 ]; do
sample_events
+max_retry=$((max_retry - 1))
+if [ $max_retry -eq 0 ]; then
+ exit_fail
+fi
+done
hitcnt=`grep kmem_cache_free trace| grep $target_func | wc -l`
misscnt=`grep kmem_cache_free trace| grep -v $target_func | wc -l`
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
index 1f6981ef7afa..ba19b81cef39 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
@@ -30,7 +30,8 @@ find_dot_func() {
fi
grep " [tT] .*\.isra\..*" /proc/kallsyms | cut -f 3 -d " " | while read f; do
- if grep -s $f available_filter_functions; then
+ cnt=`grep -s $f available_filter_functions | wc -l`;
+ if [ $cnt -eq 1 ]; then
echo $f
break
fi
diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile
index 11e157d7533b..78ab2cd111f6 100644
--- a/tools/testing/selftests/futex/Makefile
+++ b/tools/testing/selftests/futex/Makefile
@@ -3,8 +3,6 @@ SUBDIRS := functional
TEST_PROGS := run.sh
-.PHONY: all clean
-
include ../lib.mk
all:
diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile
index a392d0917b4e..994fa3468f17 100644
--- a/tools/testing/selftests/futex/functional/Makefile
+++ b/tools/testing/selftests/futex/functional/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
INCLUDES := -I../include -I../../ $(KHDR_INCLUDES)
-CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) $(KHDR_INCLUDES)
+CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE= -pthread $(INCLUDES) $(KHDR_INCLUDES)
LDLIBS := -lpthread -lrt
LOCAL_HDRS := \
diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi.c b/tools/testing/selftests/futex/functional/futex_requeue_pi.c
index 7f3ca5c78df1..215c6cb539b4 100644
--- a/tools/testing/selftests/futex/functional/futex_requeue_pi.c
+++ b/tools/testing/selftests/futex/functional/futex_requeue_pi.c
@@ -360,7 +360,7 @@ out:
int main(int argc, char *argv[])
{
- const char *test_name;
+ char *test_name;
int c, ret;
while ((c = getopt(argc, argv, "bchlot:v:")) != -1) {
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 6b5a9ff88c3d..7d063c652be1 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -35,6 +35,7 @@
* See https://sourceware.org/glibc/wiki/Synchronizing_Headers.
*/
#include <linux/fs.h>
+#include <linux/mount.h>
#include "common.h"
@@ -47,6 +48,13 @@ int renameat2(int olddirfd, const char *oldpath, int newdirfd,
}
#endif
+#ifndef open_tree
+int open_tree(int dfd, const char *filename, unsigned int flags)
+{
+ return syscall(__NR_open_tree, dfd, filename, flags);
+}
+#endif
+
#ifndef RENAME_EXCHANGE
#define RENAME_EXCHANGE (1 << 1)
#endif
@@ -2400,6 +2408,43 @@ TEST_F_FORK(layout1, refer_denied_by_default4)
layer_dir_s1d1_refer);
}
+/*
+ * Tests walking through a denied root mount.
+ */
+TEST_F_FORK(layout1, refer_mount_root_deny)
+{
+ const struct landlock_ruleset_attr ruleset_attr = {
+ .handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_DIR,
+ };
+ int root_fd, ruleset_fd;
+
+ /* Creates a mount object from a non-mount point. */
+ set_cap(_metadata, CAP_SYS_ADMIN);
+ root_fd =
+ open_tree(AT_FDCWD, dir_s1d1,
+ AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
+ clear_cap(_metadata, CAP_SYS_ADMIN);
+ ASSERT_LE(0, root_fd);
+
+ ruleset_fd =
+ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
+ ASSERT_LE(0, ruleset_fd);
+
+ ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
+ ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
+ EXPECT_EQ(0, close(ruleset_fd));
+
+ /* Link denied by Landlock: EACCES. */
+ EXPECT_EQ(-1, linkat(root_fd, ".", root_fd, "does_not_exist", 0));
+ EXPECT_EQ(EACCES, errno);
+
+ /* renameat2() always returns EBUSY. */
+ EXPECT_EQ(-1, renameat2(root_fd, ".", root_fd, "does_not_exist", 0));
+ EXPECT_EQ(EBUSY, errno);
+
+ EXPECT_EQ(0, close(root_fd));
+}
+
TEST_F_FORK(layout1, reparent_link)
{
const struct rule layer1[] = {
diff --git a/tools/testing/selftests/net/hsr/hsr_ping.sh b/tools/testing/selftests/net/hsr/hsr_ping.sh
index 790294c8af83..3684b813b0f6 100755
--- a/tools/testing/selftests/net/hsr/hsr_ping.sh
+++ b/tools/testing/selftests/net/hsr/hsr_ping.sh
@@ -174,6 +174,8 @@ trap cleanup_all_ns EXIT
setup_hsr_interfaces 0
do_complete_ping_test
+setup_ns ns1 ns2 ns3
+
setup_hsr_interfaces 1
do_complete_ping_test
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index fefa9173bdaa..2b66c5fa71eb 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -261,6 +261,8 @@ reset()
TEST_NAME="${1}"
+ MPTCP_LIB_SUBTEST_FLAKY=0 # reset if modified
+
if skip_test; then
MPTCP_LIB_TEST_COUNTER=$((MPTCP_LIB_TEST_COUNTER+1))
last_test_ignored=1
@@ -448,7 +450,9 @@ reset_with_tcp_filter()
# $1: err msg
fail_test()
{
- ret=${KSFT_FAIL}
+ if ! mptcp_lib_subtest_is_flaky; then
+ ret=${KSFT_FAIL}
+ fi
if [ ${#} -gt 0 ]; then
print_fail "${@}"
@@ -3069,6 +3073,7 @@ fullmesh_tests()
fastclose_tests()
{
if reset_check_counter "fastclose test" "MPTcpExtMPFastcloseTx"; then
+ MPTCP_LIB_SUBTEST_FLAKY=1
test_linkfail=1024 fastclose=client \
run_tests $ns1 $ns2 10.0.1.1
chk_join_nr 0 0 0
@@ -3077,6 +3082,7 @@ fastclose_tests()
fi
if reset_check_counter "fastclose server test" "MPTcpExtMPFastcloseRx"; then
+ MPTCP_LIB_SUBTEST_FLAKY=1
test_linkfail=1024 fastclose=server \
run_tests $ns1 $ns2 10.0.1.1
chk_join_nr 0 0 0 0 0 0 1
@@ -3095,6 +3101,7 @@ fail_tests()
{
# single subflow
if reset_with_fail "Infinite map" 1; then
+ MPTCP_LIB_SUBTEST_FLAKY=1
test_linkfail=128 \
run_tests $ns1 $ns2 10.0.1.1
chk_join_nr 0 0 0 +1 +0 1 0 1 "$(pedit_action_pkts)"
@@ -3103,6 +3110,7 @@ fail_tests()
# multiple subflows
if reset_with_fail "MP_FAIL MP_RST" 2; then
+ MPTCP_LIB_SUBTEST_FLAKY=1
tc -n $ns2 qdisc add dev ns2eth1 root netem rate 1mbit delay 5ms
pm_nl_set_limits $ns1 0 1
pm_nl_set_limits $ns2 0 1
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index ad2ebda5cb64..6ffa9b7a3260 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -21,6 +21,7 @@ declare -rx MPTCP_LIB_AF_INET6=10
MPTCP_LIB_SUBTESTS=()
MPTCP_LIB_SUBTESTS_DUPLICATED=0
+MPTCP_LIB_SUBTEST_FLAKY=0
MPTCP_LIB_TEST_COUNTER=0
MPTCP_LIB_TEST_FORMAT="%02u %-50s"
MPTCP_LIB_IP_MPTCP=0
@@ -41,6 +42,16 @@ else
readonly MPTCP_LIB_COLOR_RESET=
fi
+# SELFTESTS_MPTCP_LIB_OVERRIDE_FLAKY env var can be set not to ignore errors
+# from subtests marked as flaky
+mptcp_lib_override_flaky() {
+ [ "${SELFTESTS_MPTCP_LIB_OVERRIDE_FLAKY:-}" = 1 ]
+}
+
+mptcp_lib_subtest_is_flaky() {
+ [ "${MPTCP_LIB_SUBTEST_FLAKY}" = 1 ] && ! mptcp_lib_override_flaky
+}
+
# $1: color, $2: text
mptcp_lib_print_color() {
echo -e "${MPTCP_LIB_START_PRINT:-}${*}${MPTCP_LIB_COLOR_RESET}"
@@ -72,7 +83,16 @@ mptcp_lib_pr_skip() {
}
mptcp_lib_pr_fail() {
- mptcp_lib_print_err "[FAIL]${1:+ ${*}}"
+ local title cmt
+
+ if mptcp_lib_subtest_is_flaky; then
+ title="IGNO"
+ cmt=" (flaky)"
+ else
+ title="FAIL"
+ fi
+
+ mptcp_lib_print_err "[${title}]${cmt}${1:+ ${*}}"
}
mptcp_lib_pr_info() {
@@ -208,7 +228,13 @@ mptcp_lib_result_pass() {
# $1: test name
mptcp_lib_result_fail() {
- __mptcp_lib_result_add "not ok" "${1}"
+ if mptcp_lib_subtest_is_flaky; then
+ # It might sound better to use 'not ok # TODO' or 'ok # SKIP',
+ # but some CIs don't understand 'TODO' and treat SKIP as errors.
+ __mptcp_lib_result_add "ok" "${1} # IGNORE Flaky"
+ else
+ __mptcp_lib_result_add "not ok" "${1}"
+ fi
}
# $1: test name
diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
index 4b14b4412166..f74e1c3c126d 100755
--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -244,7 +244,7 @@ run_test()
do_transfer $small $large $time
lret=$?
mptcp_lib_result_code "${lret}" "${msg}"
- if [ $lret -ne 0 ]; then
+ if [ $lret -ne 0 ] && ! mptcp_lib_subtest_is_flaky; then
ret=$lret
[ $bail -eq 0 ] || exit $ret
fi
@@ -254,7 +254,7 @@ run_test()
do_transfer $large $small $time
lret=$?
mptcp_lib_result_code "${lret}" "${msg}"
- if [ $lret -ne 0 ]; then
+ if [ $lret -ne 0 ] && ! mptcp_lib_subtest_is_flaky; then
ret=$lret
[ $bail -eq 0 ] || exit $ret
fi
@@ -290,7 +290,7 @@ run_test 10 10 0 0 "balanced bwidth"
run_test 10 10 1 25 "balanced bwidth with unbalanced delay"
# we still need some additional infrastructure to pass the following test-cases
-run_test 10 3 0 0 "unbalanced bwidth"
+MPTCP_LIB_SUBTEST_FLAKY=1 run_test 10 3 0 0 "unbalanced bwidth"
run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay"
run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay"
diff --git a/tools/testing/selftests/openat2/openat2_test.c b/tools/testing/selftests/openat2/openat2_test.c
index 9024754530b2..5790ab446527 100644
--- a/tools/testing/selftests/openat2/openat2_test.c
+++ b/tools/testing/selftests/openat2/openat2_test.c
@@ -5,6 +5,7 @@
*/
#define _GNU_SOURCE
+#define __SANE_USERSPACE_TYPES__ // Use ll64
#include <fcntl.h>
#include <sched.h>
#include <sys/stat.h>
diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json
index 12da0a939e3e..557fb074acf0 100644
--- a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json
+++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json
@@ -133,6 +133,50 @@
]
},
{
+ "id": "6f62",
+ "name": "Add taprio Qdisc with too short interval",
+ "category": [
+ "qdisc",
+ "taprio"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "echo \"1 1 8\" > /sys/bus/netdevsim/new_device"
+ ],
+ "cmdUnderTest": "$TC qdisc add dev $ETH root handle 1: taprio num_tc 2 queues 1@0 1@1 sched-entry S 01 300 sched-entry S 02 1700 clockid CLOCK_TAI",
+ "expExitCode": "2",
+ "verifyCmd": "$TC qdisc show dev $ETH",
+ "matchPattern": "qdisc taprio 1: root refcnt",
+ "matchCount": "0",
+ "teardown": [
+ "echo \"1\" > /sys/bus/netdevsim/del_device"
+ ]
+ },
+ {
+ "id": "831f",
+ "name": "Add taprio Qdisc with too short cycle-time",
+ "category": [
+ "qdisc",
+ "taprio"
+ ],
+ "plugins": {
+ "requires": "nsPlugin"
+ },
+ "setup": [
+ "echo \"1 1 8\" > /sys/bus/netdevsim/new_device"
+ ],
+ "cmdUnderTest": "$TC qdisc add dev $ETH root handle 1: taprio num_tc 2 queues 1@0 1@1 sched-entry S 01 200000 sched-entry S 02 200000 cycle-time 100 clockid CLOCK_TAI",
+ "expExitCode": "2",
+ "verifyCmd": "$TC qdisc show dev $ETH",
+ "matchPattern": "qdisc taprio 1: root refcnt",
+ "matchCount": "0",
+ "teardown": [
+ "echo \"1\" > /sys/bus/netdevsim/del_device"
+ ]
+ },
+ {
"id": "3e1e",
"name": "Add taprio Qdisc with an invalid cycle-time",
"category": [