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 */ 9 noinline void leaf(void); 10 noinline void parent(void); 11 12 static volatile sig_atomic_t done asm("leafloop_done"); 13 14 static 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 */ 25 asm( 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 40 noinline void leaf(void) 41 { 42 while (!done) 43 ; 44 } 45 46 #endif 47 48 noinline void parent(void) 49 { 50 leaf(); 51 } 52 53 static 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 68 DEFINE_WORKLOAD(leafloop); 69