Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / tools / testing / selftests / powerpc / pmu / per_event_excludes.c
1 /*
2  * Copyright 2014, Michael Ellerman, IBM Corp.
3  * Licensed under GPLv2.
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         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
111 int main(void)
112 {
113         return test_harness(per_event_excludes, "per_event_excludes");
114 }