mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-28 04:24:26 +01:00
userland: get a bit closer to perfection
This commit is contained in:
@@ -3811,7 +3811,9 @@ Result on <<p51>> at bad30f513c46c1b0995d3a10c0d9bc2a33dc4fa0:
|
|||||||
* QEMU user: 45 seconds
|
* QEMU user: 45 seconds
|
||||||
* QEMU full system: 223 seconds
|
* QEMU full system: 223 seconds
|
||||||
|
|
||||||
=== QEMU user mode does not show stdout immediately
|
=== QEMU user mode quirks
|
||||||
|
|
||||||
|
==== QEMU user mode does not show stdout immediately
|
||||||
|
|
||||||
At 8d8307ac0710164701f6e14c99a69ee172ccbb70 + 1, I noticed that if you run link:userland/posix/count.c[]:
|
At 8d8307ac0710164701f6e14c99a69ee172ccbb70 + 1, I noticed that if you run link:userland/posix/count.c[]:
|
||||||
|
|
||||||
|
|||||||
25
common.py
25
common.py
@@ -1372,11 +1372,13 @@ class TestResult:
|
|||||||
self,
|
self,
|
||||||
test_id: str ='',
|
test_id: str ='',
|
||||||
status : TestStatus =TestStatus.PASS,
|
status : TestStatus =TestStatus.PASS,
|
||||||
ellapsed_seconds : float =0
|
ellapsed_seconds : float =0,
|
||||||
|
reason : str =''
|
||||||
):
|
):
|
||||||
self.test_id = test_id
|
self.test_id = test_id
|
||||||
self.status = status
|
self.status = status
|
||||||
self.ellapsed_seconds = ellapsed_seconds
|
self.ellapsed_seconds = ellapsed_seconds
|
||||||
|
self.reason = reason
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.test_id == other.test_id
|
return self.test_id == other.test_id
|
||||||
@@ -1385,12 +1387,13 @@ class TestResult:
|
|||||||
return self.test_id < other.test_id
|
return self.test_id < other.test_id
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
out = []
|
out = [
|
||||||
if self.status is not None:
|
self.status.name,
|
||||||
out.append(self.status.name)
|
LkmcCliFunction.seconds_to_hms(self.ellapsed_seconds),
|
||||||
if self.ellapsed_seconds is not None:
|
repr(self.test_id),
|
||||||
out.append(LkmcCliFunction.seconds_to_hms(self.ellapsed_seconds))
|
]
|
||||||
out.append(self.test_id)
|
if self.status is TestStatus.FAIL:
|
||||||
|
out.append(repr(self.reason))
|
||||||
return ' '.join(out)
|
return ' '.join(out)
|
||||||
|
|
||||||
class TestCliFunction(LkmcCliFunction):
|
class TestCliFunction(LkmcCliFunction):
|
||||||
@@ -1455,11 +1458,16 @@ class TestCliFunction(LkmcCliFunction):
|
|||||||
):
|
):
|
||||||
if expected_exit_status is None:
|
if expected_exit_status is None:
|
||||||
expected_exit_status = 0
|
expected_exit_status = 0
|
||||||
|
reason = ''
|
||||||
if not self.env['dry_run']:
|
if not self.env['dry_run']:
|
||||||
if exit_status == expected_exit_status:
|
if exit_status == expected_exit_status:
|
||||||
test_result = TestStatus.PASS
|
test_result = TestStatus.PASS
|
||||||
else:
|
else:
|
||||||
test_result = TestStatus.FAIL
|
test_result = TestStatus.FAIL
|
||||||
|
reason = 'wrong exit status, got {} expected {}'.format(
|
||||||
|
exit_status,
|
||||||
|
expected_exit_status
|
||||||
|
)
|
||||||
ellapsed_seconds = run_obj.ellapsed_seconds
|
ellapsed_seconds = run_obj.ellapsed_seconds
|
||||||
else:
|
else:
|
||||||
test_result = TestStatus.PASS
|
test_result = TestStatus.PASS
|
||||||
@@ -1467,7 +1475,8 @@ class TestCliFunction(LkmcCliFunction):
|
|||||||
test_result = TestResult(
|
test_result = TestResult(
|
||||||
test_id_string,
|
test_id_string,
|
||||||
test_result,
|
test_result,
|
||||||
ellapsed_seconds
|
ellapsed_seconds,
|
||||||
|
reason
|
||||||
)
|
)
|
||||||
self.log_info(test_result)
|
self.log_info(test_result)
|
||||||
self.test_results.put(test_result)
|
self.test_results.put(test_result)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
class ExecutableProperties:
|
class ExecutableProperties:
|
||||||
'''
|
'''
|
||||||
Encodes properties of userland and baremetal examples.
|
Encodes properties of userland and baremetal examples.
|
||||||
@@ -11,26 +13,39 @@ class ExecutableProperties:
|
|||||||
exit_status=0,
|
exit_status=0,
|
||||||
interactive=False,
|
interactive=False,
|
||||||
more_than_1s=False,
|
more_than_1s=False,
|
||||||
|
receives_signal=False,
|
||||||
|
requires_kernel_modules=False,
|
||||||
):
|
):
|
||||||
|
'''
|
||||||
|
:param receives_signal: the test receives a signal. We skip those tests for now,
|
||||||
|
on userland because we are lazy to figure out the exact semantics
|
||||||
|
of how Python + QEMU + gem5 determine the exit status of signals.
|
||||||
|
'''
|
||||||
self.exit_status = exit_status
|
self.exit_status = exit_status
|
||||||
self.interactive = interactive
|
self.interactive = interactive
|
||||||
self.more_than_1s = more_than_1s
|
self.more_than_1s = more_than_1s
|
||||||
|
self.receives_signal = receives_signal
|
||||||
|
self.requires_kernel_modules = requires_kernel_modules
|
||||||
|
|
||||||
def should_be_tested(self):
|
def should_be_tested(self):
|
||||||
return \
|
return \
|
||||||
not self.interactive and \
|
not self.interactive and \
|
||||||
not self.more_than_1s
|
not self.more_than_1s and \
|
||||||
|
not self.receives_signal
|
||||||
|
|
||||||
executable_properties = {
|
executable_properties = {
|
||||||
|
'arch/x86_64/c/ring0.c': ExecutableProperties(receives_signal=True),
|
||||||
'c/assert_fail.c': ExecutableProperties(exit_status=1),
|
'c/assert_fail.c': ExecutableProperties(exit_status=1),
|
||||||
'c/false.c': ExecutableProperties(exit_status=1),
|
'c/false.c': ExecutableProperties(exit_status=1),
|
||||||
'c/infinite_loop.c': ExecutableProperties(more_than_1s=True),
|
'c/infinite_loop.c': ExecutableProperties(more_than_1s=True),
|
||||||
|
'kernel_modules': ExecutableProperties(requires_kernel_modules=True),
|
||||||
'posix/count.c': ExecutableProperties(more_than_1s=True),
|
'posix/count.c': ExecutableProperties(more_than_1s=True),
|
||||||
'posix/sleep_forever.c': ExecutableProperties(more_than_1s=True),
|
'posix/sleep_forever.c': ExecutableProperties(more_than_1s=True),
|
||||||
'posix/virt_to_phys_test.c': ExecutableProperties(more_than_1s=True),
|
'posix/virt_to_phys_test.c': ExecutableProperties(more_than_1s=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get(test_path):
|
def get(test_path):
|
||||||
|
test_path_components = test_path.split(os.sep)
|
||||||
if test_path in executable_properties:
|
if test_path in executable_properties:
|
||||||
return executable_properties[test_path]
|
return executable_properties[test_path]
|
||||||
else:
|
else:
|
||||||
|
|||||||
80
run
80
run
@@ -99,7 +99,20 @@ timestamps.
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'--kdb', default=False,
|
'--graphic',
|
||||||
|
default=False,
|
||||||
|
help='''\
|
||||||
|
Run in graphic mode.
|
||||||
|
See: http://github.com/cirosantilli/linux-kernel-module-cheat#graphics
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
self.add_argument(
|
||||||
|
'--kdb',
|
||||||
|
default=False,
|
||||||
|
help='''\
|
||||||
|
Setup KDB kernel CLI options.
|
||||||
|
See: http://github.com/cirosantilli/linux-kernel-module-cheat#kdb
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'--kernel-cli',
|
'--kernel-cli',
|
||||||
@@ -136,14 +149,26 @@ See: http://github.com/cirosantilli/linux-kernel-module-cheat#fatal-kernel-too-o
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'--kgdb', default=False,
|
'--kgdb',
|
||||||
|
default=False,
|
||||||
|
help='''\
|
||||||
|
Setup KGDB kernel CLI options.
|
||||||
|
See: http://github.com/cirosantilli/linux-kernel-module-cheat#kgdb
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-K', '--kvm', default=False,
|
'-K',
|
||||||
help='Use KVM. Only works if guest arch == host arch'
|
'--kvm',
|
||||||
|
default=False,
|
||||||
|
help='''\
|
||||||
|
Use KVM. Only works if guest arch == host arch.
|
||||||
|
See: http://github.com/cirosantilli/linux-kernel-module-cheat#kvm
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-m', '--memory', default='256M',
|
'-m',
|
||||||
|
'--memory',
|
||||||
|
default='256M',
|
||||||
help='''\
|
help='''\
|
||||||
Set the memory size of the guest. E.g.: `-m 512M`. We try to keep the default
|
Set the memory size of the guest. E.g.: `-m 512M`. We try to keep the default
|
||||||
at the minimal ammount amount that boots all archs. Anything lower could lead
|
at the minimal ammount amount that boots all archs. Anything lower could lead
|
||||||
@@ -159,19 +184,25 @@ Setup a kernel init parameter that makes the emulator quit immediately after boo
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-R', '--replay', default=False,
|
'-R',
|
||||||
|
'--replay',
|
||||||
|
default=False,
|
||||||
help='Replay a QEMU run record deterministically'
|
help='Replay a QEMU run record deterministically'
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-r', '--record', default=False,
|
'-r',
|
||||||
|
'--record',
|
||||||
|
default=False,
|
||||||
help='Record a QEMU run record for later replay with `-R`'
|
help='Record a QEMU run record for later replay with `-R`'
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'--show-stdout', default=True,
|
'--show-stdout',
|
||||||
|
default=True,
|
||||||
help='''Show emulator stdout and stderr on the host terminal.'''
|
help='''Show emulator stdout and stderr on the host terminal.'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'--terminal', default=False,
|
'--terminal',
|
||||||
|
default=False,
|
||||||
help='''\
|
help='''\
|
||||||
Output to the terminal, don't pipe to tee as the default.
|
Output to the terminal, don't pipe to tee as the default.
|
||||||
Does not save the output to a file, but allows you to use debuggers.
|
Does not save the output to a file, but allows you to use debuggers.
|
||||||
@@ -180,13 +211,15 @@ gem5 Python scripts with pdb.
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-T', '--trace',
|
'-T',
|
||||||
|
'--trace',
|
||||||
help='''\
|
help='''\
|
||||||
Set trace events to be enabled. If not given, gem5 tracing is completely
|
Set trace events to be enabled. If not given, gem5 tracing is completely
|
||||||
disabled, while QEMU tracing is enabled but uses default traces that are very
|
disabled, while QEMU tracing is enabled but uses default traces that are very
|
||||||
rare and don't affect performance, because `./configure
|
rare and don't affect performance, because `./configure
|
||||||
--enable-trace-backends=simple` seems to enable some traces by default, e.g.
|
--enable-trace-backends=simple` seems to enable some traces by default, e.g.
|
||||||
`pr_manager_run`, and I don't know how to get rid of them.
|
`pr_manager_run`, and I don't know how to get rid of them.
|
||||||
|
See: http://github.com/cirosantilli/linux-kernel-module-cheat#tracing
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
@@ -204,7 +237,9 @@ Trace instructions run to stdout. Shortcut for --trace --trace-stdout.
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-t', '--tmux', default=False,
|
'-t',
|
||||||
|
'--tmux',
|
||||||
|
default=False,
|
||||||
help='''\
|
help='''\
|
||||||
Create a tmux split the window. You must already be inside of a `tmux` session
|
Create a tmux split the window. You must already be inside of a `tmux` session
|
||||||
to use this option:
|
to use this option:
|
||||||
@@ -222,23 +257,28 @@ Parameters to pass to the program running on the tmux split. Implies --tmux.
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-w', '--wait-gdb', default=False,
|
'--wait-gdb',
|
||||||
help='Wait for GDB to connect before starting execution'
|
default=False,
|
||||||
|
help='''\
|
||||||
|
Wait for GDB to connect before starting execution
|
||||||
|
See: https://github.com/cirosantilli/linux-kernel-module-cheat#gdb
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-x', '--graphic', default=False,
|
'--vnc',
|
||||||
help='Run in graphic mode. Mnemonic: X11'
|
default=False,
|
||||||
)
|
|
||||||
self.add_argument(
|
|
||||||
'-V', '--vnc', default=False,
|
|
||||||
help='''\
|
help='''\
|
||||||
Run QEMU with VNC instead of the default SDL. Connect to it with:
|
Run QEMU with VNC instead of the default SDL. Connect to it with:
|
||||||
`vinagre localhost:5900`.
|
`vinagre localhost:5900`.
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'extra_emulator_args', nargs='*', default=[],
|
'extra_emulator_args',
|
||||||
help='Extra options to append at the end of the emulator command line'
|
nargs='*',
|
||||||
|
default=[],
|
||||||
|
help='''\
|
||||||
|
Extra options to append at the end of the emulator command line.
|
||||||
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
def timed_main(self):
|
def timed_main(self):
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class Main(common.TestCliFunction):
|
|||||||
super().__init__(
|
super().__init__(
|
||||||
description='''\
|
description='''\
|
||||||
https://github.com/cirosantilli/linux-kernel-module-cheat#user-mode-tests
|
https://github.com/cirosantilli/linux-kernel-module-cheat#user-mode-tests
|
||||||
|
TODO: expose all userland relevant ./run args here as well somehow.
|
||||||
''',
|
''',
|
||||||
)
|
)
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
|
|||||||
Reference in New Issue
Block a user