1 #include <stdlib.h> 2 #include <signal.h> 3 #include <unistd.h> 4 #include <linux/compiler.h> 5 #include "../tests.h" 6 7 typedef struct _buf { 8 char data1; 9 char reserved[55]; 10 char data2; 11 } buf __attribute__((aligned(64))); 12 13 /* volatile to try to avoid the compiler seeing reserved as unused. */ 14 static volatile buf workload_datasym_buf1 = { 15 /* to have this in the data section */ 16 .reserved[0] = 1, 17 }; 18 19 static volatile sig_atomic_t done; 20 sighandler(int sig __maybe_unused)21static void sighandler(int sig __maybe_unused) 22 { 23 done = 1; 24 } 25 datasym(int argc,const char ** argv)26static int datasym(int argc, const char **argv) 27 { 28 int sec = 1; 29 30 if (argc > 0) 31 sec = atoi(argv[0]); 32 33 signal(SIGINT, sighandler); 34 signal(SIGALRM, sighandler); 35 alarm(sec); 36 37 while (!done) { 38 workload_datasym_buf1.data1++; 39 if (workload_datasym_buf1.data1 == 123) { 40 /* 41 * Add some 'noise' in the loop to work around errata 42 * 1694299 on Arm N1. 43 * 44 * Bias exists in SPE sampling which can cause the load 45 * and store instructions to be skipped entirely. This 46 * comes and goes randomly depending on the offset the 47 * linker places the datasym loop at in the Perf binary. 48 * With an extra branch in the middle of the loop that 49 * isn't always taken, the instruction stream is no 50 * longer a continuous repeating pattern that interacts 51 * badly with the bias. 52 */ 53 workload_datasym_buf1.data1++; 54 } 55 workload_datasym_buf1.data2 += workload_datasym_buf1.data1; 56 } 57 return 0; 58 } 59 60 DEFINE_WORKLOAD(datasym); 61