blob: 869986139146060216ef3e56099641d5ec1eebab [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Kan Liangc84974e2015-09-04 04:58:31 -04002#include <string.h>
3#include <stdlib.h>
4#include <stdio.h>
Jiri Olsa9c3516d2019-07-21 13:24:30 +02005#include <perf/cpumap.h>
Arnaldo Carvalho de Melo87ffb6c2019-09-10 16:29:02 +01006#include "cpumap.h"
Kan Liangc84974e2015-09-04 04:58:31 -04007#include "tests.h"
Kan Liangc84974e2015-09-04 04:58:31 -04008#include "session.h"
9#include "evlist.h"
10#include "debug.h"
Jin Yaoc1020382021-04-27 15:01:36 +080011#include "pmu.h"
Mamatha Inamdar6ef81c52019-08-22 12:50:49 +053012#include <linux/err.h>
Kan Liangc84974e2015-09-04 04:58:31 -040013
14#define TEMPL "/tmp/perf-test-XXXXXX"
15#define DATA_SIZE 10
16
17static 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
33static int session_write_header(char *path)
34{
35 struct perf_session *session;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +010036 struct perf_data data = {
Tommi Rantaladbd660e2020-04-23 14:53:40 +030037 .path = path,
38 .mode = PERF_DATA_MODE_WRITE,
Kan Liangc84974e2015-09-04 04:58:31 -040039 };
40
Namhyung Kim2681bd82021-07-19 15:31:49 -070041 session = perf_session__new(&data, NULL);
Mamatha Inamdar6ef81c52019-08-22 12:50:49 +053042 TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
Kan Liangc84974e2015-09-04 04:58:31 -040043
Jin Yaoc1020382021-04-27 15:01:36 +080044 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);
Ian Rogers07eafd42021-11-07 01:00:01 -080052 parse_events_error__init(&err);
Jin Yaoc1020382021-04-27 15:01:36 +080053 parse_events(session->evlist, "cpu_core/cycles/", &err);
Ian Rogers07eafd42021-11-07 01:00:01 -080054 parse_events_error__exit(&err);
Jin Yaoc1020382021-04-27 15:01:36 +080055 }
Kan Liangc84974e2015-09-04 04:58:31 -040056
57 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
58 perf_header__set_feat(&session->header, HEADER_NRCPUS);
Thomas Richterb930e622018-06-11 09:31:53 +020059 perf_header__set_feat(&session->header, HEADER_ARCH);
Kan Liangc84974e2015-09-04 04:58:31 -040060
61 session->header.data_size += DATA_SIZE;
62
63 TEST_ASSERT_VAL("failed to write header",
Jiri Olsaeae8ad82017-01-23 22:25:41 +010064 !perf_session__write_header(session, session->evlist, data.file.fd, true));
Kan Liangc84974e2015-09-04 04:58:31 -040065
Riccardo Mancini233f2dc2021-07-15 18:07:08 +020066 evlist__delete(session->evlist);
Kan Liangc84974e2015-09-04 04:58:31 -040067 perf_session__delete(session);
68
69 return 0;
70}
71
Jiri Olsaf8548392019-07-21 13:23:49 +020072static int check_cpu_topology(char *path, struct perf_cpu_map *map)
Kan Liangc84974e2015-09-04 04:58:31 -040073{
74 struct perf_session *session;
Jiri Olsa8ceb41d2017-01-23 22:07:59 +010075 struct perf_data data = {
Tommi Rantaladbd660e2020-04-23 14:53:40 +030076 .path = path,
77 .mode = PERF_DATA_MODE_READ,
Kan Liangc84974e2015-09-04 04:58:31 -040078 };
James Clark2760f5a12020-11-26 16:13:20 +020079 int i;
80 struct aggr_cpu_id id;
Kan Liangc84974e2015-09-04 04:58:31 -040081
Namhyung Kim2681bd82021-07-19 15:31:49 -070082 session = perf_session__new(&data, NULL);
Mamatha Inamdar6ef81c52019-08-22 12:50:49 +053083 TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
James Clark23331ee2020-11-26 16:13:17 +020084 cpu__setup_cpunode_map();
Kan Liangc84974e2015-09-04 04:58:31 -040085
Thomas Richterd1211092018-05-28 09:36:57 +020086 /* 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
Ingo Molnar4d39c892021-03-23 17:09:15 +010095 * dependent and might have higher numbers than the CPU id.
Thomas Richterd1211092018-05-28 09:36:57 +020096 * 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 *
James Clark23331ee2020-11-26 16:13:17 +0200102 * 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.
Thomas Richterd1211092018-05-28 09:36:57 +0200106 */
James Clark23331ee2020-11-26 16:13:17 +0200107 if (!session->header.env.cpu
108 && strncmp(session->header.env.arch, "s390", 4)
109 && strncmp(session->header.env.arch, "aarch64", 7))
Thomas Richterd1211092018-05-28 09:36:57 +0200110 return TEST_SKIP;
111
James Clark23331ee2020-11-26 16:13:17 +0200112 TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
113
Jan Stancekda8a58b2017-02-17 12:10:26 +0100114 for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
115 if (!cpu_map__has(map, i))
116 continue;
Kan Liangc84974e2015-09-04 04:58:31 -0400117 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
James Clark23331ee2020-11-26 16:13:17 +0200122 // Test that core ID contains socket, die and core
Kan Liangc84974e2015-09-04 04:58:31 -0400123 for (i = 0; i < map->nr; i++) {
James Clark23331ee2020-11-26 16:13:17 +0200124 id = cpu_map__get_core(map, i, NULL);
125 TEST_ASSERT_VAL("Core map - Core ID doesn't match",
James Clarkb9933812020-11-26 16:13:27 +0200126 session->header.env.cpu[map->map[i]].core_id == id.core);
Kan Liangc84974e2015-09-04 04:58:31 -0400127
James Clark23331ee2020-11-26 16:13:17 +0200128 TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
James Clark1a270cb2020-11-26 16:13:25 +0200129 session->header.env.cpu[map->map[i]].socket_id == id.socket);
James Clark23331ee2020-11-26 16:13:17 +0200130
131 TEST_ASSERT_VAL("Core map - Die ID doesn't match",
James Clarkba2ee162020-11-26 16:13:26 +0200132 session->header.env.cpu[map->map[i]].die_id == id.die);
James Clarkfcd83a32020-11-26 16:13:24 +0200133 TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
James Clark8d4852b2020-11-26 16:13:28 +0200134 TEST_ASSERT_VAL("Core map - Thread is set", id.thread == -1);
Kan Liangc84974e2015-09-04 04:58:31 -0400135 }
136
James Clark23331ee2020-11-26 16:13:17 +0200137 // 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",
James Clark1a270cb2020-11-26 16:13:25 +0200141 session->header.env.cpu[map->map[i]].socket_id == id.socket);
James Clark23331ee2020-11-26 16:13:17 +0200142
143 TEST_ASSERT_VAL("Die map - Die ID doesn't match",
James Clarkba2ee162020-11-26 16:13:26 +0200144 session->header.env.cpu[map->map[i]].die_id == id.die);
James Clarkfcd83a32020-11-26 16:13:24 +0200145
146 TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
James Clarkb9933812020-11-26 16:13:27 +0200147 TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
James Clark8d4852b2020-11-26 16:13:28 +0200148 TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1);
James Clark23331ee2020-11-26 16:13:17 +0200149 }
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",
James Clark1a270cb2020-11-26 16:13:25 +0200155 session->header.env.cpu[map->map[i]].socket_id == id.socket);
James Clarkfcd83a32020-11-26 16:13:24 +0200156
157 TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
James Clarkba2ee162020-11-26 16:13:26 +0200158 TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
James Clarkb9933812020-11-26 16:13:27 +0200159 TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
James Clark8d4852b2020-11-26 16:13:28 +0200160 TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1);
James Clark23331ee2020-11-26 16:13:17 +0200161 }
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",
James Clarkfcd83a32020-11-26 16:13:24 +0200167 cpu__get_node(map->map[i]) == id.node);
James Clark1a270cb2020-11-26 16:13:25 +0200168 TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
James Clarkba2ee162020-11-26 16:13:26 +0200169 TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
James Clarkb9933812020-11-26 16:13:27 +0200170 TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
James Clark8d4852b2020-11-26 16:13:28 +0200171 TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1);
James Clark23331ee2020-11-26 16:13:17 +0200172 }
Kan Liangc84974e2015-09-04 04:58:31 -0400173 perf_session__delete(session);
174
175 return 0;
176}
177
Ian Rogers33f44bf2021-11-03 23:41:51 -0700178static int test__session_topology(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
Kan Liangc84974e2015-09-04 04:58:31 -0400179{
180 char path[PATH_MAX];
Jiri Olsaf8548392019-07-21 13:23:49 +0200181 struct perf_cpu_map *map;
Thomas Richterd1211092018-05-28 09:36:57 +0200182 int ret = TEST_FAIL;
Kan Liangc84974e2015-09-04 04:58:31 -0400183
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
Jiri Olsa9c3516d2019-07-21 13:24:30 +0200191 map = perf_cpu_map__new(NULL);
Kan Liangc84974e2015-09-04 04:58:31 -0400192 if (map == NULL) {
193 pr_debug("failed to get system cpumap\n");
194 goto free_path;
195 }
196
Thomas Richterd1211092018-05-28 09:36:57 +0200197 ret = check_cpu_topology(path, map);
Jiri Olsa38f01d82019-07-21 13:24:17 +0200198 perf_cpu_map__put(map);
Thomas Richterd1211092018-05-28 09:36:57 +0200199
Kan Liangc84974e2015-09-04 04:58:31 -0400200free_path:
201 unlink(path);
202 return ret;
203}
Ian Rogersd68f0362021-11-03 23:41:50 -0700204
205DEFINE_SUITE("Session topology", session_topology);