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        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
 108int main(void)
 109{
 110        return test_harness(per_event_excludes, "per_event_excludes");
 111}
 112