Make nOS-V kernel overflow test configurable
This commit is contained in:
		
							parent
							
								
									e9788e22ad
								
							
						
					
					
						commit
						acf18c1bb4
					
				| @ -44,7 +44,6 @@ 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) | ||||
| @ -63,3 +62,13 @@ nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-2 LEVEL 2 BREA | ||||
| # From level 3 up the breakdown can be enabled | ||||
| nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-3 LEVEL 3 BREAKDOWN) | ||||
| nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN) | ||||
| 
 | ||||
| include(CheckPerfParanoid) | ||||
| if (PERF_PARANOID_KERNEL) | ||||
|   message(STATUS "Enabling perf paranoid tests for nOS-V") | ||||
|   nosv_test(overflow-kernel-ring.c DRIVER "overflow-kernel-ring.driver.sh") | ||||
| elseif(ENABLE_ALL_TESTS) | ||||
|   message(FATAL_ERROR "Cannot enable perf paranoid tests for nOS-V") | ||||
| else() | ||||
|   message(STATUS "Disabling perf paranoid tests for nOS-V") | ||||
| endif() | ||||
|  | ||||
| @ -5,47 +5,44 @@ | ||||
| #include <nosv/affinity.h> | ||||
| #include <stdatomic.h> | ||||
| #include <unistd.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.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
 | ||||
| unsigned long ncs = 0; | ||||
| unsigned long nflush = 0; | ||||
| 
 | ||||
| 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); | ||||
| 	for (unsigned long i = 1; i <= ncs; i++) { | ||||
| 		nanosleep(&one_ns, NULL); | ||||
| 		/* Make a total of 16 waitfor calls to flush the ring buffer */ | ||||
| 		if (i % nflush == 0) { | ||||
| 			info("flusing at %lu", i); | ||||
| 			if (nosv_waitfor(1, NULL) != 0) | ||||
| 				die("nosv_waitfor failed"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	done = 1; | ||||
| } | ||||
| 
 | ||||
| int main(void) | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
| 	if (argc != 3) | ||||
| 		die("usage: %s <num-cs> <num-flush>\n", argv[0]); | ||||
| 
 | ||||
| 	ncs = (unsigned long) atol(argv[1]); | ||||
| 	nflush = (unsigned long) atol(argv[2]); | ||||
| 
 | ||||
| 	if (nosv_init()) | ||||
| 		die("nosv_init failed"); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										46
									
								
								test/rt/nosv/overflow-kernel-ring.driver.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								test/rt/nosv/overflow-kernel-ring.driver.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| target=$OVNI_TEST_BIN | ||||
| 
 | ||||
| # We will set our own | ||||
| unset NOSV_CONFIG | ||||
| unset NOSV_CONFIG_OVERRIDE | ||||
| 
 | ||||
| export NOSV_APPID=1 | ||||
| 
 | ||||
| # Small kernel ring size to make execution fast | ||||
| ringsize=$((64*1024)) | ||||
| 
 | ||||
| # Each CS event pair occupies 16 bytes. | ||||
| cspair=32 | ||||
| 
 | ||||
| # How many CS event pairs fit in the ring buffer? | ||||
| navail=$(($ringsize / $cspair)) | ||||
| 
 | ||||
| # For the test, write 8 times the ring buffer | ||||
| ncs=$((8 * $navail)) | ||||
| 
 | ||||
| # Flush the kernel after writing 1/4 of the ring buffer.  | ||||
| nflush=$(($ringsize / $cspair / 4)) | ||||
| 
 | ||||
| cat > nosv.toml << EOF | ||||
| instrumentation.version = "ovni" | ||||
| ovni.level = 3 | ||||
| ovni.kernel_ringsize = ${ringsize} | ||||
| EOF | ||||
| 
 | ||||
| $target $ncs $nflush 2>&1 | tee err.log | ||||
| 
 | ||||
| # Ensure no nOS-V warnings at runtime | ||||
| if grep -c "cannot enable kernel events" err.log; then | ||||
|   echo "cannot enable kernel events in all threads" >&2 | ||||
|   exit 1 | ||||
| fi | ||||
| 
 | ||||
| # We need to sort the trace as it has unsorted regions | ||||
| ovnisort ovni | ||||
| 
 | ||||
| # Ensure we have at least the number of context switches we caused, and ensure | ||||
| # the number of "in" and "out" events match. | ||||
| ovnitop ovni | awk '{n[$1] = $2} END { if (n["KCO"] != n["KCI"] || n["KCO"] < '$ncs') exit 1 }' | ||||
| 
 | ||||
| # Run the emulator | ||||
| ovniemu -l ovni | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user