112 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2014, Michael Ellerman, IBM Corp.4 */5 6#define _GNU_SOURCE7 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 23static 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/enabled32 * 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 settings65 * 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 keep72 * 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. That89 * 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 the96 * other counts. That's because it is counting all instructions while97 * 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 108int main(void)109{110 return test_harness(per_event_excludes, "per_event_excludes");111}112