linux-kselftest-5.5-rc4
This Kselftest update for Linux 5.5-rc4 consists of: -- rseq build failures fixes related to glibc 2.30 compatibility from Mathieu Desnoyers -- Kunit fixes and cleanups from SeongJae Park -- Fixes to filesystems/epoll, firmware, and livepatch build failures and skip handling. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAl4FIkMACgkQCwJExA0N QxxWpxAAyGLaRzfRP10f9JyfwTch4GiuNfY2IYbV/Jy/uqDUYt6do5pkSMxUlryI hV8KSjyrhVRmO4PW9ufsiDx9LjOB7Axw8/6CA+iR9JaBbSboSRzSzrRRS2nlo081 WrwJCjIzWh4igIcV+CCRkZuCm7fO6FouxciLdMXtJs6gnJrmKcbi8YHFbT1+jdQ3 /sJP+wLHCcWLjXG9DZ1yTt183YB0uD2RUMixLkaLIwaoLBaJUK+/uN7rKtVH+ARE 6l/s1m4ZF+mLHH6X6S6NmXrOAOqkNNT416RbhDVP12HBD0XBGH0mh1JUOYs0bUpD M+WVeqjU8O7xKCrerj0WCxZsY5yt1UkwS4DfpPeJAkPt1XKbRo6WuXYDvfAfAz26 d7OLPqI+fLh8uj87cu7UyYeguPlfz3Ce+uLmQAgozaY62dfCiQdBmcpmhEMsNUEf A31vZAY0ysIBDjDT2VoCdCJDxtbYILQKgC7g6+sX+Q7R7zkcce4RZpPck/PJuS9l So+CPD9DNofKNClCIW8EPnnWxniEoUE8j4cetGGTvidPr7oXTqbm46KCTAptOeUT jwCqIdmh87gpbiIE+YMKhJCwJ3fPKWH7UOL8IJwbBB1x3jsigP3cGleKU7+lYe1/ PgmeMBiYuSCv/ssWhfIav+qEgVJStDtSR3l1ivArHfGOAtquuRo= =ZztB -----END PGP SIGNATURE----- Merge tag 'linux-kselftest-5.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest Pull Kselftest fixes from Shuah Khan: - rseq build failures fixes related to glibc 2.30 compatibility from Mathieu Desnoyers - Kunit fixes and cleanups from SeongJae Park - Fixes to filesystems/epoll, firmware, and livepatch build failures and skip handling. * tag 'linux-kselftest-5.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: rseq/selftests: Clarify rseq_prepare_unload() helper requirements rseq/selftests: Fix: Namespace gettid() for compatibility with glibc 2.30 rseq/selftests: Turn off timeout setting kunit/kunit_tool_test: Test '--build_dir' option run kunit: Rename 'kunitconfig' to '.kunitconfig' kunit: Place 'test.log' under the 'build_dir' kunit: Create default config in '--build_dir' kunit: Remove duplicated defconfig creation docs/kunit/start: Use in-tree 'kunit_defconfig' selftests: livepatch: Fix it to do root uid check and skip selftests: firmware: Fix it to do root uid check and skip selftests: filesystems/epoll: fix build error
This commit is contained in:
commit
f4b3974602
Documentation/dev-tools/kunit
tools/testing
kunit
selftests
filesystems/epoll
firmware
livepatch
rseq
|
@ -24,19 +24,16 @@ The wrapper can be run with:
|
|||
For more information on this wrapper (also called kunit_tool) checkout the
|
||||
:doc:`kunit-tool` page.
|
||||
|
||||
Creating a kunitconfig
|
||||
======================
|
||||
Creating a .kunitconfig
|
||||
=======================
|
||||
The Python script is a thin wrapper around Kbuild. As such, it needs to be
|
||||
configured with a ``kunitconfig`` file. This file essentially contains the
|
||||
configured with a ``.kunitconfig`` file. This file essentially contains the
|
||||
regular Kernel config, with the specific test targets as well.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone -b master https://kunit.googlesource.com/kunitconfig $PATH_TO_KUNITCONFIG_REPO
|
||||
cd $PATH_TO_LINUX_REPO
|
||||
ln -s $PATH_TO_KUNIT_CONFIG_REPO/kunitconfig kunitconfig
|
||||
|
||||
You may want to add kunitconfig to your local gitignore.
|
||||
cp arch/um/configs/kunit_defconfig .kunitconfig
|
||||
|
||||
Verifying KUnit Works
|
||||
---------------------
|
||||
|
@ -151,7 +148,7 @@ and the following to ``drivers/misc/Makefile``:
|
|||
|
||||
obj-$(CONFIG_MISC_EXAMPLE_TEST) += example-test.o
|
||||
|
||||
Now add it to your ``kunitconfig``:
|
||||
Now add it to your ``.kunitconfig``:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
|
|
@ -31,15 +31,12 @@ class KunitStatus(Enum):
|
|||
TEST_FAILURE = auto()
|
||||
|
||||
def create_default_kunitconfig():
|
||||
if not os.path.exists(kunit_kernel.KUNITCONFIG_PATH):
|
||||
if not os.path.exists(kunit_kernel.kunitconfig_path):
|
||||
shutil.copyfile('arch/um/configs/kunit_defconfig',
|
||||
kunit_kernel.KUNITCONFIG_PATH)
|
||||
kunit_kernel.kunitconfig_path)
|
||||
|
||||
def run_tests(linux: kunit_kernel.LinuxSourceTree,
|
||||
request: KunitRequest) -> KunitResult:
|
||||
if request.defconfig:
|
||||
create_default_kunitconfig()
|
||||
|
||||
config_start = time.time()
|
||||
success = linux.build_reconfig(request.build_dir)
|
||||
config_end = time.time()
|
||||
|
@ -108,15 +105,22 @@ def main(argv, linux=None):
|
|||
run_parser.add_argument('--build_dir',
|
||||
help='As in the make command, it specifies the build '
|
||||
'directory.',
|
||||
type=str, default=None, metavar='build_dir')
|
||||
type=str, default='', metavar='build_dir')
|
||||
|
||||
run_parser.add_argument('--defconfig',
|
||||
help='Uses a default kunitconfig.',
|
||||
help='Uses a default .kunitconfig.',
|
||||
action='store_true')
|
||||
|
||||
cli_args = parser.parse_args(argv)
|
||||
|
||||
if cli_args.subcommand == 'run':
|
||||
if cli_args.build_dir:
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
kunit_kernel.kunitconfig_path = os.path.join(
|
||||
cli_args.build_dir,
|
||||
kunit_kernel.kunitconfig_path)
|
||||
|
||||
if cli_args.defconfig:
|
||||
create_default_kunitconfig()
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import os
|
|||
import kunit_config
|
||||
|
||||
KCONFIG_PATH = '.config'
|
||||
KUNITCONFIG_PATH = 'kunitconfig'
|
||||
kunitconfig_path = '.kunitconfig'
|
||||
|
||||
class ConfigError(Exception):
|
||||
"""Represents an error trying to configure the Linux kernel."""
|
||||
|
@ -82,7 +82,7 @@ class LinuxSourceTree(object):
|
|||
|
||||
def __init__(self):
|
||||
self._kconfig = kunit_config.Kconfig()
|
||||
self._kconfig.read_from_file(KUNITCONFIG_PATH)
|
||||
self._kconfig.read_from_file(kunitconfig_path)
|
||||
self._ops = LinuxSourceTreeOperations()
|
||||
|
||||
def clean(self):
|
||||
|
@ -111,7 +111,7 @@ class LinuxSourceTree(object):
|
|||
return True
|
||||
|
||||
def build_reconfig(self, build_dir):
|
||||
"""Creates a new .config if it is not a subset of the kunitconfig."""
|
||||
"""Creates a new .config if it is not a subset of the .kunitconfig."""
|
||||
kconfig_path = get_kconfig_path(build_dir)
|
||||
if os.path.exists(kconfig_path):
|
||||
existing_kconfig = kunit_config.Kconfig()
|
||||
|
@ -140,10 +140,10 @@ class LinuxSourceTree(object):
|
|||
return False
|
||||
return True
|
||||
|
||||
def run_kernel(self, args=[], timeout=None, build_dir=None):
|
||||
def run_kernel(self, args=[], timeout=None, build_dir=''):
|
||||
args.extend(['mem=256M'])
|
||||
process = self._ops.linux_bin(args, timeout, build_dir)
|
||||
with open('test.log', 'w') as f:
|
||||
with open(os.path.join(build_dir, 'test.log'), 'w') as f:
|
||||
for line in process.stdout:
|
||||
f.write(line.rstrip().decode('ascii') + '\n')
|
||||
yield line.rstrip().decode('ascii')
|
||||
|
|
|
@ -174,6 +174,7 @@ class KUnitMainTest(unittest.TestCase):
|
|||
kunit.main(['run'], self.linux_source_mock)
|
||||
assert self.linux_source_mock.build_reconfig.call_count == 1
|
||||
assert self.linux_source_mock.run_kernel.call_count == 1
|
||||
self.linux_source_mock.run_kernel.assert_called_once_with(build_dir='', timeout=300)
|
||||
self.print_mock.assert_any_call(StrContains('Testing complete.'))
|
||||
|
||||
def test_run_passes_args_fail(self):
|
||||
|
@ -199,7 +200,14 @@ class KUnitMainTest(unittest.TestCase):
|
|||
timeout = 3453
|
||||
kunit.main(['run', '--timeout', str(timeout)], self.linux_source_mock)
|
||||
assert self.linux_source_mock.build_reconfig.call_count == 1
|
||||
self.linux_source_mock.run_kernel.assert_called_once_with(build_dir=None, timeout=timeout)
|
||||
self.linux_source_mock.run_kernel.assert_called_once_with(build_dir='', timeout=timeout)
|
||||
self.print_mock.assert_any_call(StrContains('Testing complete.'))
|
||||
|
||||
def test_run_builddir(self):
|
||||
build_dir = '.kunit'
|
||||
kunit.main(['run', '--build_dir', build_dir], self.linux_source_mock)
|
||||
assert self.linux_source_mock.build_reconfig.call_count == 1
|
||||
self.linux_source_mock.run_kernel.assert_called_once_with(build_dir=build_dir, timeout=300)
|
||||
self.print_mock.assert_any_call(StrContains('Testing complete.'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
CFLAGS += -I../../../../../usr/include/
|
||||
LDFLAGS += -lpthread
|
||||
LDLIBS += -lpthread
|
||||
TEST_GEN_PROGS := epoll_wakeup_test
|
||||
|
||||
include ../../lib.mk
|
||||
|
|
|
@ -34,6 +34,12 @@ test_modprobe()
|
|||
|
||||
check_mods()
|
||||
{
|
||||
local uid=$(id -u)
|
||||
if [ $uid -ne 0 ]; then
|
||||
echo "skip all tests: must be run as root" >&2
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
trap "test_modprobe" EXIT
|
||||
if [ ! -d $DIR ]; then
|
||||
modprobe test_firmware
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
MAX_RETRIES=600
|
||||
RETRY_INTERVAL=".1" # seconds
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4
|
||||
ksft_skip=4
|
||||
|
||||
# log(msg) - write message to kernel log
|
||||
# msg - insightful words
|
||||
function log() {
|
||||
|
@ -18,7 +21,16 @@ function log() {
|
|||
function skip() {
|
||||
log "SKIP: $1"
|
||||
echo "SKIP: $1" >&2
|
||||
exit 4
|
||||
exit $ksft_skip
|
||||
}
|
||||
|
||||
# root test
|
||||
function is_root() {
|
||||
uid=$(id -u)
|
||||
if [ $uid -ne 0 ]; then
|
||||
echo "skip all tests: must be run as root" >&2
|
||||
exit $ksft_skip
|
||||
fi
|
||||
}
|
||||
|
||||
# die(msg) - game over, man
|
||||
|
@ -62,6 +74,7 @@ function set_ftrace_enabled() {
|
|||
# for verbose livepatching output and turn on
|
||||
# the ftrace_enabled sysctl.
|
||||
function setup_config() {
|
||||
is_root
|
||||
push_config
|
||||
set_dynamic_debug
|
||||
set_ftrace_enabled 1
|
||||
|
|
|
@ -8,8 +8,7 @@ MOD_LIVEPATCH=test_klp_state
|
|||
MOD_LIVEPATCH2=test_klp_state2
|
||||
MOD_LIVEPATCH3=test_klp_state3
|
||||
|
||||
set_dynamic_debug
|
||||
|
||||
setup_config
|
||||
|
||||
# TEST: Loading and removing a module that modifies the system state
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
static inline pid_t gettid(void)
|
||||
static inline pid_t rseq_gettid(void)
|
||||
{
|
||||
return syscall(__NR_gettid);
|
||||
}
|
||||
|
@ -373,11 +373,12 @@ void *test_percpu_spinlock_thread(void *arg)
|
|||
rseq_percpu_unlock(&data->lock, cpu);
|
||||
#ifndef BENCHMARK
|
||||
if (i != 0 && !(i % (reps / 10)))
|
||||
printf_verbose("tid %d: count %lld\n", (int) gettid(), i);
|
||||
printf_verbose("tid %d: count %lld\n",
|
||||
(int) rseq_gettid(), i);
|
||||
#endif
|
||||
}
|
||||
printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n",
|
||||
(int) gettid(), nr_abort, signals_delivered);
|
||||
(int) rseq_gettid(), nr_abort, signals_delivered);
|
||||
if (!opt_disable_rseq && thread_data->reg &&
|
||||
rseq_unregister_current_thread())
|
||||
abort();
|
||||
|
@ -454,11 +455,12 @@ void *test_percpu_inc_thread(void *arg)
|
|||
} while (rseq_unlikely(ret));
|
||||
#ifndef BENCHMARK
|
||||
if (i != 0 && !(i % (reps / 10)))
|
||||
printf_verbose("tid %d: count %lld\n", (int) gettid(), i);
|
||||
printf_verbose("tid %d: count %lld\n",
|
||||
(int) rseq_gettid(), i);
|
||||
#endif
|
||||
}
|
||||
printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n",
|
||||
(int) gettid(), nr_abort, signals_delivered);
|
||||
(int) rseq_gettid(), nr_abort, signals_delivered);
|
||||
if (!opt_disable_rseq && thread_data->reg &&
|
||||
rseq_unregister_current_thread())
|
||||
abort();
|
||||
|
@ -605,7 +607,7 @@ void *test_percpu_list_thread(void *arg)
|
|||
}
|
||||
|
||||
printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n",
|
||||
(int) gettid(), nr_abort, signals_delivered);
|
||||
(int) rseq_gettid(), nr_abort, signals_delivered);
|
||||
if (!opt_disable_rseq && rseq_unregister_current_thread())
|
||||
abort();
|
||||
|
||||
|
@ -796,7 +798,7 @@ void *test_percpu_buffer_thread(void *arg)
|
|||
}
|
||||
|
||||
printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n",
|
||||
(int) gettid(), nr_abort, signals_delivered);
|
||||
(int) rseq_gettid(), nr_abort, signals_delivered);
|
||||
if (!opt_disable_rseq && rseq_unregister_current_thread())
|
||||
abort();
|
||||
|
||||
|
@ -1011,7 +1013,7 @@ void *test_percpu_memcpy_buffer_thread(void *arg)
|
|||
}
|
||||
|
||||
printf_verbose("tid %d: number of rseq abort: %d, signals delivered: %u\n",
|
||||
(int) gettid(), nr_abort, signals_delivered);
|
||||
(int) rseq_gettid(), nr_abort, signals_delivered);
|
||||
if (!opt_disable_rseq && rseq_unregister_current_thread())
|
||||
abort();
|
||||
|
||||
|
|
|
@ -149,11 +149,13 @@ static inline void rseq_clear_rseq_cs(void)
|
|||
/*
|
||||
* rseq_prepare_unload() should be invoked by each thread executing a rseq
|
||||
* critical section at least once between their last critical section and
|
||||
* library unload of the library defining the rseq critical section
|
||||
* (struct rseq_cs). This also applies to use of rseq in code generated by
|
||||
* JIT: rseq_prepare_unload() should be invoked at least once by each
|
||||
* thread executing a rseq critical section before reclaim of the memory
|
||||
* holding the struct rseq_cs.
|
||||
* library unload of the library defining the rseq critical section (struct
|
||||
* rseq_cs) or the code referred to by the struct rseq_cs start_ip and
|
||||
* post_commit_offset fields. This also applies to use of rseq in code
|
||||
* generated by JIT: rseq_prepare_unload() should be invoked at least once by
|
||||
* each thread executing a rseq critical section before reclaim of the memory
|
||||
* holding the struct rseq_cs or reclaim of the code pointed to by struct
|
||||
* rseq_cs start_ip and post_commit_offset fields.
|
||||
*/
|
||||
static inline void rseq_prepare_unload(void)
|
||||
{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
timeout=0
|
Loading…
Reference in New Issue