1 #include <linux/compiler.h>
2 #include "../tests.h"
3 
4 typedef struct _buf {
5 	char data1;
6 	char reserved[55];
7 	char data2;
8 } buf __attribute__((aligned(64)));
9 
10 static buf buf1 = {
11 	/* to have this in the data section */
12 	.reserved[0] = 1,
13 };
14 
datasym(int argc __maybe_unused,const char ** argv __maybe_unused)15 static int datasym(int argc __maybe_unused, const char **argv __maybe_unused)
16 {
17 	for (;;) {
18 		buf1.data1++;
19 		if (buf1.data1 == 123) {
20 			/*
21 			 * Add some 'noise' in the loop to work around errata
22 			 * 1694299 on Arm N1.
23 			 *
24 			 * Bias exists in SPE sampling which can cause the load
25 			 * and store instructions to be skipped entirely. This
26 			 * comes and goes randomly depending on the offset the
27 			 * linker places the datasym loop at in the Perf binary.
28 			 * With an extra branch in the middle of the loop that
29 			 * isn't always taken, the instruction stream is no
30 			 * longer a continuous repeating pattern that interacts
31 			 * badly with the bias.
32 			 */
33 			buf1.data1++;
34 		}
35 		buf1.data2 += buf1.data1;
36 	}
37 	return 0;
38 }
39 
40 DEFINE_WORKLOAD(datasym);
41