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