mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

With LTO builds, although regular builds could also see this as
all the code is in one file, the datasym workload can realize the
buf1.reserved data is never accessed. The compiler moves the
variable to bss and only keeps the data1 and data2 parts as
separate variables. This causes the symbol check to fail in the
test. Make the variable volatile to disable the more aggressive
optimization. Rename the variable to make which buf1 in perf is
being referred to.
Before:
$ perf test -vv "data symbol"
126: Test data symbol:
--- start ---
test child forked, pid 299808
perf does not have symbol 'buf1'
perf is missing symbols - skipping test
---- end(-2) ----
126: Test data symbol : Skip
$ nm perf|grep buf1
0000000000a5fa40 b buf1.0
0000000000a5fa48 b buf1.1
After:
$ nm perf|grep buf1
0000000000a53a00 d buf1
$ perf test -vv "data symbol"126: Test data symbol:
--- start ---
test child forked, pid 302166
a53a00-a53a39 l buf1
perf does have symbol 'buf1'
Recording workload...
Waiting for "perf record has started" message
OK
Cleaning up files...
---- end(0) ----
126: Test data symbol : Ok
Fixes: 3dfc01fe9d
("perf test: Add 'datasym' test workload")
Signed-off-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250226230109.314580-1-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
60 lines
1.4 KiB
C
60 lines
1.4 KiB
C
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <linux/compiler.h>
|
|
#include "../tests.h"
|
|
|
|
typedef struct _buf {
|
|
char data1;
|
|
char reserved[55];
|
|
char data2;
|
|
} buf __attribute__((aligned(64)));
|
|
|
|
/* volatile to try to avoid the compiler seeing reserved as unused. */
|
|
static volatile buf workload_datasym_buf1 = {
|
|
/* to have this in the data section */
|
|
.reserved[0] = 1,
|
|
};
|
|
|
|
static volatile sig_atomic_t done;
|
|
|
|
static void sighandler(int sig __maybe_unused)
|
|
{
|
|
done = 1;
|
|
}
|
|
|
|
static int datasym(int argc, const char **argv)
|
|
{
|
|
int sec = 1;
|
|
|
|
if (argc > 0)
|
|
sec = atoi(argv[0]);
|
|
|
|
signal(SIGINT, sighandler);
|
|
signal(SIGALRM, sighandler);
|
|
alarm(sec);
|
|
|
|
while (!done) {
|
|
workload_datasym_buf1.data1++;
|
|
if (workload_datasym_buf1.data1 == 123) {
|
|
/*
|
|
* Add some 'noise' in the loop to work around errata
|
|
* 1694299 on Arm N1.
|
|
*
|
|
* Bias exists in SPE sampling which can cause the load
|
|
* and store instructions to be skipped entirely. This
|
|
* comes and goes randomly depending on the offset the
|
|
* linker places the datasym loop at in the Perf binary.
|
|
* With an extra branch in the middle of the loop that
|
|
* isn't always taken, the instruction stream is no
|
|
* longer a continuous repeating pattern that interacts
|
|
* badly with the bias.
|
|
*/
|
|
workload_datasym_buf1.data1++;
|
|
}
|
|
workload_datasym_buf1.data2 += workload_datasym_buf1.data1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
DEFINE_WORKLOAD(datasym);
|