tests: mem_protect: add migration test case
We need to make sure that if we migrate a thread to another memory domain, the migration process doesn't cause the target thread to explode. This is mostly a concern on SMP systems; the thread could be running on another CPU at the same time. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
1367c4a4b7
commit
4303d35380
3 changed files with 68 additions and 0 deletions
|
@ -32,6 +32,7 @@ void test_main(void)
|
|||
ztest_unit_test(test_mem_domain_remove_add_partition),
|
||||
ztest_unit_test(test_mem_domain_api_supervisor_only),
|
||||
ztest_unit_test(test_mem_domain_boot_threads),
|
||||
ztest_unit_test(test_mem_domain_migration),
|
||||
|
||||
/* mem_partition.c */
|
||||
ztest_unit_test(test_macros_obtain_names_data_bss),
|
||||
|
|
|
@ -265,3 +265,69 @@ void test_mem_domain_boot_threads(void)
|
|||
|
||||
k_thread_abort(zzz_thread);
|
||||
}
|
||||
|
||||
static ZTEST_BMEM volatile bool spin_done;
|
||||
static K_SEM_DEFINE(spin_sem, 0, 1);
|
||||
|
||||
static void spin_entry(void *p1, void *p2, void *p3)
|
||||
{
|
||||
printk("spin thread entry\n");
|
||||
k_sem_give(&spin_sem);
|
||||
|
||||
while (!spin_done) {
|
||||
k_busy_wait(1);
|
||||
}
|
||||
printk("spin thread completed\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Show that moving a thread from one domain to another works
|
||||
*
|
||||
* Start a thread and have it spin. Then while it is spinning, show that
|
||||
* adding it to another memory domain doesn't cause any faults.
|
||||
*
|
||||
* This test is of particular importance on SMP systems where the child
|
||||
* thread is spinning on a different CPU concurrently with the migration
|
||||
* operation.
|
||||
*
|
||||
* @ingroup kernel_memprotect_tests
|
||||
*
|
||||
* @see k_mem_domain_add_thread()
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define PRIO K_PRIO_COOP(0)
|
||||
#else
|
||||
#define PRIO K_PRIO_PREEMPT(1)
|
||||
#endif
|
||||
|
||||
void test_mem_domain_migration(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
set_fault_valid(false);
|
||||
|
||||
k_thread_create(&child_thread, child_stack,
|
||||
K_THREAD_STACK_SIZEOF(child_stack), spin_entry,
|
||||
NULL, NULL, NULL,
|
||||
PRIO, K_USER | K_INHERIT_PERMS, K_FOREVER);
|
||||
k_thread_name_set(&child_thread, "child_thread");
|
||||
k_object_access_grant(&spin_sem, &child_thread);
|
||||
k_thread_start(&child_thread);
|
||||
|
||||
/* Ensure that the child thread has started */
|
||||
ret = k_sem_take(&spin_sem, K_FOREVER);
|
||||
zassert_equal(ret, 0, "k_sem_take failed");
|
||||
|
||||
/* Now move it to test_domain. This domain also has the ztest partition,
|
||||
* so the child thread should keep running and not explode
|
||||
*/
|
||||
printk("migrate to new domain\n");
|
||||
k_mem_domain_add_thread(&test_domain, &child_thread);
|
||||
|
||||
/* set spin_done so the child thread completes */
|
||||
printk("set test completion\n");
|
||||
spin_done = true;
|
||||
|
||||
k_thread_join(&child_thread, K_FOREVER);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ extern void test_mem_domain_no_writes_to_ro(void);
|
|||
extern void test_mem_domain_remove_add_partition(void);
|
||||
extern void test_mem_domain_api_supervisor_only(void);
|
||||
extern void test_mem_domain_boot_threads(void);
|
||||
extern void test_mem_domain_migration(void);
|
||||
|
||||
extern void test_macros_obtain_names_data_bss(void);
|
||||
extern void test_mem_part_assign_bss_vars_zero(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue