1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2014, Michael Ellerman, IBM Corp. 4 */ 5 6 #define _GNU_SOURCE 7 8 #include <elf.h> 9 #include <limits.h> 10 #include <stdio.h> 11 #include <stdbool.h> 12 #include <string.h> 13 #include <sys/prctl.h> 14 15 #include <asm/cputable.h> 16 17 #include "event.h" 18 #include "lib.h" 19 #include "utils.h" 20 21 /* 22 * Test that per-event excludes work. 23 */ 24 25 static int per_event_excludes(void) 26 { 27 struct event *e, events[4]; 28 int i; 29 30 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07)); 31 32 /* 33 * We need to create the events disabled, otherwise the running/enabled 34 * counts don't match up. 35 */ 36 e = &events[0]; 37 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, 38 PERF_TYPE_HARDWARE, "instructions"); 39 e->attr.disabled = 1; 40 41 e = &events[1]; 42 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, 43 PERF_TYPE_HARDWARE, "instructions(k)"); 44 e->attr.disabled = 1; 45 e->attr.exclude_user = 1; 46 e->attr.exclude_hv = 1; 47 48 e = &events[2]; 49 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, 50 PERF_TYPE_HARDWARE, "instructions(h)"); 51 e->attr.disabled = 1; 52 e->attr.exclude_user = 1; 53 e->attr.exclude_kernel = 1; 54 55 e = &events[3]; 56 event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, 57 PERF_TYPE_HARDWARE, "instructions(u)"); 58 e->attr.disabled = 1; 59 e->attr.exclude_hv = 1; 60 e->attr.exclude_kernel = 1; 61 62 FAIL_IF(event_open(&events[0])); 63 64 /* 65 * The open here will fail if we don't have per event exclude support, 66 * because the second event has an incompatible set of exclude settings 67 * and we're asking for the events to be in a group. 68 */ 69 for (i = 1; i < 4; i++) 70 FAIL_IF(event_open_with_group(&events[i], events[0].fd)); 71 72 /* 73 * Even though the above will fail without per-event excludes we keep 74 * testing in order to be thorough. 75 */ 76 prctl(PR_TASK_PERF_EVENTS_ENABLE); 77 78 /* Spin for a while */ 79 for (i = 0; i < INT_MAX; i++) 80 asm volatile("" : : : "memory"); 81 82 prctl(PR_TASK_PERF_EVENTS_DISABLE); 83 84 for (i = 0; i < 4; i++) { 85 FAIL_IF(event_read(&events[i])); 86 event_report(&events[i]); 87 } 88 89 /* 90 * We should see that all events have enabled == running. That 91 * shows that they were all on the PMU at once. 92 */ 93 for (i = 0; i < 4; i++) 94 FAIL_IF(events[i].result.running != events[i].result.enabled); 95 96 /* 97 * We can also check that the result for instructions is >= all the 98 * other counts. That's because it is counting all instructions while 99 * the others are counting a subset. 100 */ 101 for (i = 1; i < 4; i++) 102 FAIL_IF(events[0].result.value < events[i].result.value); 103 104 for (i = 0; i < 4; i++) 105 event_close(&events[i]); 106 107 return 0; 108 } 109 110 int main(void) 111 { 112 return test_harness(per_event_excludes, "per_event_excludes"); 113 } 114