Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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);