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

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

Version: ~ [ linux-6.1-rc5 ] ~ [ linux-6.0.8 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.78 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.154 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.224 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.265 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.299 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.333 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ 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 <stdlib.h>
  4 #include <stdio.h>
  5 #include <perf/cpumap.h>
  6 #include "cpumap.h"
  7 #include "tests.h"
  8 #include "session.h"
  9 #include "evlist.h"
 10 #include "debug.h"
 11 #include "pmu.h"
 12 #include <linux/err.h>
 13 
 14 #define TEMPL "/tmp/perf-test-XXXXXX"
 15 #define DATA_SIZE       10
 16 
 17 static int get_temp(char *path)
 18 {
 19         int fd;
 20 
 21         strcpy(path, TEMPL);
 22 
 23         fd = mkstemp(path);
 24         if (fd < 0) {
 25                 perror("mkstemp failed");
 26                 return -1;
 27         }
 28 
 29         close(fd);
 30         return 0;
 31 }
 32 
 33 static int session_write_header(char *path)
 34 {
 35         struct perf_session *session;
 36         struct perf_data data = {
 37                 .path = path,
 38                 .mode = PERF_DATA_MODE_WRITE,
 39         };
 40 
 41         session = perf_session__new(&data, NULL);
 42         TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
 43 
 44         if (!perf_pmu__has_hybrid()) {
 45                 session->evlist = evlist__new_default();
 46                 TEST_ASSERT_VAL("can't get evlist", session->evlist);
 47         } else {
 48                 struct parse_events_error err;
 49 
 50                 session->evlist = evlist__new();
 51                 TEST_ASSERT_VAL("can't get evlist", session->evlist);
 52                 parse_events_error__init(&err);
 53                 parse_events(session->evlist, "cpu_core/cycles/", &err);
 54                 parse_events_error__exit(&err);
 55         }
 56 
 57         perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
 58         perf_header__set_feat(&session->header, HEADER_NRCPUS);
 59         perf_header__set_feat(&session->header, HEADER_ARCH);
 60 
 61         session->header.data_size += DATA_SIZE;
 62 
 63         TEST_ASSERT_VAL("failed to write header",
 64                         !perf_session__write_header(session, session->evlist, data.file.fd, true));
 65 
 66         evlist__delete(session->evlist);
 67         perf_session__delete(session);
 68 
 69         return 0;
 70 }
 71 
 72 static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 73 {
 74         struct perf_session *session;
 75         struct perf_data data = {
 76                 .path = path,
 77                 .mode = PERF_DATA_MODE_READ,
 78         };
 79         int i;
 80         struct aggr_cpu_id id;
 81 
 82         session = perf_session__new(&data, NULL);
 83         TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
 84         cpu__setup_cpunode_map();
 85 
 86         /* On platforms with large numbers of CPUs process_cpu_topology()
 87          * might issue an error while reading the perf.data file section
 88          * HEADER_CPU_TOPOLOGY and the cpu_topology_map pointed to by member
 89          * cpu is a NULL pointer.
 90          * Example: On s390
 91          *   CPU 0 is on core_id 0 and physical_package_id 6
 92          *   CPU 1 is on core_id 1 and physical_package_id 3
 93          *
 94          *   Core_id and physical_package_id are platform and architecture
 95          *   dependent and might have higher numbers than the CPU id.
 96          *   This actually depends on the configuration.
 97          *
 98          *  In this case process_cpu_topology() prints error message:
 99          *  "socket_id number is too big. You may need to upgrade the
100          *  perf tool."
101          *
102          *  This is the reason why this test might be skipped. aarch64 and
103          *  s390 always write this part of the header, even when the above
104          *  condition is true (see do_core_id_test in header.c). So always
105          *  run this test on those platforms.
106          */
107         if (!session->header.env.cpu
108                         && strncmp(session->header.env.arch, "s390", 4)
109                         && strncmp(session->header.env.arch, "aarch64", 7))
110                 return TEST_SKIP;
111 
112         TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
113 
114         for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
115                 if (!cpu_map__has(map, i))
116                         continue;
117                 pr_debug("CPU %d, core %d, socket %d\n", i,
118                          session->header.env.cpu[i].core_id,
119                          session->header.env.cpu[i].socket_id);
120         }
121 
122         // Test that core ID contains socket, die and core
123         for (i = 0; i < map->nr; i++) {
124                 id = cpu_map__get_core(map, i, NULL);
125                 TEST_ASSERT_VAL("Core map - Core ID doesn't match",
126                         session->header.env.cpu[map->map[i]].core_id == id.core);
127 
128                 TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
129                         session->header.env.cpu[map->map[i]].socket_id == id.socket);
130 
131                 TEST_ASSERT_VAL("Core map - Die ID doesn't match",
132                         session->header.env.cpu[map->map[i]].die_id == id.die);
133                 TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
134                 TEST_ASSERT_VAL("Core map - Thread is set", id.thread == -1);
135         }
136 
137         // Test that die ID contains socket and die
138         for (i = 0; i < map->nr; i++) {
139                 id = cpu_map__get_die(map, i, NULL);
140                 TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
141                         session->header.env.cpu[map->map[i]].socket_id == id.socket);
142 
143                 TEST_ASSERT_VAL("Die map - Die ID doesn't match",
144                         session->header.env.cpu[map->map[i]].die_id == id.die);
145 
146                 TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
147                 TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
148                 TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1);
149         }
150 
151         // Test that socket ID contains only socket
152         for (i = 0; i < map->nr; i++) {
153                 id = cpu_map__get_socket(map, i, NULL);
154                 TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
155                         session->header.env.cpu[map->map[i]].socket_id == id.socket);
156 
157                 TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
158                 TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
159                 TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
160                 TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1);
161         }
162 
163         // Test that node ID contains only node
164         for (i = 0; i < map->nr; i++) {
165                 id = cpu_map__get_node(map, i, NULL);
166                 TEST_ASSERT_VAL("Node map - Node ID doesn't match",
167                         cpu__get_node(map->map[i]) == id.node);
168                 TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
169                 TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
170                 TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
171                 TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1);
172         }
173         perf_session__delete(session);
174 
175         return 0;
176 }
177 
178 static int test__session_topology(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
179 {
180         char path[PATH_MAX];
181         struct perf_cpu_map *map;
182         int ret = TEST_FAIL;
183 
184         TEST_ASSERT_VAL("can't get templ file", !get_temp(path));
185 
186         pr_debug("templ file: %s\n", path);
187 
188         if (session_write_header(path))
189                 goto free_path;
190 
191         map = perf_cpu_map__new(NULL);
192         if (map == NULL) {
193                 pr_debug("failed to get system cpumap\n");
194                 goto free_path;
195         }
196 
197         ret = check_cpu_topology(path, map);
198         perf_cpu_map__put(map);
199 
200 free_path:
201         unlink(path);
202         return ret;
203 }
204 
205 DEFINE_SUITE("Session topology", session_topology);
206 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp