at v6.19 60 lines 1.4 kB view raw
1#include <stdlib.h> 2#include <signal.h> 3#include <unistd.h> 4#include <linux/compiler.h> 5#include "../tests.h" 6 7typedef 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. */ 14static volatile buf workload_datasym_buf1 = { 15 /* to have this in the data section */ 16 .reserved[0] = 1, 17}; 18 19static volatile sig_atomic_t done; 20 21static void sighandler(int sig __maybe_unused) 22{ 23 done = 1; 24} 25 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 60DEFINE_WORKLOAD(datasym);