Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2014, Michael Ellerman, IBM Corp.
0004  */
0005 
0006 #define _GNU_SOURCE
0007 
0008 #include <elf.h>
0009 #include <limits.h>
0010 #include <stdio.h>
0011 #include <stdbool.h>
0012 #include <string.h>
0013 #include <sys/prctl.h>
0014 
0015 #include "event.h"
0016 #include "lib.h"
0017 #include "utils.h"
0018 
0019 /*
0020  * Test that per-event excludes work.
0021  */
0022 
0023 static int per_event_excludes(void)
0024 {
0025     struct event *e, events[4];
0026     int i;
0027 
0028     SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
0029 
0030     /*
0031      * We need to create the events disabled, otherwise the running/enabled
0032      * counts don't match up.
0033      */
0034     e = &events[0];
0035     event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
0036             PERF_TYPE_HARDWARE, "instructions");
0037     e->attr.disabled = 1;
0038 
0039     e = &events[1];
0040     event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
0041             PERF_TYPE_HARDWARE, "instructions(k)");
0042     e->attr.disabled = 1;
0043     e->attr.exclude_user = 1;
0044     e->attr.exclude_hv = 1;
0045 
0046     e = &events[2];
0047     event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
0048             PERF_TYPE_HARDWARE, "instructions(h)");
0049     e->attr.disabled = 1;
0050     e->attr.exclude_user = 1;
0051     e->attr.exclude_kernel = 1;
0052 
0053     e = &events[3];
0054     event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
0055             PERF_TYPE_HARDWARE, "instructions(u)");
0056     e->attr.disabled = 1;
0057     e->attr.exclude_hv = 1;
0058     e->attr.exclude_kernel = 1;
0059 
0060     FAIL_IF(event_open(&events[0]));
0061 
0062     /*
0063      * The open here will fail if we don't have per event exclude support,
0064      * because the second event has an incompatible set of exclude settings
0065      * and we're asking for the events to be in a group.
0066      */
0067     for (i = 1; i < 4; i++)
0068         FAIL_IF(event_open_with_group(&events[i], events[0].fd));
0069 
0070     /*
0071      * Even though the above will fail without per-event excludes we keep
0072      * testing in order to be thorough.
0073      */
0074     prctl(PR_TASK_PERF_EVENTS_ENABLE);
0075 
0076     /* Spin for a while */
0077     for (i = 0; i < INT_MAX; i++)
0078         asm volatile("" : : : "memory");
0079 
0080     prctl(PR_TASK_PERF_EVENTS_DISABLE);
0081 
0082     for (i = 0; i < 4; i++) {
0083         FAIL_IF(event_read(&events[i]));
0084         event_report(&events[i]);
0085     }
0086 
0087     /*
0088      * We should see that all events have enabled == running. That
0089      * shows that they were all on the PMU at once.
0090      */
0091     for (i = 0; i < 4; i++)
0092         FAIL_IF(events[i].result.running != events[i].result.enabled);
0093 
0094     /*
0095      * We can also check that the result for instructions is >= all the
0096      * other counts. That's because it is counting all instructions while
0097      * the others are counting a subset.
0098      */
0099     for (i = 1; i < 4; i++)
0100         FAIL_IF(events[0].result.value < events[i].result.value);
0101 
0102     for (i = 0; i < 4; i++)
0103         event_close(&events[i]);
0104 
0105     return 0;
0106 }
0107 
0108 int main(void)
0109 {
0110     return test_harness(per_event_excludes, "per_event_excludes");
0111 }