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