tests/kernel/smp: Add SMP switch torture test
Formalize and rework the issue reproducer for #40795 and add it to the SMP test suite. Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
parent
322175e4fc
commit
8edf9817c0
4 changed files with 89 additions and 1 deletions
4
tests/kernel/smp/boards/qemu_cortex_a53_smp.conf
Normal file
4
tests/kernel/smp/boards/qemu_cortex_a53_smp.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Copyright (c) 2022 Carlo Caione <ccaione@baylibre.com>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
CONFIG_MP_NUM_CPUS=4
|
19
tests/kernel/smp/boards/qemu_cortex_a53_smp.overlay
Normal file
19
tests/kernel/smp/boards/qemu_cortex_a53_smp.overlay
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/* Copyright 2022 Carlo Caione <ccaione@baylibre.com>
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/ {
|
||||||
|
cpus {
|
||||||
|
cpu@2 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53";
|
||||||
|
reg = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpu@3 {
|
||||||
|
device_type = "cpu";
|
||||||
|
compatible = "arm,cortex-a53";
|
||||||
|
reg = <3>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,3 +1,4 @@
|
||||||
CONFIG_ZTEST=y
|
CONFIG_ZTEST=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_TRACE_SCHED_IPI=y
|
CONFIG_TRACE_SCHED_IPI=y
|
||||||
|
CONFIG_POLL=y
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define EQUAL_PRIORITY 1
|
#define EQUAL_PRIORITY 1
|
||||||
#define TIME_SLICE_MS 500
|
#define TIME_SLICE_MS 500
|
||||||
#define THREAD_DELAY 1
|
#define THREAD_DELAY 1
|
||||||
|
#define SLEEP_MS_LONG 15000
|
||||||
|
|
||||||
struct k_thread t2;
|
struct k_thread t2;
|
||||||
K_THREAD_STACK_DEFINE(t2_stack, T2_STACK_SIZE);
|
K_THREAD_STACK_DEFINE(t2_stack, T2_STACK_SIZE);
|
||||||
|
@ -52,6 +53,9 @@ static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREADS_NUM, STACK_SIZE);
|
||||||
|
|
||||||
static volatile int thread_started[THREADS_NUM - 1];
|
static volatile int thread_started[THREADS_NUM - 1];
|
||||||
|
|
||||||
|
static struct k_poll_signal tsignal[THREADS_NUM];
|
||||||
|
static struct k_poll_event tevent[THREADS_NUM];
|
||||||
|
|
||||||
static int curr_cpu(void)
|
static int curr_cpu(void)
|
||||||
{
|
{
|
||||||
unsigned int k = arch_irq_lock();
|
unsigned int k = arch_irq_lock();
|
||||||
|
@ -948,6 +952,65 @@ void test_inc_concurrency(void)
|
||||||
"total count %d is wrong(M)", global_cnt);
|
"total count %d is wrong(M)", global_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Torture test for context switching code
|
||||||
|
*
|
||||||
|
* @ingroup kernel_smp_tests
|
||||||
|
*
|
||||||
|
* @details Leverage the polling API to stress test the context switching code.
|
||||||
|
* This test will hammer all the CPUs with thread swapping requests.
|
||||||
|
*/
|
||||||
|
static void process_events(void *arg0, void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
uintptr_t id = (uintptr_t) arg0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_poll(&tevent[id], 1, K_FOREVER);
|
||||||
|
|
||||||
|
if (tevent[id].signal->result != 0x55) {
|
||||||
|
ztest_test_fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
tevent[id].signal->signaled = 0;
|
||||||
|
tevent[id].state = K_POLL_STATE_NOT_READY;
|
||||||
|
|
||||||
|
k_poll_signal_reset(&tsignal[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void signal_raise(void *arg0, void *arg1, void *arg2)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
for (uintptr_t i = 0; i < THREADS_NUM; i++) {
|
||||||
|
k_poll_signal_raise(&tsignal[i], 0x55);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_smp_switch_torture(void)
|
||||||
|
{
|
||||||
|
for (uintptr_t i = 0; i < THREADS_NUM; i++) {
|
||||||
|
k_poll_signal_init(&tsignal[i]);
|
||||||
|
k_poll_event_init(&tevent[i], K_POLL_TYPE_SIGNAL,
|
||||||
|
K_POLL_MODE_NOTIFY_ONLY, &tsignal[i]);
|
||||||
|
|
||||||
|
k_thread_create(&tthread[i], tstack[i], STACK_SIZE,
|
||||||
|
(k_thread_entry_t) process_events,
|
||||||
|
(void *) i, NULL, NULL, K_PRIO_PREEMPT(i + 1),
|
||||||
|
K_INHERIT_PERMS, K_NO_WAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
k_thread_create(&t2, t2_stack, T2_STACK_SIZE, signal_raise,
|
||||||
|
NULL, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT);
|
||||||
|
|
||||||
|
k_sleep(K_MSEC(SLEEP_MS_LONG));
|
||||||
|
|
||||||
|
k_thread_abort(&t2);
|
||||||
|
for (uintptr_t i = 0; i < THREADS_NUM; i++) {
|
||||||
|
k_thread_abort(&tthread[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void test_main(void)
|
void test_main(void)
|
||||||
{
|
{
|
||||||
/* Sleep a bit to guarantee that both CPUs enter an idle
|
/* Sleep a bit to guarantee that both CPUs enter an idle
|
||||||
|
@ -969,7 +1032,8 @@ void test_main(void)
|
||||||
ztest_unit_test(test_fatal_on_smp),
|
ztest_unit_test(test_fatal_on_smp),
|
||||||
ztest_unit_test(test_workq_on_smp),
|
ztest_unit_test(test_workq_on_smp),
|
||||||
ztest_unit_test(test_smp_release_global_lock),
|
ztest_unit_test(test_smp_release_global_lock),
|
||||||
ztest_unit_test(test_inc_concurrency)
|
ztest_unit_test(test_inc_concurrency),
|
||||||
|
ztest_unit_test(test_smp_switch_torture)
|
||||||
);
|
);
|
||||||
ztest_run_test_suite(smp);
|
ztest_run_test_suite(smp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue