~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/tests/event_groups.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <string.h>
  3 #include <unistd.h>
  4 #include <stdio.h>
  5 #include "linux/perf_event.h"
  6 #include "tests.h"
  7 #include "debug.h"
  8 #include "pmu.h"
  9 #include "pmus.h"
 10 #include "header.h"
 11 #include "../perf-sys.h"
 12 
 13 /* hw: cycles, sw: context-switch, uncore: [arch dependent] */
 14 static int types[] = {0, 1, -1};
 15 static unsigned long configs[] = {0, 3, 0};
 16 
 17 #define NR_UNCORE_PMUS 5
 18 
 19 /* Uncore pmus that support more than 3 counters */
 20 static struct uncore_pmus {
 21         const char *name;
 22         __u64 config;
 23 } uncore_pmus[NR_UNCORE_PMUS] = {
 24         { "amd_l3", 0x0 },
 25         { "amd_df", 0x0 },
 26         { "uncore_imc_0", 0x1 },         /* Intel */
 27         { "core_imc", 0x318 },           /* PowerPC: core_imc/CPM_STCX_FIN/ */
 28         { "hv_24x7", 0x22000000003 },    /* PowerPC: hv_24x7/CPM_STCX_FIN/ */
 29 };
 30 
 31 static int event_open(int type, unsigned long config, int group_fd)
 32 {
 33         struct perf_event_attr attr;
 34 
 35         memset(&attr, 0, sizeof(struct perf_event_attr));
 36         attr.type = type;
 37         attr.size = sizeof(struct perf_event_attr);
 38         attr.config = config;
 39         /*
 40          * When creating an event group, typically the group leader is
 41          * initialized with disabled set to 1 and any child events are
 42          * initialized with disabled set to 0. Despite disabled being 0,
 43          * the child events will not start until the group leader is
 44          * enabled.
 45          */
 46         attr.disabled = group_fd == -1 ? 1 : 0;
 47 
 48         return sys_perf_event_open(&attr, -1, 0, group_fd, 0);
 49 }
 50 
 51 static int setup_uncore_event(void)
 52 {
 53         struct perf_pmu *pmu = NULL;
 54         int i, fd;
 55 
 56         while ((pmu = perf_pmus__scan(pmu)) != NULL) {
 57                 for (i = 0; i < NR_UNCORE_PMUS; i++) {
 58                         if (!strcmp(uncore_pmus[i].name, pmu->name)) {
 59                                 pr_debug("Using %s for uncore pmu event\n", pmu->name);
 60                                 types[2] = pmu->type;
 61                                 configs[2] = uncore_pmus[i].config;
 62                                 /*
 63                                  * Check if the chosen uncore pmu event can be
 64                                  * used in the test. For example, incase of accessing
 65                                  * hv_24x7 pmu counters, partition should have
 66                                  * additional permissions. If not, event open will
 67                                  * fail. So check if the event open succeeds
 68                                  * before proceeding.
 69                                  */
 70                                 fd = event_open(types[2], configs[2], -1);
 71                                 if (fd < 0)
 72                                         return -1;
 73                                 close(fd);
 74                                 return 0;
 75                         }
 76                 }
 77         }
 78         return -1;
 79 }
 80 
 81 static int run_test(int i, int j, int k)
 82 {
 83         int erroneous = ((((1 << i) | (1 << j) | (1 << k)) & 5) == 5);
 84         int group_fd, sibling_fd1, sibling_fd2;
 85 
 86         group_fd = event_open(types[i], configs[i], -1);
 87         if (group_fd == -1)
 88                 return -1;
 89 
 90         sibling_fd1 = event_open(types[j], configs[j], group_fd);
 91         if (sibling_fd1 == -1) {
 92                 close(group_fd);
 93                 return erroneous ? 0 : -1;
 94         }
 95 
 96         sibling_fd2 = event_open(types[k], configs[k], group_fd);
 97         if (sibling_fd2 == -1) {
 98                 close(sibling_fd1);
 99                 close(group_fd);
100                 return erroneous ? 0 : -1;
101         }
102 
103         close(sibling_fd2);
104         close(sibling_fd1);
105         close(group_fd);
106         return erroneous ? -1 : 0;
107 }
108 
109 static int test__event_groups(struct test_suite *text __maybe_unused, int subtest __maybe_unused)
110 {
111         int i, j, k;
112         int ret;
113         int r;
114 
115         ret = setup_uncore_event();
116         if (ret || types[2] == -1)
117                 return TEST_SKIP;
118 
119         ret = TEST_OK;
120         for (i = 0; i < 3; i++) {
121                 for (j = 0; j < 3; j++) {
122                         for (k = 0; k < 3; k++) {
123                                 r = run_test(i, j, k);
124                                 if (r)
125                                         ret = TEST_FAIL;
126 
127                                 pr_debug("0x%x 0x%lx, 0x%x 0x%lx, 0x%x 0x%lx: %s\n",
128                                          types[i], configs[i], types[j], configs[j],
129                                          types[k], configs[k], r ? "Fail" : "Pass");
130                         }
131                 }
132         }
133         return ret;
134 }
135 
136 DEFINE_SUITE("Event groups", event_groups);
137 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php