1 /* 2 * Copyright 2014, Michael Ellerman, IBM Corp. 3 * Licensed under GPLv2. 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 count_pmc(1, sample_period); 65 66 dump_summary_ebb_state(); 67 68 event_close(&event); 69 70 FAIL_IF(ebb_state.stats.ebb_count == 0); 71 72 return 0; 73 } 74 75 #define NR_CHILDREN 4 76 77 int multi_ebb_procs(void) 78 { 79 pid_t pids[NR_CHILDREN]; 80 int cpu, rc, i; 81 82 SKIP_IF(!ebb_is_supported()); 83 84 cpu = pick_online_cpu(); 85 FAIL_IF(cpu < 0); 86 FAIL_IF(bind_to_cpu(cpu)); 87 88 for (i = 0; i < NR_CHILDREN; i++) { 89 pids[i] = fork(); 90 if (pids[i] == 0) 91 exit(cycles_child()); 92 } 93 94 /* Have them all run for "a while" */ 95 sleep(10); 96 97 rc = 0; 98 for (i = 0; i < NR_CHILDREN; i++) { 99 /* Tell them to stop */ 100 kill(pids[i], SIGINT); 101 /* And wait */ 102 rc |= wait_for_child(pids[i]); 103 } 104 105 return rc; 106 } 107 108 int main(void) 109 { 110 return test_harness(multi_ebb_procs, "multi_ebb_procs"); 111 } 112