1 /*
2  * Copyright (c) 2018 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/tc_util.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/kernel.h>
10 #include <ksched.h>
11 #include <zephyr/kernel_structs.h>
12 
13 #if CONFIG_MP_MAX_NUM_CPUS < 2
14 #error SMP test requires at least two CPUs!
15 #endif
16 
17 /*
18  * The test is designed to work with no more than 12 CPUs.
19  * If attempting to run on a platform with more than that,
20  * create a custom board overlay file to reduce the number
21  * of CPUs to 12.
22  */
23 #if CONFIG_MP_MAX_NUM_CPUS > 12
24 #error "Test only supports up to 12 CPUs\nReduce CONFIG_MP_MAX_NUM_CPUS\n"
25 #endif
26 
27 #define RUN_FACTOR (CONFIG_SMP_TEST_RUN_FACTOR / 100.0)
28 
29 #define T2_STACK_SIZE (2048 + CONFIG_TEST_EXTRA_STACK_SIZE)
30 #define STACK_SIZE (384 + CONFIG_TEST_EXTRA_STACK_SIZE)
31 #define DELAY_US 50000
32 #define TIMEOUT 5000
33 #define EQUAL_PRIORITY 1
34 #define TIME_SLICE_MS 500
35 #define THREAD_DELAY 1
36 #define SLEEP_MS_LONG ((int)(15000 * RUN_FACTOR))
37 
38 struct k_thread t2;
39 K_THREAD_STACK_DEFINE(t2_stack, T2_STACK_SIZE);
40 
41 volatile int t2_count;
42 volatile int sync_count = -1;
43 
44 static int main_thread_id;
45 static int child_thread_id;
46 volatile int rv;
47 
48 K_SEM_DEFINE(cpuid_sema, 0, 1);
49 K_SEM_DEFINE(sema, 0, 1);
50 static struct k_mutex smutex;
51 static struct k_sem smp_sem;
52 
53 #define MAX_NUM_THREADS CONFIG_MP_MAX_NUM_CPUS
54 
55 struct thread_info {
56 	k_tid_t tid;
57 	int executed;
58 	int priority;
59 	int cpu_id;
60 };
61 static ZTEST_BMEM volatile struct thread_info tinfo[MAX_NUM_THREADS];
62 static struct k_thread tthread[MAX_NUM_THREADS];
63 static K_THREAD_STACK_ARRAY_DEFINE(tstack, MAX_NUM_THREADS, STACK_SIZE);
64 
65 static volatile int thread_started[MAX_NUM_THREADS - 1];
66 
67 static struct k_poll_signal tsignal[MAX_NUM_THREADS];
68 static struct k_poll_event tevent[MAX_NUM_THREADS];
69 
curr_cpu(void)70 static int curr_cpu(void)
71 {
72 	unsigned int k = arch_irq_lock();
73 	int ret = arch_curr_cpu()->id;
74 
75 	arch_irq_unlock(k);
76 	return ret;
77 }
78 
79 /**
80  * @brief SMP
81  * @defgroup kernel_smp_tests SMP Tests
82  * @ingroup all_tests
83  * @{
84  * @}
85  */
86 
87 /**
88  * @defgroup kernel_smp_integration_tests SMP Integration Tests
89  * @ingroup kernel_smp_tests
90  * @{
91  * @}
92  */
93 
94 /**
95  * @defgroup kernel_smp_module_tests SMP Module Tests
96  * @ingroup kernel_smp_tests
97  * @{
98  * @}
99  */
100 
t2_fn(void * a,void * b,void * c)101 static void t2_fn(void *a, void *b, void *c)
102 {
103 	ARG_UNUSED(a);
104 	ARG_UNUSED(b);
105 	ARG_UNUSED(c);
106 
107 	t2_count = 0;
108 
109 	/* This thread simply increments a counter while spinning on
110 	 * the CPU.  The idea is that it will always be iterating
111 	 * faster than the other thread so long as it is fairly
112 	 * scheduled (and it's designed to NOT be fairly schedulable
113 	 * without a separate CPU!), so the main thread can always
114 	 * check its progress.
115 	 */
116 	while (1) {
117 		k_busy_wait(DELAY_US);
118 		t2_count++;
119 	}
120 }
121 
122 /**
123  * @brief Verify SMP with 2 cooperative threads
124  *
125  * @ingroup kernel_smp_tests
126  *
127  * @details Multi processing is verified by checking whether
128  * 2 cooperative threads run simultaneously at different cores
129  */
ZTEST(smp,test_smp_coop_threads)130 ZTEST(smp, test_smp_coop_threads)
131 {
132 	int i, ok = 1;
133 
134 	if (!IS_ENABLED(CONFIG_SCHED_IPI_SUPPORTED)) {
135 		/* The spawned thread enters an infinite loop, so it can't be
136 		 * successfully aborted via an IPI.  Just skip in that
137 		 * configuration.
138 		 */
139 		ztest_test_skip();
140 	}
141 
142 	k_tid_t tid = k_thread_create(&t2, t2_stack, T2_STACK_SIZE, t2_fn,
143 				      NULL, NULL, NULL,
144 				      K_PRIO_COOP(2), 0, K_NO_WAIT);
145 
146 	/* Wait for the other thread (on a separate CPU) to actually
147 	 * start running.  We want synchrony to be as perfect as
148 	 * possible.
149 	 */
150 	t2_count = -1;
151 	while (t2_count == -1) {
152 	}
153 
154 	for (i = 0; i < 10; i++) {
155 		/* Wait slightly longer than the other thread so our
156 		 * count will always be lower
157 		 */
158 		k_busy_wait(DELAY_US + (DELAY_US / 8));
159 
160 		if (t2_count <= i) {
161 			ok = 0;
162 			break;
163 		}
164 	}
165 
166 	k_thread_abort(tid);
167 	k_thread_join(tid, K_FOREVER);
168 	zassert_true(ok, "SMP test failed");
169 }
170 
child_fn(void * p1,void * p2,void * p3)171 static void child_fn(void *p1, void *p2, void *p3)
172 {
173 	ARG_UNUSED(p2);
174 	ARG_UNUSED(p3);
175 	int parent_cpu_id = POINTER_TO_INT(p1);
176 
177 	zassert_true(parent_cpu_id != curr_cpu(),
178 		     "Parent isn't on other core");
179 
180 	sync_count++;
181 	k_sem_give(&cpuid_sema);
182 }
183 
184 /**
185  * @brief Verify CPU IDs of threads in SMP
186  *
187  * @ingroup kernel_smp_tests
188  *
189  * @details Verify whether thread running on other core is
190  * parent thread from child thread
191  */
ZTEST(smp,test_cpu_id_threads)192 ZTEST(smp, test_cpu_id_threads)
193 {
194 	/* Make sure idle thread runs on each core */
195 	k_sleep(K_MSEC(1000));
196 
197 	int parent_cpu_id = curr_cpu();
198 
199 	k_tid_t tid = k_thread_create(&t2, t2_stack, T2_STACK_SIZE, child_fn,
200 				      INT_TO_POINTER(parent_cpu_id), NULL,
201 				      NULL, K_PRIO_PREEMPT(2), 0, K_NO_WAIT);
202 
203 	while (sync_count == -1) {
204 	}
205 	k_sem_take(&cpuid_sema, K_FOREVER);
206 
207 	k_thread_abort(tid);
208 	k_thread_join(tid, K_FOREVER);
209 }
210 
thread_entry_fn(void * p1,void * p2,void * p3)211 static void thread_entry_fn(void *p1, void *p2, void *p3)
212 {
213 	ARG_UNUSED(p2);
214 	ARG_UNUSED(p3);
215 	int thread_num = POINTER_TO_INT(p1);
216 	int count = 0;
217 
218 	tinfo[thread_num].executed  = 1;
219 	tinfo[thread_num].cpu_id = curr_cpu();
220 
221 	while (count++ < 5) {
222 		k_busy_wait(DELAY_US);
223 	}
224 }
225 
spin_for_threads_exit(void)226 static void spin_for_threads_exit(void)
227 {
228 	unsigned int num_threads = arch_num_cpus();
229 
230 	for (int i = 0; i < num_threads - 1; i++) {
231 		volatile uint8_t *p = &tinfo[i].tid->base.thread_state;
232 
233 		while (!(*p & _THREAD_DEAD)) {
234 		}
235 	}
236 	k_busy_wait(DELAY_US);
237 }
238 
spawn_threads(int prio,int thread_num,int equal_prio,k_thread_entry_t thread_entry,int delay)239 static void spawn_threads(int prio, int thread_num, int equal_prio,
240 			k_thread_entry_t thread_entry, int delay)
241 {
242 	int i;
243 
244 	/* Spawn threads of priority higher than
245 	 * the previously created thread
246 	 */
247 	for (i = 0; i < thread_num; i++) {
248 		if (equal_prio) {
249 			tinfo[i].priority = prio;
250 		} else {
251 			/* Increase priority for each thread */
252 			tinfo[i].priority = prio - 1;
253 			prio = tinfo[i].priority;
254 		}
255 		tinfo[i].tid = k_thread_create(&tthread[i], tstack[i],
256 					       STACK_SIZE, thread_entry,
257 					       INT_TO_POINTER(i), NULL, NULL,
258 					       tinfo[i].priority, 0,
259 					       K_MSEC(delay));
260 		if (delay) {
261 			/* Increase delay for each thread */
262 			delay = delay + 10;
263 		}
264 	}
265 }
266 
abort_threads(int num)267 static void abort_threads(int num)
268 {
269 	for (int i = 0; i < num; i++) {
270 		k_thread_abort(tinfo[i].tid);
271 	}
272 
273 	for (int i = 0; i < num; i++) {
274 		k_thread_join(tinfo[i].tid, K_FOREVER);
275 	}
276 }
277 
cleanup_resources(void)278 static void cleanup_resources(void)
279 {
280 	unsigned int num_threads = arch_num_cpus();
281 
282 	for (int i = 0; i < num_threads; i++) {
283 		tinfo[i].tid = 0;
284 		tinfo[i].executed = 0;
285 		tinfo[i].priority = 0;
286 	}
287 }
288 
thread_ab_entry(void * p1,void * p2,void * p3)289 static void __no_optimization thread_ab_entry(void *p1, void *p2, void *p3)
290 {
291 	ARG_UNUSED(p1);
292 	ARG_UNUSED(p2);
293 	ARG_UNUSED(p3);
294 
295 	while (true) {
296 	}
297 }
298 
299 #define SPAWN_AB_PRIO K_PRIO_COOP(10)
300 
301 /**
302  * @brief Verify the code path when we do context switch in k_thread_abort on SMP system
303  *
304  * @ingroup kernel_smp_tests
305  *
306  * @details test logic:
307  * - The ztest thread has cooperative priority.
308  * - From ztest thread we spawn N number of cooperative threads, where N = number of CPUs.
309  *   - The spawned cooperative are executing infinite loop (so they occupy CPU core until they are
310  *     aborted).
311  *   - We have (number of CPUs - 1) spawned threads run and executing infinite loop, as current CPU
312  *     is occupied by ztest cooperative thread. Due to that the last of spawned threads is ready but
313  *     not executing.
314  * - We abort spawned threads one-by-one from the ztest thread.
315  *   - At the first k_thread_abort call the ztest thread will be preempted by the remaining spawned
316  *     thread which has higher priority than ztest thread.
317  *     But... k_thread_abort call should has destroyed one of the spawned threads, so ztest thread
318  *     should have a CPU available to run on.
319  * - We expect that all spawned threads will be aborted successfully.
320  *
321  * This was the test case for zephyrproject-rtos/zephyr#58040 issue where this test caused system
322  * hang.
323  */
324 
ZTEST(smp,test_coop_switch_in_abort)325 ZTEST(smp, test_coop_switch_in_abort)
326 {
327 	k_tid_t tid[MAX_NUM_THREADS];
328 	unsigned int num_threads = arch_num_cpus();
329 	unsigned int i;
330 
331 	zassert_true(_current->base.prio < 0, "test case relies on ztest thread be cooperative");
332 	zassert_true(_current->base.prio > SPAWN_AB_PRIO,
333 		     "spawn test need to have higher priority than ztest thread");
334 
335 	/* Spawn N number of cooperative threads, where N = number of CPUs */
336 	for (i = 0; i < num_threads; i++) {
337 		tid[i] = k_thread_create(&tthread[i], tstack[i],
338 					 STACK_SIZE, thread_ab_entry,
339 					 NULL, NULL, NULL,
340 					 SPAWN_AB_PRIO, 0, K_NO_WAIT);
341 	}
342 
343 	/* Wait for some time to let spawned threads on other cores run and start executing infinite
344 	 * loop.
345 	 */
346 	k_busy_wait(DELAY_US * 4);
347 
348 	/* At this time we have (number of CPUs - 1) spawned threads run and executing infinite loop
349 	 * on other CPU cores, as current CPU is occupied by this ztest cooperative thread.
350 	 * Due to that the last of spawned threads is ready but not executing.
351 	 */
352 
353 	/* Abort all spawned threads one-by-one. At the first k_thread_abort call the context
354 	 * switch will happen and the last 'spawned' thread will start.
355 	 * We should successfully abort all threads.
356 	 */
357 	for (i = 0; i < num_threads; i++) {
358 		k_thread_abort(tid[i]);
359 	}
360 
361 	/* Cleanup */
362 	for (i = 0; i < num_threads; i++) {
363 		zassert_equal(k_thread_join(tid[i], K_FOREVER), 0);
364 	}
365 }
366 
367 /**
368  * @brief Test cooperative threads non-preemption
369  *
370  * @ingroup kernel_smp_tests
371  *
372  * @details Spawn cooperative threads equal to number of cores
373  * supported. Main thread will already be running on 1 core.
374  * Check if the last thread created preempts any threads
375  * already running.
376  */
ZTEST(smp,test_coop_resched_threads)377 ZTEST(smp, test_coop_resched_threads)
378 {
379 	unsigned int num_threads = arch_num_cpus();
380 
381 	/* Spawn threads equal to number of cores,
382 	 * since we don't give up current CPU, last thread
383 	 * will not get scheduled
384 	 */
385 	spawn_threads(K_PRIO_COOP(12), num_threads, !EQUAL_PRIORITY,
386 		      &thread_entry_fn, THREAD_DELAY);
387 
388 	/* Wait for some time to let other core's thread run */
389 	k_busy_wait(DELAY_US * 5);
390 
391 
392 	/* Reassure that cooperative thread's are not preempted
393 	 * by checking last thread's execution
394 	 * status. We know that all threads got rescheduled on
395 	 * other cores except the last one
396 	 */
397 	for (int i = 0; i < num_threads - 1; i++) {
398 		zassert_true(tinfo[i].executed == 1,
399 			     "cooperative thread %d didn't run", i);
400 	}
401 	zassert_true(tinfo[num_threads - 1].executed == 0,
402 		     "cooperative thread is preempted");
403 
404 	/* Abort threads created */
405 	abort_threads(num_threads);
406 	cleanup_resources();
407 }
408 
409 /**
410  * @brief Test preemptness of preemptive thread
411  *
412  * @ingroup kernel_smp_tests
413  *
414  * @details Create preemptive thread and let it run
415  * on another core and verify if it gets preempted
416  * if another thread of higher priority is spawned
417  */
ZTEST(smp,test_preempt_resched_threads)418 ZTEST(smp, test_preempt_resched_threads)
419 {
420 	unsigned int num_threads = arch_num_cpus();
421 
422 	/* Spawn threads  equal to number of cores,
423 	 * lower priority thread should
424 	 * be preempted by higher ones
425 	 */
426 	spawn_threads(K_PRIO_PREEMPT(12), num_threads, !EQUAL_PRIORITY,
427 		      &thread_entry_fn, THREAD_DELAY);
428 
429 	spin_for_threads_exit();
430 
431 	for (int i = 0; i < num_threads; i++) {
432 		zassert_true(tinfo[i].executed == 1,
433 			     "preemptive thread %d didn't run", i);
434 	}
435 
436 	/* Abort threads created */
437 	abort_threads(num_threads);
438 	cleanup_resources();
439 }
440 
441 /**
442  * @brief Validate behavior of thread when it yields
443  *
444  * @ingroup kernel_smp_tests
445  *
446  * @details Spawn cooperative threads equal to number
447  * of cores, so last thread would be pending, call
448  * yield() from main thread. Now, all threads must be
449  * executed
450  */
ZTEST(smp,test_yield_threads)451 ZTEST(smp, test_yield_threads)
452 {
453 	unsigned int num_threads = arch_num_cpus();
454 
455 	/* Spawn threads equal to the number
456 	 * of cores, so the last thread would be
457 	 * pending.
458 	 */
459 	spawn_threads(K_PRIO_COOP(12), num_threads, !EQUAL_PRIORITY,
460 		      &thread_entry_fn, !THREAD_DELAY);
461 
462 	k_yield();
463 	k_busy_wait(DELAY_US * 5);
464 
465 	for (int i = 0; i < num_threads; i++) {
466 		zassert_true(tinfo[i].executed == 1,
467 			     "thread %d did not execute", i);
468 
469 	}
470 
471 	abort_threads(num_threads);
472 	cleanup_resources();
473 }
474 
475 /**
476  * @brief Test behavior of thread when it sleeps
477  *
478  * @ingroup kernel_smp_tests
479  *
480  * @details Spawn cooperative thread and call
481  * sleep() from main thread. After timeout, all
482  * threads has to be scheduled.
483  */
ZTEST(smp,test_sleep_threads)484 ZTEST(smp, test_sleep_threads)
485 {
486 	unsigned int num_threads = arch_num_cpus();
487 
488 	spawn_threads(K_PRIO_COOP(12), num_threads, !EQUAL_PRIORITY,
489 		      &thread_entry_fn, !THREAD_DELAY);
490 
491 	k_msleep(TIMEOUT);
492 
493 	for (int i = 0; i < num_threads; i++) {
494 		zassert_true(tinfo[i].executed == 1,
495 			     "thread %d did not execute", i);
496 	}
497 
498 	abort_threads(num_threads);
499 	cleanup_resources();
500 }
501 
thread_wakeup_entry(void * p1,void * p2,void * p3)502 static void thread_wakeup_entry(void *p1, void *p2, void *p3)
503 {
504 	ARG_UNUSED(p2);
505 	ARG_UNUSED(p3);
506 	int thread_num = POINTER_TO_INT(p1);
507 
508 	thread_started[thread_num] = 1;
509 
510 	k_msleep(DELAY_US * 1000);
511 
512 	tinfo[thread_num].executed  = 1;
513 }
514 
wakeup_on_start_thread(int tnum)515 static void wakeup_on_start_thread(int tnum)
516 {
517 	int threads_started = 0, i;
518 
519 	/* For each thread, spin waiting for it to first flag that
520 	 * it's going to sleep, and then that it's actually blocked
521 	 */
522 	for (i = 0; i < tnum; i++) {
523 		while (thread_started[i] == 0) {
524 		}
525 		while (!z_is_thread_prevented_from_running(tinfo[i].tid)) {
526 		}
527 	}
528 
529 	for (i = 0; i < tnum; i++) {
530 		if (thread_started[i] == 1 && threads_started <= tnum) {
531 			threads_started++;
532 			k_wakeup(tinfo[i].tid);
533 		}
534 	}
535 	zassert_equal(threads_started, tnum,
536 		      "All threads haven't started");
537 }
538 
check_wokeup_threads(int tnum)539 static void check_wokeup_threads(int tnum)
540 {
541 	int threads_woke_up = 0, i;
542 
543 	/* k_wakeup() isn't synchronous, give the other CPU time to
544 	 * schedule them
545 	 */
546 	k_busy_wait(300000);
547 
548 	for (i = 0; i < tnum; i++) {
549 		if (tinfo[i].executed == 1 && threads_woke_up <= tnum) {
550 			threads_woke_up++;
551 		}
552 	}
553 	zassert_equal(threads_woke_up, tnum, "Threads did not wakeup");
554 }
555 
556 /**
557  * @brief Test behavior of wakeup() in SMP case
558  *
559  * @ingroup kernel_smp_tests
560  *
561  * @details Spawn number of threads equal to number of
562  * remaining cores and let them sleep for a while. Call
563  * wakeup() of those threads from parent thread and check
564  * if they are all running
565  */
ZTEST(smp,test_wakeup_threads)566 ZTEST(smp, test_wakeup_threads)
567 {
568 	unsigned int num_threads = arch_num_cpus();
569 
570 	/* Spawn threads to run on all remaining cores */
571 	spawn_threads(K_PRIO_COOP(12), num_threads - 1, !EQUAL_PRIORITY,
572 		      &thread_wakeup_entry, !THREAD_DELAY);
573 
574 	/* Check if all the threads have started, then call wakeup */
575 	wakeup_on_start_thread(num_threads - 1);
576 
577 	/* Count threads which are woken up */
578 	check_wokeup_threads(num_threads - 1);
579 
580 	/* Abort all threads and cleanup */
581 	abort_threads(num_threads - 1);
582 	cleanup_resources();
583 }
584 
585 /* a thread for testing get current cpu */
thread_get_cpu_entry(void * p1,void * p2,void * p3)586 static void thread_get_cpu_entry(void *p1, void *p2, void *p3)
587 {
588 	ARG_UNUSED(p1);
589 	ARG_UNUSED(p2);
590 	ARG_UNUSED(p3);
591 
592 	int bsp_id = *(int *)p1;
593 	int cpu_id = -1;
594 
595 	/* get current cpu number for running thread */
596 	_cpu_t *curr_cpu = arch_curr_cpu();
597 
598 	/**TESTPOINT: call arch_curr_cpu() to get cpu struct */
599 	zassert_true(curr_cpu != NULL,
600 			"test failed to get current cpu.");
601 
602 	cpu_id = curr_cpu->id;
603 
604 	zassert_true(bsp_id != cpu_id,
605 			"should not be the same with our BSP");
606 
607 	/* loop forever to ensure running on this CPU */
608 	while (1) {
609 		k_busy_wait(DELAY_US);
610 	}
611 }
612 
613 /**
614  * @brief Test get a pointer of CPU
615  *
616  * @ingroup kernel_smp_module_tests
617  *
618  * @details
619  * Test Objective:
620  * - To verify architecture layer provides a mechanism to return a pointer to the
621  *   current kernel CPU record of the running CPU.
622  *   We call arch_curr_cpu() and get its member, both in main and spawned thread
623  *   separately, and compare them. They shall be different in SMP environment.
624  *
625  * Testing techniques:
626  * - Interface testing, function and block box testing,
627  *   dynamic analysis and testing,
628  *
629  * Prerequisite Conditions:
630  * - CONFIG_SMP=y, and the HW platform must support SMP.
631  *
632  * Input Specifications:
633  * - N/A
634  *
635  * Test Procedure:
636  * -# In main thread, call arch_curr_cpu() to get it's member "id",then store it
637  *  into a variable thread_id.
638  * -# Spawn a thread t2, and pass the stored thread_id to it, then call
639  *  k_busy_wait() 50us to wait for thread run and won't be swapped out.
640  * -# In thread t2, call arch_curr_cpu() to get pointer of current cpu data. Then
641  *  check if it not NULL.
642  * -# Store the member id via accessing pointer of current cpu data to var cpu_id.
643  * -# Check if cpu_id is not equaled to bsp_id that we pass into thread.
644  * -# Call k_busy_wait() and loop forever.
645  * -# In main thread, terminate the thread t2 before exit.
646  *
647  * Expected Test Result:
648  * - The pointer of current cpu data that we got from function call is correct.
649  *
650  * Pass/Fail Criteria:
651  * - Successful if the check of step 3,5 are all passed.
652  * - Failure if one of the check of step 3,5 is failed.
653  *
654  * Assumptions and Constraints:
655  * - This test using for the platform that support SMP, in our current scenario
656  *   , only x86_64, arc and xtensa supported.
657  *
658  * @see arch_curr_cpu()
659  */
660 static int _cpu_id;
ZTEST(smp,test_get_cpu)661 ZTEST(smp, test_get_cpu)
662 {
663 	k_tid_t thread_id;
664 
665 	if (!IS_ENABLED(CONFIG_SCHED_IPI_SUPPORTED)) {
666 		/* The spawned thread enters an infinite loop, so it can't be
667 		 * successfully aborted via an IPI.  Just skip in that
668 		 * configuration.
669 		 */
670 		ztest_test_skip();
671 	}
672 
673 	/* get current cpu number */
674 	_cpu_id = arch_curr_cpu()->id;
675 
676 	thread_id = k_thread_create(&t2, t2_stack, T2_STACK_SIZE,
677 				      thread_get_cpu_entry,
678 				      &_cpu_id, NULL, NULL,
679 				      K_PRIO_COOP(2),
680 				      K_INHERIT_PERMS, K_NO_WAIT);
681 
682 	k_busy_wait(DELAY_US);
683 
684 	k_thread_abort(thread_id);
685 	k_thread_join(thread_id, K_FOREVER);
686 }
687 
688 #ifdef CONFIG_TRACE_SCHED_IPI
689 /* global variable for testing send IPI */
690 static volatile int sched_ipi_has_called;
691 
z_trace_sched_ipi(void)692 void z_trace_sched_ipi(void)
693 {
694 	sched_ipi_has_called++;
695 }
696 #endif
697 
698 /**
699  * @brief Test interprocessor interrupt
700  *
701  * @ingroup kernel_smp_integration_tests
702  *
703  * @details
704  * Test Objective:
705  * - To verify architecture layer provides a mechanism to issue an interprocessor
706  *   interrupt to all other CPUs in the system that calls the scheduler IPI.
707  *   We simply add a hook in z_sched_ipi(), in order to check if it has been
708  *   called once in another CPU except the caller, when arch_sched_broadcast_ipi()
709  *   is called.
710  *
711  * Testing techniques:
712  * - Interface testing, function and block box testing,
713  *   dynamic analysis and testing
714  *
715  * Prerequisite Conditions:
716  * - CONFIG_SMP=y, and the HW platform must support SMP.
717  * - CONFIG_TRACE_SCHED_IPI=y was set.
718  *
719  * Input Specifications:
720  * - N/A
721  *
722  * Test Procedure:
723  * -# In main thread, given a global variable sched_ipi_has_called equaled zero.
724  * -# Call arch_sched_broadcast_ipi() then sleep for 100ms.
725  * -# In z_sched_ipi() handler, increment the sched_ipi_has_called.
726  * -# In main thread, check the sched_ipi_has_called is not equaled to zero.
727  * -# Repeat step 1 to 4 for 3 times.
728  *
729  * Expected Test Result:
730  * - The pointer of current cpu data that we got from function call is correct.
731  *
732  * Pass/Fail Criteria:
733  * - Successful if the check of step 4 are all passed.
734  * - Failure if one of the check of step 4 is failed.
735  *
736  * Assumptions and Constraints:
737  * - This test using for the platform that support SMP, in our current scenario
738  *   , only x86_64 and arc supported.
739  *
740  * @see arch_sched_broadcast_ipi()
741  */
742 #ifdef CONFIG_SCHED_IPI_SUPPORTED
ZTEST(smp,test_smp_ipi)743 ZTEST(smp, test_smp_ipi)
744 {
745 #ifndef CONFIG_TRACE_SCHED_IPI
746 	ztest_test_skip();
747 #else
748 	TC_PRINT("There are %u CPUs.\n", arch_num_cpus());
749 
750 	for (int i = 0; i < CONFIG_SMP_IPI_NUM_ITERS; i++) {
751 		int retries = CONFIG_SMP_IPI_WAIT_RETRIES;
752 		/* issue a sched ipi to tell other CPU to run thread */
753 		sched_ipi_has_called = 0;
754 		arch_sched_broadcast_ipi();
755 
756 		/* Need to wait longer than we think, loaded CI
757 		 * systems need to wait for host scheduling to run the
758 		 * other CPU's thread.
759 		 */
760 		while (retries > 0) {
761 			k_msleep(CONFIG_SMP_IPI_WAIT_MS);
762 
763 			/* Bail out early if test is deemed a success. */
764 			if (sched_ipi_has_called > 0) {
765 				break;
766 			}
767 
768 			retries--;
769 		}
770 
771 		/**TESTPOINT: check if enter our IPI interrupt handler */
772 		zassert_true(sched_ipi_has_called != 0,
773 				"did not receive IPI.(%d,%d)", i,
774 				sched_ipi_has_called);
775 	}
776 #endif
777 }
778 #endif
779 
k_sys_fatal_error_handler(unsigned int reason,const struct arch_esf * esf)780 void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *esf)
781 {
782 	static int trigger;
783 
784 	if (reason != K_ERR_KERNEL_OOPS) {
785 		printk("wrong error reason\n");
786 		TC_END_REPORT(TC_FAIL);
787 		k_fatal_halt(reason);
788 	}
789 
790 	if (trigger == 0) {
791 		child_thread_id = curr_cpu();
792 		trigger++;
793 	} else {
794 		main_thread_id = curr_cpu();
795 
796 		/* Verify the fatal was happened on different core */
797 		zassert_true(main_thread_id != child_thread_id,
798 					"fatal on the same core");
799 	}
800 }
801 
entry_oops(void * p1,void * p2,void * p3)802 void entry_oops(void *p1, void *p2, void *p3)
803 {
804 	k_oops();
805 	TC_ERROR("SHOULD NEVER SEE THIS\n");
806 }
807 
808 /**
809  * @brief Test fatal error can be triggered on different core
810 
811  * @details When CONFIG_SMP is enabled, on some multiprocessor
812  * platforms, exception can be triggered on different core at
813  * the same time.
814  *
815  * @ingroup kernel_common_tests
816  */
ZTEST(smp,test_fatal_on_smp)817 ZTEST(smp, test_fatal_on_smp)
818 {
819 	/* Creat a child thread and trigger a crash */
820 	k_thread_create(&t2, t2_stack, T2_STACK_SIZE, entry_oops,
821 				      NULL, NULL, NULL,
822 				      K_PRIO_PREEMPT(2), 0, K_NO_WAIT);
823 
824 	/* hold cpu and wait for thread trigger exception and being terminated */
825 	k_busy_wait(5 * DELAY_US);
826 
827 	/* Verify that child thread is no longer running. We can't simply use k_thread_join here
828 	 * as we don't want to introduce reschedule point here.
829 	 */
830 	zassert_true(z_is_thread_state_set(&t2, _THREAD_DEAD));
831 
832 	/* Manually trigger the crash in mainthread */
833 	entry_oops(NULL, NULL, NULL);
834 
835 	/* should not be here */
836 	ztest_test_fail();
837 }
838 
workq_handler(struct k_work * work)839 static void workq_handler(struct k_work *work)
840 {
841 	child_thread_id = curr_cpu();
842 }
843 
844 /**
845  * @brief Test system workq run on different core
846 
847  * @details When macro CONFIG_SMP is enabled, workq can be run
848  * on different core.
849  *
850  * @ingroup kernel_common_tests
851  */
ZTEST(smp,test_workq_on_smp)852 ZTEST(smp, test_workq_on_smp)
853 {
854 	static struct k_work work;
855 
856 	k_work_init(&work, workq_handler);
857 
858 	/* submit work item on system workq */
859 	k_work_submit(&work);
860 
861 	/* Wait for some time to let other core's thread run */
862 	k_busy_wait(DELAY_US);
863 
864 	/* check work have finished */
865 	zassert_equal(k_work_busy_get(&work), 0);
866 
867 	main_thread_id = curr_cpu();
868 
869 	/* Verify the ztest thread and system workq run on different core */
870 	zassert_true(main_thread_id != child_thread_id,
871 		"system workq run on the same core");
872 }
873 
t1_mutex_lock(void * p1,void * p2,void * p3)874 static void t1_mutex_lock(void *p1, void *p2, void *p3)
875 {
876 	ARG_UNUSED(p2);
877 	ARG_UNUSED(p3);
878 
879 	/* t1 will get mutex first */
880 	k_mutex_lock((struct k_mutex *)p1, K_FOREVER);
881 
882 	k_msleep(2);
883 
884 	k_mutex_unlock((struct k_mutex *)p1);
885 }
886 
t2_mutex_lock(void * p1,void * p2,void * p3)887 static void t2_mutex_lock(void *p1, void *p2, void *p3)
888 {
889 	ARG_UNUSED(p2);
890 	ARG_UNUSED(p3);
891 
892 	zassert_equal(_current->base.global_lock_count, 0,
893 			"thread global lock cnt %d is incorrect",
894 			_current->base.global_lock_count);
895 
896 	k_mutex_lock((struct k_mutex *)p1, K_FOREVER);
897 
898 	zassert_equal(_current->base.global_lock_count, 0,
899 			"thread global lock cnt %d is incorrect",
900 			_current->base.global_lock_count);
901 
902 	k_mutex_unlock((struct k_mutex *)p1);
903 
904 	/**TESTPOINT: z_smp_release_global_lock() has been call during
905 	 * context switch but global_lock_cnt has not been decrease
906 	 * because no irq_lock() was called.
907 	 */
908 	zassert_equal(_current->base.global_lock_count, 0,
909 			"thread global lock cnt %d is incorrect",
910 			_current->base.global_lock_count);
911 }
912 
913 /**
914  * @brief Test scenario that a thread release the global lock
915  *
916  * @ingroup kernel_smp_tests
917  *
918  * @details Validate the scenario that make the internal APIs of SMP
919  * z_smp_release_global_lock() to be called.
920  */
ZTEST(smp,test_smp_release_global_lock)921 ZTEST(smp, test_smp_release_global_lock)
922 {
923 	k_mutex_init(&smutex);
924 
925 	tinfo[0].tid =
926 	k_thread_create(&tthread[0], tstack[0], STACK_SIZE,
927 			t1_mutex_lock,
928 			&smutex, NULL, NULL,
929 			K_PRIO_PREEMPT(5),
930 			K_INHERIT_PERMS, K_NO_WAIT);
931 
932 	tinfo[1].tid =
933 	k_thread_create(&tthread[1], tstack[1], STACK_SIZE,
934 		t2_mutex_lock,
935 			&smutex, NULL, NULL,
936 			K_PRIO_PREEMPT(3),
937 			K_INHERIT_PERMS, K_MSEC(1));
938 
939 	/* Hold one of the cpu to ensure context switch as we wanted
940 	 * can happen in another cpu.
941 	 */
942 	k_busy_wait(20000);
943 
944 	k_thread_join(tinfo[1].tid, K_FOREVER);
945 	k_thread_join(tinfo[0].tid, K_FOREVER);
946 	cleanup_resources();
947 }
948 
949 #define LOOP_COUNT ((int)(20000 * RUN_FACTOR))
950 
951 enum sync_t {
952 	LOCK_IRQ,
953 	LOCK_SEM,
954 	LOCK_MUTEX
955 };
956 
957 static int global_cnt;
958 static struct k_mutex smp_mutex;
959 
960 static void (*sync_lock)(void *);
961 static void (*sync_unlock)(void *);
962 
sync_lock_dummy(void * k)963 static void sync_lock_dummy(void *k)
964 {
965 	/* no sync lock used */
966 }
967 
sync_lock_irq(void * k)968 static void sync_lock_irq(void *k)
969 {
970 	*((unsigned int *)k) = irq_lock();
971 }
972 
sync_unlock_irq(void * k)973 static void sync_unlock_irq(void *k)
974 {
975 	irq_unlock(*(unsigned int *)k);
976 }
977 
sync_lock_sem(void * k)978 static void sync_lock_sem(void *k)
979 {
980 	k_sem_take(&smp_sem, K_FOREVER);
981 }
982 
sync_unlock_sem(void * k)983 static void sync_unlock_sem(void *k)
984 {
985 	k_sem_give(&smp_sem);
986 }
987 
sync_lock_mutex(void * k)988 static void sync_lock_mutex(void *k)
989 {
990 	k_mutex_lock(&smp_mutex, K_FOREVER);
991 }
992 
sync_unlock_mutex(void * k)993 static void sync_unlock_mutex(void *k)
994 {
995 	k_mutex_unlock(&smp_mutex);
996 }
997 
sync_init(int lock_type)998 static void sync_init(int lock_type)
999 {
1000 	switch (lock_type) {
1001 	case LOCK_IRQ:
1002 		sync_lock = sync_lock_irq;
1003 		sync_unlock = sync_unlock_irq;
1004 		break;
1005 	case LOCK_SEM:
1006 		sync_lock = sync_lock_sem;
1007 		sync_unlock = sync_unlock_sem;
1008 		k_sem_init(&smp_sem, 1, 3);
1009 		break;
1010 	case LOCK_MUTEX:
1011 		sync_lock = sync_lock_mutex;
1012 		sync_unlock = sync_unlock_mutex;
1013 		k_mutex_init(&smp_mutex);
1014 		break;
1015 
1016 	default:
1017 		sync_lock = sync_unlock = sync_lock_dummy;
1018 	}
1019 }
1020 
inc_global_cnt(void * a,void * b,void * c)1021 static void inc_global_cnt(void *a, void *b, void *c)
1022 {
1023 	int key;
1024 
1025 	for (int i = 0; i < LOOP_COUNT; i++) {
1026 
1027 		sync_lock(&key);
1028 
1029 		global_cnt++;
1030 		global_cnt--;
1031 		global_cnt++;
1032 
1033 		sync_unlock(&key);
1034 	}
1035 }
1036 
run_concurrency(void * p1,void * p2,void * p3)1037 static int run_concurrency(void *p1, void *p2, void *p3)
1038 {
1039 	ARG_UNUSED(p3);
1040 
1041 	int type = POINTER_TO_INT(p1);
1042 	k_thread_entry_t func = p2;
1043 	uint32_t start_t, end_t;
1044 
1045 	sync_init(type);
1046 	global_cnt = 0;
1047 	start_t = k_cycle_get_32();
1048 
1049 	tinfo[0].tid =
1050 	k_thread_create(&tthread[0], tstack[0], STACK_SIZE,
1051 			func,
1052 			NULL, NULL, NULL,
1053 			K_PRIO_PREEMPT(1),
1054 			K_INHERIT_PERMS, K_NO_WAIT);
1055 
1056 	tinfo[1].tid =
1057 	k_thread_create(&tthread[1], tstack[1], STACK_SIZE,
1058 			func,
1059 			NULL, NULL, NULL,
1060 			K_PRIO_PREEMPT(1),
1061 			K_INHERIT_PERMS, K_NO_WAIT);
1062 
1063 	k_tid_t tid =
1064 	k_thread_create(&t2, t2_stack, T2_STACK_SIZE,
1065 			func,
1066 			NULL, NULL, NULL,
1067 			K_PRIO_PREEMPT(1),
1068 			K_INHERIT_PERMS, K_NO_WAIT);
1069 
1070 	k_thread_join(tinfo[0].tid, K_FOREVER);
1071 	k_thread_join(tinfo[1].tid, K_FOREVER);
1072 	k_thread_join(tid, K_FOREVER);
1073 	cleanup_resources();
1074 
1075 	end_t =  k_cycle_get_32();
1076 
1077 	printk("type %d: cnt %d, spend %u ms\n", type, global_cnt,
1078 		k_cyc_to_ms_ceil32(end_t - start_t));
1079 
1080 	return global_cnt == (LOOP_COUNT * 3);
1081 }
1082 
1083 /**
1084  * @brief Test if the concurrency of SMP works or not
1085  *
1086  * @ingroup kernel_smp_tests
1087  *
1088  * @details Validate the global lock and unlock API of SMP are thread-safe.
1089  * We make 3 thread to increase the global count in different cpu and
1090  * they both do locking then unlocking for LOOP_COUNT times. It shall be no
1091  * deadlock happened and total global count shall be 3 * LOOP COUNT.
1092  *
1093  * We show the 4 kinds of scenario:
1094  * - No any lock used
1095  * - Use global irq lock
1096  * - Use semaphore
1097  * - Use mutex
1098  */
ZTEST(smp,test_inc_concurrency)1099 ZTEST(smp, test_inc_concurrency)
1100 {
1101 	/* increasing global var with irq lock */
1102 	zassert_true(run_concurrency(INT_TO_POINTER(LOCK_IRQ), inc_global_cnt, NULL),
1103 			"total count %d is wrong(i)", global_cnt);
1104 
1105 	/* increasing global var with irq lock */
1106 	zassert_true(run_concurrency(INT_TO_POINTER(LOCK_SEM), inc_global_cnt, NULL),
1107 			"total count %d is wrong(s)", global_cnt);
1108 
1109 	/* increasing global var with irq lock */
1110 	zassert_true(run_concurrency(INT_TO_POINTER(LOCK_MUTEX), inc_global_cnt, NULL),
1111 			"total count %d is wrong(M)", global_cnt);
1112 }
1113 
1114 /** Keep track of how many signals raised. */
1115 static unsigned int t_signal_raised;
1116 
1117 /** Keep track of how many signals received per thread. */
1118 static unsigned int t_signals_rcvd[MAX_NUM_THREADS];
1119 
1120 /**
1121  * @brief Stress test for context switching code
1122  *
1123  * @ingroup kernel_smp_tests
1124  *
1125  * @details Leverage the polling API to stress test the context switching code.
1126  *          This test will hammer all the CPUs with thread swapping requests.
1127  */
process_events(void * arg0,void * arg1,void * arg2)1128 static void process_events(void *arg0, void *arg1, void *arg2)
1129 {
1130 	ARG_UNUSED(arg1);
1131 	ARG_UNUSED(arg2);
1132 
1133 	uintptr_t id = (uintptr_t) arg0;
1134 	unsigned int signaled;
1135 	int result;
1136 
1137 	while (1) {
1138 		/* Retry if no event(s) are ready.
1139 		 * For example, -EINTR where polling is interrupted.
1140 		 */
1141 		if (k_poll(&tevent[id], 1, K_FOREVER) != 0) {
1142 			continue;
1143 		}
1144 
1145 		/* Grab the raised signal. */
1146 		k_poll_signal_check(tevent[id].signal, &signaled, &result);
1147 
1148 		/* Check correct result. */
1149 		if (result != 0x55) {
1150 			ztest_test_fail();
1151 		}
1152 
1153 		t_signals_rcvd[id]++;
1154 
1155 		/* Reset both event and signal. */
1156 		tevent[id].state = K_POLL_STATE_NOT_READY;
1157 		tevent[id].signal->result = 0;
1158 		k_poll_signal_reset(tevent[id].signal);
1159 	}
1160 }
1161 
signal_raise(void * arg0,void * arg1,void * arg2)1162 static void signal_raise(void *arg0, void *arg1, void *arg2)
1163 {
1164 	unsigned int num_threads = arch_num_cpus();
1165 	unsigned int signaled;
1166 	int result;
1167 
1168 	t_signal_raised = 0U;
1169 
1170 	while (1) {
1171 		for (uintptr_t i = 0; i < num_threads; i++) {
1172 			/* Only raise signal when it is okay to do so.
1173 			 * We don't want to raise a signal while the signal
1174 			 * and the associated event are still in the process
1175 			 * of being reset (see above).
1176 			 */
1177 			k_poll_signal_check(tevent[i].signal, &signaled, &result);
1178 
1179 			if (signaled != 0U) {
1180 				continue;
1181 			}
1182 
1183 			t_signal_raised++;
1184 			k_poll_signal_raise(&tsignal[i], 0x55);
1185 		}
1186 	}
1187 }
1188 
ZTEST(smp_stress,test_smp_switch_stress)1189 ZTEST(smp_stress, test_smp_switch_stress)
1190 {
1191 	unsigned int num_threads = arch_num_cpus();
1192 
1193 	if (CONFIG_SMP_TEST_RUN_FACTOR == 0) {
1194 		/* If CONFIG_SMP_TEST_RUN_FACTOR is zero,
1195 		 * the switch stress test is effectively
1196 		 * not doing anything as the k_sleep()
1197 		 * below is not going to sleep at all,
1198 		 * and all created threads are being
1199 		 * terminated (almost) immediately after
1200 		 * creation. So if run factor is zero,
1201 		 * mark the test as skipped.
1202 		 */
1203 		ztest_test_skip();
1204 	}
1205 
1206 	for (uintptr_t i = 0; i < num_threads; i++) {
1207 		t_signals_rcvd[i] = 0;
1208 
1209 		k_poll_signal_init(&tsignal[i]);
1210 		k_poll_event_init(&tevent[i], K_POLL_TYPE_SIGNAL,
1211 				  K_POLL_MODE_NOTIFY_ONLY, &tsignal[i]);
1212 
1213 		k_thread_create(&tthread[i], tstack[i], STACK_SIZE,
1214 				process_events,
1215 				(void *) i, NULL, NULL, K_PRIO_PREEMPT(i + 1),
1216 				K_INHERIT_PERMS, K_NO_WAIT);
1217 	}
1218 
1219 	k_thread_create(&t2, t2_stack, T2_STACK_SIZE, signal_raise,
1220 			NULL, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT);
1221 
1222 	k_sleep(K_MSEC(SLEEP_MS_LONG));
1223 
1224 	k_thread_abort(&t2);
1225 	k_thread_join(&t2, K_FOREVER);
1226 	for (uintptr_t i = 0; i < num_threads; i++) {
1227 		k_thread_abort(&tthread[i]);
1228 		k_thread_join(&tthread[i], K_FOREVER);
1229 	}
1230 
1231 	TC_PRINT("Total signals raised %u\n", t_signal_raised);
1232 
1233 	for (unsigned int i = 0; i < num_threads; i++) {
1234 		TC_PRINT("Thread #%d received %u signals\n", i, t_signals_rcvd[i]);
1235 	}
1236 
1237 	/* Check if we at least have done some switching. */
1238 	for (unsigned int i = 0; i < num_threads; i++) {
1239 		zassert_not_equal(0, t_signals_rcvd[i],
1240 				  "Thread #%d has not received any signals", i);
1241 	}
1242 }
1243 
1244 /**
1245  * @brief Stress test for cpu affinity code
1246  *
1247  * @ingroup kernel_smp_tests
1248  *
1249  * @details Pin thread to a specific cpu. Once thread gets cpu, check
1250  *          the cpu id is correct and then thread will give up cpu.
1251  */
1252 #ifdef CONFIG_SCHED_CPU_MASK
check_affinity(void * arg0,void * arg1,void * arg2)1253 static void check_affinity(void *arg0, void *arg1, void *arg2)
1254 {
1255 	ARG_UNUSED(arg1);
1256 	ARG_UNUSED(arg2);
1257 
1258 	int affinity = POINTER_TO_INT(arg0);
1259 	int counter = 30;
1260 
1261 	while (counter != 0) {
1262 		zassert_equal(affinity, curr_cpu(), "Affinity test failed.");
1263 		counter--;
1264 		k_yield();
1265 	}
1266 }
1267 
ZTEST(smp,test_smp_affinity)1268 ZTEST(smp, test_smp_affinity)
1269 {
1270 	int num_threads = arch_num_cpus();
1271 
1272 	for (int i = 0; i < num_threads; ++i) {
1273 		k_thread_create(&tthread[i], tstack[i],
1274 					       STACK_SIZE, check_affinity,
1275 					       INT_TO_POINTER(i), NULL, NULL,
1276 					       0, 0, K_FOREVER);
1277 
1278 		k_thread_cpu_pin(&tthread[i], i);
1279 		k_thread_start(&tthread[i]);
1280 	}
1281 
1282 	for (int i = 0; i < num_threads; i++) {
1283 		k_thread_join(&tthread[i], K_FOREVER);
1284 	}
1285 }
1286 #endif
1287 
smp_tests_setup(void)1288 static void *smp_tests_setup(void)
1289 {
1290 	/* Sleep a bit to guarantee that both CPUs enter an idle
1291 	 * thread from which they can exit correctly to run the main
1292 	 * test.
1293 	 */
1294 	k_sleep(K_MSEC(10));
1295 
1296 	return NULL;
1297 }
1298 
1299 ZTEST_SUITE(smp, NULL, smp_tests_setup, NULL, NULL, NULL);
1300 ZTEST_SUITE(smp_stress, NULL, smp_tests_setup, NULL, NULL, NULL);
1301