projects/linux·blob master · refs

68 lines · 1.2 KiB

1/* SPDX-License-Identifier: GPL-2.0 */
2#include <signal.h>
3#include <stdlib.h>
4#include <linux/compiler.h>
5#include <unistd.h>
6#include "../tests.h"
7
8/* We want to check these symbols in perf script */
9noinline void leaf(void);
10noinline void parent(void);
11
12static volatile sig_atomic_t done asm("leafloop_done");
13
14static void sighandler(int sig __maybe_unused)
15{
16 done = 1;
17}
18
19#if defined(__aarch64__)
20/*
21 * Write leaf() in assembly so it stays as a minimal leaf function with no
22 * stack frame and won't get silently broken in the future by any Perf wide
23 * compilation options like -fstack-protector-all.
24 */
25asm(
26 ".pushsection .text,\"ax\",%progbits\n"
27 ".global leaf\n"
28 ".type leaf, %function\n"
29 "leaf:\n"
30 " adrp x1, leafloop_done\n"
31 " ldr w2, [x1, #:lo12:leafloop_done]\n"
32 " cbz w2, leaf\n"
33 " ret\n"
34 ".size leaf, .-leaf\n"
35 ".popsection\n"
36);
37
38#else
39
40noinline void leaf(void)
41{
42 while (!done)
43 ;
44}
45
46#endif
47
48noinline void parent(void)
49{
50 leaf();
51}
52
53static int leafloop(int argc, const char **argv)
54{
55 int sec = 1;
56
57 if (argc > 0)
58 sec = atoi(argv[0]);
59
60 signal(SIGINT, sighandler);
61 signal(SIGALRM, sighandler);
62 alarm(sec);
63
64 parent();
65 return 0;
66}
67
68DEFINE_WORKLOAD(leafloop);