Add test kernel ring overflow test for nOS-V
There is a problem in the way we are reading the buffer in nOS-V, which fails when the ring buffer gets full. This regression test ensures it is fixed. Reported-by: David Álvarez <david.alvarez@bsc.es>
This commit is contained in:
		
							parent
							
								
									6cb983a7c4
								
							
						
					
					
						commit
						e9788e22ad
					
				| @ -44,6 +44,7 @@ nosv_test(parallel-tasks.c SORT) | ||||
| nosv_test(inline.c SORT) | ||||
| nosv_test(mutex.c SORT LEVEL 3) | ||||
| nosv_test(barrier.c SORT LEVEL 3) | ||||
| nosv_test(overflow-kernel-ring.c SORT LEVEL 3) | ||||
| 
 | ||||
| # Test multiple instrumentation levels | ||||
| nosv_test(several-tasks.c SORT NAME several-tasks-level-0 LEVEL 0) | ||||
|  | ||||
							
								
								
									
										77
									
								
								test/rt/nosv/overflow-kernel-ring.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								test/rt/nosv/overflow-kernel-ring.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| /* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include <nosv.h> | ||||
| #include <nosv/affinity.h> | ||||
| #include <stdatomic.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "compat.h" | ||||
| 
 | ||||
| int done = 0; | ||||
| 
 | ||||
| /* https://gitlab.bsc.es/nos-v/nos-v/-/blob/master/src/include/instr.h?ref_type=heads#L542 */ | ||||
| #define NOSV_INSTR_KBUFLEN (4UL * 1024UL * 1024UL) // 4 MB
 | ||||
| 
 | ||||
| static void | ||||
| task_run(nosv_task_t task) | ||||
| { | ||||
| 	UNUSED(task); | ||||
| 
 | ||||
| 	/* Cause enough context switches for the kernel ring to be full,
 | ||||
| 	 * which wouldn't fail if nosv_waitfor() flushes the kernel | ||||
| 	 * events. */ | ||||
| 
 | ||||
| 	unsigned long fill = 3 * NOSV_INSTR_KBUFLEN / 4; | ||||
| 	unsigned long n = fill / 16; | ||||
| 
 | ||||
| 	struct timespec one_ns = { .tv_sec = 0, .tv_nsec = 1 }; | ||||
| 
 | ||||
| 	for (unsigned long run = 0; run < 3; run++) { | ||||
| 		info("starting run %lu", run); | ||||
| 		for (unsigned long i = 0; i < n; i++) | ||||
| 			nanosleep(&one_ns, NULL); | ||||
| 
 | ||||
| 		info("starting waitfor"); | ||||
| 
 | ||||
| 		if (nosv_waitfor(1, NULL) != 0) | ||||
| 			die("nosv_waitfor failed"); | ||||
| 
 | ||||
| 		info("end run %lu", run); | ||||
| 	} | ||||
| 
 | ||||
| 	done = 1; | ||||
| } | ||||
| 
 | ||||
| int main(void) | ||||
| { | ||||
| 	if (nosv_init()) | ||||
| 		die("nosv_init failed"); | ||||
| 
 | ||||
| 	nosv_task_type_t task_type; | ||||
| 	if (nosv_type_init(&task_type, task_run, NULL, NULL, "task", NULL, NULL, NOSV_TYPE_INIT_NONE)) | ||||
| 		die("nosv_type_init failed"); | ||||
| 
 | ||||
| 	nosv_task_t task; | ||||
| 	if (nosv_create(&task, task_type, 0, NOSV_CREATE_NONE)) | ||||
| 		die("nosv_create failed"); | ||||
| 
 | ||||
| 	if (nosv_submit(task, NOSV_SUBMIT_IMMEDIATE)) | ||||
| 		die("nosv_submit failed"); | ||||
| 
 | ||||
| 	/* Wait for the task to finish */ | ||||
| 	while (!done) | ||||
| 		sleep_us(10000); | ||||
| 
 | ||||
| 	if (nosv_destroy(task, NOSV_DESTROY_NONE)) | ||||
| 		die("nosv_destroy failed"); | ||||
| 
 | ||||
| 	if (nosv_type_destroy(task_type, NOSV_TYPE_DESTROY_NONE)) | ||||
| 		die("nosv_type_destroy failed"); | ||||
| 
 | ||||
| 	if (nosv_shutdown()) | ||||
| 		die("nosv_shutdown failed"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user