Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf into perf/core

Pull perf/core improvements and fixes from Jiri Olsa:

* Wire up perf_regs and unwind support for ARM64 (Jean Pihet)

* Move u64_swap union to its single user's header, evsel.h (Borislav Petkov)

* Fix for s390 to properly parse tracepoints plus test code (Alexander Yarygin)

* Handle EINTR error for readn/writen (Namhyung Kim)

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

+380 -51
+7
tools/perf/arch/arm64/Makefile
··· 1 + ifndef NO_DWARF 2 + PERF_HAVE_DWARF_REGS := 1 3 + LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o 4 + endif 5 + ifndef NO_LIBUNWIND 6 + LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o 7 + endif
+88
tools/perf/arch/arm64/include/perf_regs.h
··· 1 + #ifndef ARCH_PERF_REGS_H 2 + #define ARCH_PERF_REGS_H 3 + 4 + #include <stdlib.h> 5 + #include "../../util/types.h" 6 + #include <asm/perf_regs.h> 7 + 8 + #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1) 9 + #define PERF_REG_IP PERF_REG_ARM64_PC 10 + #define PERF_REG_SP PERF_REG_ARM64_SP 11 + 12 + static inline const char *perf_reg_name(int id) 13 + { 14 + switch (id) { 15 + case PERF_REG_ARM64_X0: 16 + return "x0"; 17 + case PERF_REG_ARM64_X1: 18 + return "x1"; 19 + case PERF_REG_ARM64_X2: 20 + return "x2"; 21 + case PERF_REG_ARM64_X3: 22 + return "x3"; 23 + case PERF_REG_ARM64_X4: 24 + return "x4"; 25 + case PERF_REG_ARM64_X5: 26 + return "x5"; 27 + case PERF_REG_ARM64_X6: 28 + return "x6"; 29 + case PERF_REG_ARM64_X7: 30 + return "x7"; 31 + case PERF_REG_ARM64_X8: 32 + return "x8"; 33 + case PERF_REG_ARM64_X9: 34 + return "x9"; 35 + case PERF_REG_ARM64_X10: 36 + return "x10"; 37 + case PERF_REG_ARM64_X11: 38 + return "x11"; 39 + case PERF_REG_ARM64_X12: 40 + return "x12"; 41 + case PERF_REG_ARM64_X13: 42 + return "x13"; 43 + case PERF_REG_ARM64_X14: 44 + return "x14"; 45 + case PERF_REG_ARM64_X15: 46 + return "x15"; 47 + case PERF_REG_ARM64_X16: 48 + return "x16"; 49 + case PERF_REG_ARM64_X17: 50 + return "x17"; 51 + case PERF_REG_ARM64_X18: 52 + return "x18"; 53 + case PERF_REG_ARM64_X19: 54 + return "x19"; 55 + case PERF_REG_ARM64_X20: 56 + return "x20"; 57 + case PERF_REG_ARM64_X21: 58 + return "x21"; 59 + case PERF_REG_ARM64_X22: 60 + return "x22"; 61 + case PERF_REG_ARM64_X23: 62 + return "x23"; 63 + case PERF_REG_ARM64_X24: 64 + return "x24"; 65 + case PERF_REG_ARM64_X25: 66 + return "x25"; 67 + case PERF_REG_ARM64_X26: 68 + return "x26"; 69 + case PERF_REG_ARM64_X27: 70 + return "x27"; 71 + case PERF_REG_ARM64_X28: 72 + return "x28"; 73 + case PERF_REG_ARM64_X29: 74 + return "x29"; 75 + case PERF_REG_ARM64_SP: 76 + return "sp"; 77 + case PERF_REG_ARM64_LR: 78 + return "lr"; 79 + case PERF_REG_ARM64_PC: 80 + return "pc"; 81 + default: 82 + return NULL; 83 + } 84 + 85 + return NULL; 86 + } 87 + 88 + #endif /* ARCH_PERF_REGS_H */
+80
tools/perf/arch/arm64/util/dwarf-regs.c
··· 1 + /* 2 + * Mapping of DWARF debug register numbers into register names. 3 + * 4 + * Copyright (C) 2010 Will Deacon, ARM Ltd. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <stddef.h> 12 + #include <dwarf-regs.h> 13 + 14 + struct pt_regs_dwarfnum { 15 + const char *name; 16 + unsigned int dwarfnum; 17 + }; 18 + 19 + #define STR(s) #s 20 + #define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num} 21 + #define GPR_DWARFNUM_NAME(num) \ 22 + {.name = STR(%x##num), .dwarfnum = num} 23 + #define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0} 24 + 25 + /* 26 + * Reference: 27 + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf 28 + */ 29 + static const struct pt_regs_dwarfnum regdwarfnum_table[] = { 30 + GPR_DWARFNUM_NAME(0), 31 + GPR_DWARFNUM_NAME(1), 32 + GPR_DWARFNUM_NAME(2), 33 + GPR_DWARFNUM_NAME(3), 34 + GPR_DWARFNUM_NAME(4), 35 + GPR_DWARFNUM_NAME(5), 36 + GPR_DWARFNUM_NAME(6), 37 + GPR_DWARFNUM_NAME(7), 38 + GPR_DWARFNUM_NAME(8), 39 + GPR_DWARFNUM_NAME(9), 40 + GPR_DWARFNUM_NAME(10), 41 + GPR_DWARFNUM_NAME(11), 42 + GPR_DWARFNUM_NAME(12), 43 + GPR_DWARFNUM_NAME(13), 44 + GPR_DWARFNUM_NAME(14), 45 + GPR_DWARFNUM_NAME(15), 46 + GPR_DWARFNUM_NAME(16), 47 + GPR_DWARFNUM_NAME(17), 48 + GPR_DWARFNUM_NAME(18), 49 + GPR_DWARFNUM_NAME(19), 50 + GPR_DWARFNUM_NAME(20), 51 + GPR_DWARFNUM_NAME(21), 52 + GPR_DWARFNUM_NAME(22), 53 + GPR_DWARFNUM_NAME(23), 54 + GPR_DWARFNUM_NAME(24), 55 + GPR_DWARFNUM_NAME(25), 56 + GPR_DWARFNUM_NAME(26), 57 + GPR_DWARFNUM_NAME(27), 58 + GPR_DWARFNUM_NAME(28), 59 + GPR_DWARFNUM_NAME(29), 60 + REG_DWARFNUM_NAME("%lr", 30), 61 + REG_DWARFNUM_NAME("%sp", 31), 62 + REG_DWARFNUM_END, 63 + }; 64 + 65 + /** 66 + * get_arch_regstr() - lookup register name from it's DWARF register number 67 + * @n: the DWARF register number 68 + * 69 + * get_arch_regstr() returns the name of the register in struct 70 + * regdwarfnum_table from it's DWARF register number. If the register is not 71 + * found in the table, this returns NULL; 72 + */ 73 + const char *get_arch_regstr(unsigned int n) 74 + { 75 + const struct pt_regs_dwarfnum *roff; 76 + for (roff = regdwarfnum_table; roff->name != NULL; roff++) 77 + if (roff->dwarfnum == n) 78 + return roff->name; 79 + return NULL; 80 + }
+82
tools/perf/arch/arm64/util/unwind-libunwind.c
··· 1 + 2 + #include <errno.h> 3 + #include <libunwind.h> 4 + #include "perf_regs.h" 5 + #include "../../util/unwind.h" 6 + 7 + int libunwind__arch_reg_id(int regnum) 8 + { 9 + switch (regnum) { 10 + case UNW_AARCH64_X0: 11 + return PERF_REG_ARM64_X0; 12 + case UNW_AARCH64_X1: 13 + return PERF_REG_ARM64_X1; 14 + case UNW_AARCH64_X2: 15 + return PERF_REG_ARM64_X2; 16 + case UNW_AARCH64_X3: 17 + return PERF_REG_ARM64_X3; 18 + case UNW_AARCH64_X4: 19 + return PERF_REG_ARM64_X4; 20 + case UNW_AARCH64_X5: 21 + return PERF_REG_ARM64_X5; 22 + case UNW_AARCH64_X6: 23 + return PERF_REG_ARM64_X6; 24 + case UNW_AARCH64_X7: 25 + return PERF_REG_ARM64_X7; 26 + case UNW_AARCH64_X8: 27 + return PERF_REG_ARM64_X8; 28 + case UNW_AARCH64_X9: 29 + return PERF_REG_ARM64_X9; 30 + case UNW_AARCH64_X10: 31 + return PERF_REG_ARM64_X10; 32 + case UNW_AARCH64_X11: 33 + return PERF_REG_ARM64_X11; 34 + case UNW_AARCH64_X12: 35 + return PERF_REG_ARM64_X12; 36 + case UNW_AARCH64_X13: 37 + return PERF_REG_ARM64_X13; 38 + case UNW_AARCH64_X14: 39 + return PERF_REG_ARM64_X14; 40 + case UNW_AARCH64_X15: 41 + return PERF_REG_ARM64_X15; 42 + case UNW_AARCH64_X16: 43 + return PERF_REG_ARM64_X16; 44 + case UNW_AARCH64_X17: 45 + return PERF_REG_ARM64_X17; 46 + case UNW_AARCH64_X18: 47 + return PERF_REG_ARM64_X18; 48 + case UNW_AARCH64_X19: 49 + return PERF_REG_ARM64_X19; 50 + case UNW_AARCH64_X20: 51 + return PERF_REG_ARM64_X20; 52 + case UNW_AARCH64_X21: 53 + return PERF_REG_ARM64_X21; 54 + case UNW_AARCH64_X22: 55 + return PERF_REG_ARM64_X22; 56 + case UNW_AARCH64_X23: 57 + return PERF_REG_ARM64_X23; 58 + case UNW_AARCH64_X24: 59 + return PERF_REG_ARM64_X24; 60 + case UNW_AARCH64_X25: 61 + return PERF_REG_ARM64_X25; 62 + case UNW_AARCH64_X26: 63 + return PERF_REG_ARM64_X26; 64 + case UNW_AARCH64_X27: 65 + return PERF_REG_ARM64_X27; 66 + case UNW_AARCH64_X28: 67 + return PERF_REG_ARM64_X28; 68 + case UNW_AARCH64_X29: 69 + return PERF_REG_ARM64_X29; 70 + case UNW_AARCH64_X30: 71 + return PERF_REG_ARM64_LR; 72 + case UNW_AARCH64_SP: 73 + return PERF_REG_ARM64_SP; 74 + case UNW_AARCH64_PC: 75 + return PERF_REG_ARM64_PC; 76 + default: 77 + pr_err("unwind: invalid reg id %d\n", regnum); 78 + return -EINVAL; 79 + } 80 + 81 + return -EINVAL; 82 + }
+7 -1
tools/perf/config/Makefile
··· 29 29 endif 30 30 NO_PERF_REGS := 0 31 31 endif 32 + 32 33 ifeq ($(ARCH),arm) 33 34 NO_PERF_REGS := 0 34 35 LIBUNWIND_LIBS = -lunwind -lunwind-arm 36 + endif 37 + 38 + ifeq ($(ARCH),arm64) 39 + NO_PERF_REGS := 0 40 + LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 35 41 endif 36 42 37 43 # So far there's only x86 libdw unwind support merged in perf. ··· 376 370 endif 377 371 378 372 ifndef NO_LIBUNWIND 379 - ifeq ($(ARCH),arm) 373 + ifeq ($(ARCH),$(filter $(ARCH),arm arm64)) 380 374 $(call feature_check,libunwind-debug-frame) 381 375 ifneq ($(feature-libunwind-debug-frame), 1) 382 376 msg := $(warning No debug_frame support found in libunwind);
+97 -45
tools/perf/tests/parse-events.c
··· 1174 1174 struct evlist_test { 1175 1175 const char *name; 1176 1176 __u32 type; 1177 + const int id; 1177 1178 int (*check)(struct perf_evlist *evlist); 1178 1179 }; 1179 1180 1180 1181 static struct evlist_test test__events[] = { 1181 - [0] = { 1182 + { 1182 1183 .name = "syscalls:sys_enter_open", 1183 1184 .check = test__checkevent_tracepoint, 1185 + .id = 0, 1184 1186 }, 1185 - [1] = { 1187 + { 1186 1188 .name = "syscalls:*", 1187 1189 .check = test__checkevent_tracepoint_multi, 1190 + .id = 1, 1188 1191 }, 1189 - [2] = { 1192 + { 1190 1193 .name = "r1a", 1191 1194 .check = test__checkevent_raw, 1195 + .id = 2, 1192 1196 }, 1193 - [3] = { 1197 + { 1194 1198 .name = "1:1", 1195 1199 .check = test__checkevent_numeric, 1200 + .id = 3, 1196 1201 }, 1197 - [4] = { 1202 + { 1198 1203 .name = "instructions", 1199 1204 .check = test__checkevent_symbolic_name, 1205 + .id = 4, 1200 1206 }, 1201 - [5] = { 1207 + { 1202 1208 .name = "cycles/period=100000,config2/", 1203 1209 .check = test__checkevent_symbolic_name_config, 1210 + .id = 5, 1204 1211 }, 1205 - [6] = { 1212 + { 1206 1213 .name = "faults", 1207 1214 .check = test__checkevent_symbolic_alias, 1215 + .id = 6, 1208 1216 }, 1209 - [7] = { 1217 + { 1210 1218 .name = "L1-dcache-load-miss", 1211 1219 .check = test__checkevent_genhw, 1220 + .id = 7, 1212 1221 }, 1213 - [8] = { 1222 + { 1214 1223 .name = "mem:0", 1215 1224 .check = test__checkevent_breakpoint, 1225 + .id = 8, 1216 1226 }, 1217 - [9] = { 1227 + { 1218 1228 .name = "mem:0:x", 1219 1229 .check = test__checkevent_breakpoint_x, 1230 + .id = 9, 1220 1231 }, 1221 - [10] = { 1232 + { 1222 1233 .name = "mem:0:r", 1223 1234 .check = test__checkevent_breakpoint_r, 1235 + .id = 10, 1224 1236 }, 1225 - [11] = { 1237 + { 1226 1238 .name = "mem:0:w", 1227 1239 .check = test__checkevent_breakpoint_w, 1240 + .id = 11, 1228 1241 }, 1229 - [12] = { 1242 + { 1230 1243 .name = "syscalls:sys_enter_open:k", 1231 1244 .check = test__checkevent_tracepoint_modifier, 1245 + .id = 12, 1232 1246 }, 1233 - [13] = { 1247 + { 1234 1248 .name = "syscalls:*:u", 1235 1249 .check = test__checkevent_tracepoint_multi_modifier, 1250 + .id = 13, 1236 1251 }, 1237 - [14] = { 1252 + { 1238 1253 .name = "r1a:kp", 1239 1254 .check = test__checkevent_raw_modifier, 1255 + .id = 14, 1240 1256 }, 1241 - [15] = { 1257 + { 1242 1258 .name = "1:1:hp", 1243 1259 .check = test__checkevent_numeric_modifier, 1260 + .id = 15, 1244 1261 }, 1245 - [16] = { 1262 + { 1246 1263 .name = "instructions:h", 1247 1264 .check = test__checkevent_symbolic_name_modifier, 1265 + .id = 16, 1248 1266 }, 1249 - [17] = { 1267 + { 1250 1268 .name = "faults:u", 1251 1269 .check = test__checkevent_symbolic_alias_modifier, 1270 + .id = 17, 1252 1271 }, 1253 - [18] = { 1272 + { 1254 1273 .name = "L1-dcache-load-miss:kp", 1255 1274 .check = test__checkevent_genhw_modifier, 1275 + .id = 18, 1256 1276 }, 1257 - [19] = { 1277 + { 1258 1278 .name = "mem:0:u", 1259 1279 .check = test__checkevent_breakpoint_modifier, 1280 + .id = 19, 1260 1281 }, 1261 - [20] = { 1282 + { 1262 1283 .name = "mem:0:x:k", 1263 1284 .check = test__checkevent_breakpoint_x_modifier, 1285 + .id = 20, 1264 1286 }, 1265 - [21] = { 1287 + { 1266 1288 .name = "mem:0:r:hp", 1267 1289 .check = test__checkevent_breakpoint_r_modifier, 1290 + .id = 21, 1268 1291 }, 1269 - [22] = { 1292 + { 1270 1293 .name = "mem:0:w:up", 1271 1294 .check = test__checkevent_breakpoint_w_modifier, 1295 + .id = 22, 1272 1296 }, 1273 - [23] = { 1297 + { 1274 1298 .name = "r1,syscalls:sys_enter_open:k,1:1:hp", 1275 1299 .check = test__checkevent_list, 1300 + .id = 23, 1276 1301 }, 1277 - [24] = { 1302 + { 1278 1303 .name = "instructions:G", 1279 1304 .check = test__checkevent_exclude_host_modifier, 1305 + .id = 24, 1280 1306 }, 1281 - [25] = { 1307 + { 1282 1308 .name = "instructions:H", 1283 1309 .check = test__checkevent_exclude_guest_modifier, 1310 + .id = 25, 1284 1311 }, 1285 - [26] = { 1312 + { 1286 1313 .name = "mem:0:rw", 1287 1314 .check = test__checkevent_breakpoint_rw, 1315 + .id = 26, 1288 1316 }, 1289 - [27] = { 1317 + { 1290 1318 .name = "mem:0:rw:kp", 1291 1319 .check = test__checkevent_breakpoint_rw_modifier, 1320 + .id = 27, 1292 1321 }, 1293 - [28] = { 1322 + { 1294 1323 .name = "{instructions:k,cycles:upp}", 1295 1324 .check = test__group1, 1325 + .id = 28, 1296 1326 }, 1297 - [29] = { 1327 + { 1298 1328 .name = "{faults:k,cache-references}:u,cycles:k", 1299 1329 .check = test__group2, 1330 + .id = 29, 1300 1331 }, 1301 - [30] = { 1332 + { 1302 1333 .name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", 1303 1334 .check = test__group3, 1335 + .id = 30, 1304 1336 }, 1305 - [31] = { 1337 + { 1306 1338 .name = "{cycles:u,instructions:kp}:p", 1307 1339 .check = test__group4, 1340 + .id = 31, 1308 1341 }, 1309 - [32] = { 1342 + { 1310 1343 .name = "{cycles,instructions}:G,{cycles:G,instructions:G},cycles", 1311 1344 .check = test__group5, 1345 + .id = 32, 1312 1346 }, 1313 - [33] = { 1347 + { 1314 1348 .name = "*:*", 1315 1349 .check = test__all_tracepoints, 1350 + .id = 33, 1316 1351 }, 1317 - [34] = { 1352 + { 1318 1353 .name = "{cycles,cache-misses:G}:H", 1319 1354 .check = test__group_gh1, 1355 + .id = 34, 1320 1356 }, 1321 - [35] = { 1357 + { 1322 1358 .name = "{cycles,cache-misses:H}:G", 1323 1359 .check = test__group_gh2, 1360 + .id = 35, 1324 1361 }, 1325 - [36] = { 1362 + { 1326 1363 .name = "{cycles:G,cache-misses:H}:u", 1327 1364 .check = test__group_gh3, 1365 + .id = 36, 1328 1366 }, 1329 - [37] = { 1367 + { 1330 1368 .name = "{cycles:G,cache-misses:H}:uG", 1331 1369 .check = test__group_gh4, 1370 + .id = 37, 1332 1371 }, 1333 - [38] = { 1372 + { 1334 1373 .name = "{cycles,cache-misses,branch-misses}:S", 1335 1374 .check = test__leader_sample1, 1375 + .id = 38, 1336 1376 }, 1337 - [39] = { 1377 + { 1338 1378 .name = "{instructions,branch-misses}:Su", 1339 1379 .check = test__leader_sample2, 1380 + .id = 39, 1340 1381 }, 1341 - [40] = { 1382 + { 1342 1383 .name = "instructions:uDp", 1343 1384 .check = test__checkevent_pinned_modifier, 1385 + .id = 40, 1344 1386 }, 1345 - [41] = { 1387 + { 1346 1388 .name = "{cycles,cache-misses,branch-misses}:D", 1347 1389 .check = test__pinned_group, 1390 + .id = 41, 1348 1391 }, 1392 + #if defined(__s390x__) 1393 + { 1394 + .name = "kvm-s390:kvm_s390_create_vm", 1395 + .check = test__checkevent_tracepoint, 1396 + .id = 100, 1397 + }, 1398 + #endif 1349 1399 }; 1350 1400 1351 1401 static struct evlist_test test__events_pmu[] = { 1352 - [0] = { 1402 + { 1353 1403 .name = "cpu/config=10,config1,config2=3,period=1000/u", 1354 1404 .check = test__checkevent_pmu, 1405 + .id = 0, 1355 1406 }, 1356 - [1] = { 1407 + { 1357 1408 .name = "cpu/config=1,name=krava/u,cpu/config=2/u", 1358 1409 .check = test__checkevent_pmu_name, 1410 + .id = 1, 1359 1411 }, 1360 1412 }; 1361 1413 ··· 1454 1402 for (i = 0; i < cnt; i++) { 1455 1403 struct evlist_test *e = &events[i]; 1456 1404 1457 - pr_debug("running test %d '%s'\n", i, e->name); 1405 + pr_debug("running test %d '%s'\n", e->id, e->name); 1458 1406 ret1 = test_event(e); 1459 1407 if (ret1) 1460 1408 ret2 = ret1;
+5
tools/perf/util/evsel.h
··· 91 91 char *group_name; 92 92 }; 93 93 94 + union u64_swap { 95 + u64 val64; 96 + u32 val32[2]; 97 + }; 98 + 94 99 #define hists_to_evsel(h) container_of(h, struct perf_evsel, hists) 95 100 96 101 struct cpu_map;
+12
tools/perf/util/parse-events.y
··· 299 299 } 300 300 301 301 event_legacy_tracepoint: 302 + PE_NAME '-' PE_NAME ':' PE_NAME 303 + { 304 + struct parse_events_evlist *data = _data; 305 + struct list_head *list; 306 + char sys_name[128]; 307 + snprintf(&sys_name, 128, "%s-%s", $1, $3); 308 + 309 + ALLOC_LIST(list); 310 + ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5)); 311 + $$ = list; 312 + } 313 + | 302 314 PE_NAME ':' PE_NAME 303 315 { 304 316 struct parse_events_evlist *data = _data;
-5
tools/perf/util/types.h
··· 16 16 typedef unsigned char u8; 17 17 typedef signed char s8; 18 18 19 - union u64_swap { 20 - u64 val64; 21 - u32 val32[2]; 22 - }; 23 - 24 19 #endif /* __PERF_TYPES_H */
+2
tools/perf/util/util.c
··· 166 166 ssize_t ret = is_read ? read(fd, buf, left) : 167 167 write(fd, buf, left); 168 168 169 + if (ret < 0 && errno == EINTR) 170 + continue; 169 171 if (ret <= 0) 170 172 return ret; 171 173