1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2014, Michael Ellerman, IBM Corp. 4 */ 5 6 #include <stdbool.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <signal.h> 10 11 #include "ebb.h" 12 13 14 /* 15 * Test running multiple EBB using processes at once on a single CPU. They 16 * should all run happily without interfering with each other. 17 */ 18 19 static bool child_should_exit; 20 21 static void sigint_handler(int signal) 22 { 23 child_should_exit = true; 24 } 25 26 struct sigaction sigint_action = { 27 .sa_handler = sigint_handler, 28 }; 29 30 static int cycles_child(void) 31 { 32 struct event event; 33 34 if (sigaction(SIGINT, &sigint_action, NULL)) { 35 perror("sigaction"); 36 return 1; 37 } 38 39 event_init_named(&event, 0x1001e, "cycles"); 40 event_leader_ebb_init(&event); 41 42 event.attr.exclude_kernel = 1; 43 event.attr.exclude_hv = 1; 44 event.attr.exclude_idle = 1; 45 46 FAIL_IF(event_open(&event)); 47 48 ebb_enable_pmc_counting(1); 49 setup_ebb_handler(standard_ebb_callee); 50 ebb_global_enable(); 51 52 FAIL_IF(ebb_event_enable(&event)); 53 54 mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); 55 56 while (!child_should_exit) { 57 FAIL_IF(core_busy_loop()); 58 FAIL_IF(ebb_check_mmcr0()); 59 } 60 61 ebb_global_disable(); 62 ebb_freeze_pmcs(); 63 64 dump_summary_ebb_state(); 65 66 event_close(&event); 67 68 FAIL_IF(ebb_state.stats.ebb_count == 0); 69 70 return 0; 71 } 72 73 #define NR_CHILDREN 4 74 75 int multi_ebb_procs(void) 76 { 77 pid_t pids[NR_CHILDREN]; 78 int cpu, rc, i; 79 80 SKIP_IF(!ebb_is_supported()); 81 82 cpu = pick_online_cpu(); 83 FAIL_IF(cpu < 0); 84 FAIL_IF(bind_to_cpu(cpu)); 85 86 for (i = 0; i < NR_CHILDREN; i++) { 87 pids[i] = fork(); 88 if (pids[i] == 0) 89 exit(cycles_child()); 90 } 91 92 /* Have them all run for "a while" */ 93 sleep(10); 94 95 rc = 0; 96 for (i = 0; i < NR_CHILDREN; i++) { 97 /* Tell them to stop */ 98 kill(pids[i], SIGINT); 99 /* And wait */ 100 rc |= wait_for_child(pids[i]); 101 } 102 103 return rc; 104 } 105 106 int main(void) 107 { 108 return test_harness(multi_ebb_procs, "multi_ebb_procs"); 109 } 110