0001
0002 #include <string.h>
0003 #include <stdlib.h>
0004 #include <stdio.h>
0005 #include <perf/cpumap.h>
0006 #include "cpumap.h"
0007 #include "tests.h"
0008 #include "session.h"
0009 #include "evlist.h"
0010 #include "debug.h"
0011 #include "pmu.h"
0012 #include <linux/err.h>
0013
0014 #define TEMPL "/tmp/perf-test-XXXXXX"
0015 #define DATA_SIZE 10
0016
0017 static int get_temp(char *path)
0018 {
0019 int fd;
0020
0021 strcpy(path, TEMPL);
0022
0023 fd = mkstemp(path);
0024 if (fd < 0) {
0025 perror("mkstemp failed");
0026 return -1;
0027 }
0028
0029 close(fd);
0030 return 0;
0031 }
0032
0033 static int session_write_header(char *path)
0034 {
0035 struct perf_session *session;
0036 struct perf_data data = {
0037 .path = path,
0038 .mode = PERF_DATA_MODE_WRITE,
0039 };
0040
0041 session = perf_session__new(&data, NULL);
0042 TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
0043
0044 if (!perf_pmu__has_hybrid()) {
0045 session->evlist = evlist__new_default();
0046 TEST_ASSERT_VAL("can't get evlist", session->evlist);
0047 } else {
0048 struct parse_events_error err;
0049
0050 session->evlist = evlist__new();
0051 TEST_ASSERT_VAL("can't get evlist", session->evlist);
0052 parse_events_error__init(&err);
0053 parse_events(session->evlist, "cpu_core/cycles/", &err);
0054 parse_events_error__exit(&err);
0055 }
0056
0057 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
0058 perf_header__set_feat(&session->header, HEADER_NRCPUS);
0059 perf_header__set_feat(&session->header, HEADER_ARCH);
0060
0061 session->header.data_size += DATA_SIZE;
0062
0063 TEST_ASSERT_VAL("failed to write header",
0064 !perf_session__write_header(session, session->evlist, data.file.fd, true));
0065
0066 evlist__delete(session->evlist);
0067 perf_session__delete(session);
0068
0069 return 0;
0070 }
0071
0072 static int check_cpu_topology(char *path, struct perf_cpu_map *map)
0073 {
0074 struct perf_session *session;
0075 struct perf_data data = {
0076 .path = path,
0077 .mode = PERF_DATA_MODE_READ,
0078 };
0079 int i;
0080 struct aggr_cpu_id id;
0081
0082 session = perf_session__new(&data, NULL);
0083 TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
0084 cpu__setup_cpunode_map();
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 if (!session->header.env.cpu
0108 && strncmp(session->header.env.arch, "s390", 4)
0109 && strncmp(session->header.env.arch, "aarch64", 7))
0110 return TEST_SKIP;
0111
0112
0113
0114
0115
0116
0117
0118 if (!strncmp(session->header.env.arch, "ppc64le", 7)) {
0119 if (cpu__get_socket_id(perf_cpu_map__cpu(map, 0)) == -1)
0120 return TEST_SKIP;
0121 }
0122
0123 TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
0124
0125 for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
0126 struct perf_cpu cpu = { .cpu = i };
0127
0128 if (!perf_cpu_map__has(map, cpu))
0129 continue;
0130 pr_debug("CPU %d, core %d, socket %d\n", i,
0131 session->header.env.cpu[i].core_id,
0132 session->header.env.cpu[i].socket_id);
0133 }
0134
0135
0136 for (i = 0; i < perf_cpu_map__nr(map); i++) {
0137 id = aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL);
0138 TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match",
0139 perf_cpu_map__cpu(map, i).cpu == id.cpu.cpu);
0140
0141 TEST_ASSERT_VAL("Cpu map - Core ID doesn't match",
0142 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id == id.core);
0143 TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
0144 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
0145 id.socket);
0146
0147 TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
0148 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
0149 TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1);
0150 TEST_ASSERT_VAL("Cpu map - Thread is set", id.thread == -1);
0151 }
0152
0153
0154 for (i = 0; i < perf_cpu_map__nr(map); i++) {
0155 id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL);
0156 TEST_ASSERT_VAL("Core map - Core ID doesn't match",
0157 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id == id.core);
0158
0159 TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
0160 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
0161 id.socket);
0162
0163 TEST_ASSERT_VAL("Core map - Die ID doesn't match",
0164 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
0165 TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
0166 TEST_ASSERT_VAL("Core map - Thread is set", id.thread == -1);
0167 }
0168
0169
0170 for (i = 0; i < perf_cpu_map__nr(map); i++) {
0171 id = aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL);
0172 TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
0173 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
0174 id.socket);
0175
0176 TEST_ASSERT_VAL("Die map - Die ID doesn't match",
0177 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id == id.die);
0178
0179 TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
0180 TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
0181 TEST_ASSERT_VAL("Die map - CPU is set", id.cpu.cpu == -1);
0182 TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1);
0183 }
0184
0185
0186 for (i = 0; i < perf_cpu_map__nr(map); i++) {
0187 id = aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL);
0188 TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
0189 session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id ==
0190 id.socket);
0191
0192 TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
0193 TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
0194 TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
0195 TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu.cpu == -1);
0196 TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1);
0197 }
0198
0199
0200 for (i = 0; i < perf_cpu_map__nr(map); i++) {
0201 id = aggr_cpu_id__node(perf_cpu_map__cpu(map, i), NULL);
0202 TEST_ASSERT_VAL("Node map - Node ID doesn't match",
0203 cpu__get_node(perf_cpu_map__cpu(map, i)) == id.node);
0204 TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
0205 TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
0206 TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
0207 TEST_ASSERT_VAL("Node map - CPU is set", id.cpu.cpu == -1);
0208 TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1);
0209 }
0210 perf_session__delete(session);
0211
0212 return 0;
0213 }
0214
0215 static int test__session_topology(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
0216 {
0217 char path[PATH_MAX];
0218 struct perf_cpu_map *map;
0219 int ret = TEST_FAIL;
0220
0221 TEST_ASSERT_VAL("can't get templ file", !get_temp(path));
0222
0223 pr_debug("templ file: %s\n", path);
0224
0225 if (session_write_header(path))
0226 goto free_path;
0227
0228 map = perf_cpu_map__new(NULL);
0229 if (map == NULL) {
0230 pr_debug("failed to get system cpumap\n");
0231 goto free_path;
0232 }
0233
0234 ret = check_cpu_topology(path, map);
0235 perf_cpu_map__put(map);
0236
0237 free_path:
0238 unlink(path);
0239 return ret;
0240 }
0241
0242 DEFINE_SUITE("Session topology", session_topology);