aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-30 14:15:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-30 14:15:14 -0500
commitd8b91dde38f4c43bd0bbbf17a90f735b16aaff2c (patch)
treebd72dabf6e4b23e060fce429c87e60504f69de54 /tools/perf/util/probe-event.c
parent5e7481a25e90b661d1dbbba18be3fd3dfe12ec6f (diff)
parente4c1091cb495d9cbec8956d642644a71a1689958 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar: "Kernel side changes: - Clean up the x86 instruction decoder (Masami Hiramatsu) - Add new uprobes optimization for PUSH instructions on x86 (Yonghong Song) - Add MSR_IA32_THERM_STATUS to the MSR events (Stephane Eranian) - Fix misc bugs, update documentation, plus various cleanups (Jiri Olsa) There's a large number of tooling side improvements: - Intel-PT/BTS improvements (Adrian Hunter) - Numerous 'perf trace' improvements (Arnaldo Carvalho de Melo) - Introduce an errno code to string facility (Hendrik Brueckner) - Various build system improvements (Jiri Olsa) - Add support for CoreSight trace decoding by making the perf tools use the external openCSD (Mathieu Poirier, Tor Jeremiassen) - Add ARM Statistical Profiling Extensions (SPE) support (Kim Phillips) - libtraceevent updates (Steven Rostedt) - Intel vendor event JSON updates (Andi Kleen) - Introduce 'perf report --mmaps' and 'perf report --tasks' to show info present in 'perf.data' (Jiri Olsa, Arnaldo Carvalho de Melo) - Add infrastructure to record first and last sample time to the perf.data file header, so that when processing all samples in a 'perf record' session, such as when doing build-id processing, or when specifically requesting that that info be recorded, use that in 'perf report --time', that also got support for percent slices in addition to absolute ones. I.e. now it is possible to ask for the samples in the 10%-20% time slice of a perf.data file (Jin Yao) - Allow system wide 'perf stat --per-thread', sorting the result (Jin Yao) E.g.: [root@jouet ~]# perf stat --per-thread --metrics IPC ^C Performance counter stats for 'system wide': make-22229 23,012,094,032 inst_retired.any # 0.8 IPC cc1-22419 692,027,497 inst_retired.any # 0.8 IPC gcc-22418 328,231,855 inst_retired.any # 0.9 IPC cc1-22509 220,853,647 inst_retired.any # 0.8 IPC gcc-22486 199,874,810 inst_retired.any # 1.0 IPC as-22466 177,896,365 inst_retired.any # 0.9 IPC cc1-22465 150,732,374 inst_retired.any # 0.8 IPC gcc-22508 112,555,593 inst_retired.any # 0.9 IPC cc1-22487 108,964,079 inst_retired.any # 0.7 IPC qemu-system-x86-2697 21,330,550 inst_retired.any # 0.3 IPC systemd-journal-551 20,642,951 inst_retired.any # 0.4 IPC docker-containe-17651 9,552,892 inst_retired.any # 0.5 IPC dockerd-current-9809 7,528,586 inst_retired.any # 0.5 IPC make-22153 12,504,194,380 inst_retired.any # 0.8 IPC python2-22429 12,081,290,954 inst_retired.any # 0.8 IPC <SNIP> python2-22429 15,026,328,103 cpu_clk_unhalted.thread cc1-22419 826,660,193 cpu_clk_unhalted.thread gcc-22418 365,321,295 cpu_clk_unhalted.thread cc1-22509 279,169,362 cpu_clk_unhalted.thread gcc-22486 210,156,950 cpu_clk_unhalted.thread <SNIP> 5.638075538 seconds time elapsed [root@jouet ~]# - Improve shell auto-completion of perf events (Jin Yao) - 'perf probe' improvements (Masami Hiramatsu) - Improve PMU infrastructure to support amp64's ThunderX2 implementation defined core events (Ganapatrao Kulkarni) - Various annotation related improvements and fixes (Thomas Richter) - Clarify usage of 'overwrite' and 'backward' in the evlist/mmap code, removing the 'overwrite' parameter from several functions as it was always used it as 'false' (Wang Nan) - Fix/improve 'perf record' reverse recording support (Wang Nan) - Improve command line options documentation (Sihyeon Jang) - Optimize sample parsing for ordering events, where we don't need to parse all the PERF_SAMPLE_ bits, just the ones leading to the timestamp needed to reorder events (Jiri Olsa) - Generalize the annotation code to support other source information besides objdump/DWARF obtained ones, starting with python scripts, that will is slated to be merged soon (Jiri Olsa) - ... and a lot more that I failed to list, see the shortlog and changelog for details" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (262 commits) perf trace beauty flock: Move to separate object file perf evlist: Remove fcntl.h from evlist.h perf trace beauty futex: Beautify FUTEX_BITSET_MATCH_ANY perf trace: Do not print from time delta for interrupted syscall lines perf trace: Add --print-sample perf bpf: Remove misplaced __maybe_unused attribute MAINTAINERS: Adding entry for CoreSight trace decoding perf tools: Add mechanic to synthesise CoreSight trace packets perf tools: Add full support for CoreSight trace decoding pert tools: Add queue management functionality perf tools: Add functionality to communicate with the openCSD decoder perf tools: Add support for decoding CoreSight trace data perf tools: Add decoder mechanic to support dumping trace data perf tools: Add processing of coresight metadata perf tools: Add initial entry point for decoder CoreSight traces perf tools: Integrating the CoreSight decoding library perf vendor events intel: Update IvyTown files to V20 perf vendor events intel: Update IvyBridge files to V20 perf vendor events intel: Update BroadwellDE events to V7 perf vendor events intel: Update SkylakeX events to V1.06 ...
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c85
1 files changed, 61 insertions, 24 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index b7aaf9b2294d..e1dbc9821617 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1325,27 +1325,30 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
1325{ 1325{
1326 char *ptr; 1326 char *ptr;
1327 1327
1328 ptr = strchr(*arg, ':'); 1328 ptr = strpbrk_esc(*arg, ":");
1329 if (ptr) { 1329 if (ptr) {
1330 *ptr = '\0'; 1330 *ptr = '\0';
1331 if (!pev->sdt && !is_c_func_name(*arg)) 1331 if (!pev->sdt && !is_c_func_name(*arg))
1332 goto ng_name; 1332 goto ng_name;
1333 pev->group = strdup(*arg); 1333 pev->group = strdup_esc(*arg);
1334 if (!pev->group) 1334 if (!pev->group)
1335 return -ENOMEM; 1335 return -ENOMEM;
1336 *arg = ptr + 1; 1336 *arg = ptr + 1;
1337 } else 1337 } else
1338 pev->group = NULL; 1338 pev->group = NULL;
1339 if (!pev->sdt && !is_c_func_name(*arg)) { 1339
1340 pev->event = strdup_esc(*arg);
1341 if (pev->event == NULL)
1342 return -ENOMEM;
1343
1344 if (!pev->sdt && !is_c_func_name(pev->event)) {
1345 zfree(&pev->event);
1340ng_name: 1346ng_name:
1347 zfree(&pev->group);
1341 semantic_error("%s is bad for event name -it must " 1348 semantic_error("%s is bad for event name -it must "
1342 "follow C symbol-naming rule.\n", *arg); 1349 "follow C symbol-naming rule.\n", *arg);
1343 return -EINVAL; 1350 return -EINVAL;
1344 } 1351 }
1345 pev->event = strdup(*arg);
1346 if (pev->event == NULL)
1347 return -ENOMEM;
1348
1349 return 0; 1352 return 0;
1350} 1353}
1351 1354
@@ -1373,7 +1376,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1373 arg++; 1376 arg++;
1374 } 1377 }
1375 1378
1376 ptr = strpbrk(arg, ";=@+%"); 1379 ptr = strpbrk_esc(arg, ";=@+%");
1377 if (pev->sdt) { 1380 if (pev->sdt) {
1378 if (ptr) { 1381 if (ptr) {
1379 if (*ptr != '@') { 1382 if (*ptr != '@') {
@@ -1387,7 +1390,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1387 pev->target = build_id_cache__origname(tmp); 1390 pev->target = build_id_cache__origname(tmp);
1388 free(tmp); 1391 free(tmp);
1389 } else 1392 } else
1390 pev->target = strdup(ptr + 1); 1393 pev->target = strdup_esc(ptr + 1);
1391 if (!pev->target) 1394 if (!pev->target)
1392 return -ENOMEM; 1395 return -ENOMEM;
1393 *ptr = '\0'; 1396 *ptr = '\0';
@@ -1421,13 +1424,14 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1421 * 1424 *
1422 * Otherwise, we consider arg to be a function specification. 1425 * Otherwise, we consider arg to be a function specification.
1423 */ 1426 */
1424 if (!strpbrk(arg, "+@%") && (ptr = strpbrk(arg, ";:")) != NULL) { 1427 if (!strpbrk_esc(arg, "+@%")) {
1428 ptr = strpbrk_esc(arg, ";:");
1425 /* This is a file spec if it includes a '.' before ; or : */ 1429 /* This is a file spec if it includes a '.' before ; or : */
1426 if (memchr(arg, '.', ptr - arg)) 1430 if (ptr && memchr(arg, '.', ptr - arg))
1427 file_spec = true; 1431 file_spec = true;
1428 } 1432 }
1429 1433
1430 ptr = strpbrk(arg, ";:+@%"); 1434 ptr = strpbrk_esc(arg, ";:+@%");
1431 if (ptr) { 1435 if (ptr) {
1432 nc = *ptr; 1436 nc = *ptr;
1433 *ptr++ = '\0'; 1437 *ptr++ = '\0';
@@ -1436,7 +1440,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1436 if (arg[0] == '\0') 1440 if (arg[0] == '\0')
1437 tmp = NULL; 1441 tmp = NULL;
1438 else { 1442 else {
1439 tmp = strdup(arg); 1443 tmp = strdup_esc(arg);
1440 if (tmp == NULL) 1444 if (tmp == NULL)
1441 return -ENOMEM; 1445 return -ENOMEM;
1442 } 1446 }
@@ -1469,12 +1473,12 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1469 arg = ptr; 1473 arg = ptr;
1470 c = nc; 1474 c = nc;
1471 if (c == ';') { /* Lazy pattern must be the last part */ 1475 if (c == ';') { /* Lazy pattern must be the last part */
1472 pp->lazy_line = strdup(arg); 1476 pp->lazy_line = strdup(arg); /* let leave escapes */
1473 if (pp->lazy_line == NULL) 1477 if (pp->lazy_line == NULL)
1474 return -ENOMEM; 1478 return -ENOMEM;
1475 break; 1479 break;
1476 } 1480 }
1477 ptr = strpbrk(arg, ";:+@%"); 1481 ptr = strpbrk_esc(arg, ";:+@%");
1478 if (ptr) { 1482 if (ptr) {
1479 nc = *ptr; 1483 nc = *ptr;
1480 *ptr++ = '\0'; 1484 *ptr++ = '\0';
@@ -1501,7 +1505,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1501 semantic_error("SRC@SRC is not allowed.\n"); 1505 semantic_error("SRC@SRC is not allowed.\n");
1502 return -EINVAL; 1506 return -EINVAL;
1503 } 1507 }
1504 pp->file = strdup(arg); 1508 pp->file = strdup_esc(arg);
1505 if (pp->file == NULL) 1509 if (pp->file == NULL)
1506 return -ENOMEM; 1510 return -ENOMEM;
1507 break; 1511 break;
@@ -2573,7 +2577,8 @@ int show_perf_probe_events(struct strfilter *filter)
2573} 2577}
2574 2578
2575static int get_new_event_name(char *buf, size_t len, const char *base, 2579static int get_new_event_name(char *buf, size_t len, const char *base,
2576 struct strlist *namelist, bool allow_suffix) 2580 struct strlist *namelist, bool ret_event,
2581 bool allow_suffix)
2577{ 2582{
2578 int i, ret; 2583 int i, ret;
2579 char *p, *nbase; 2584 char *p, *nbase;
@@ -2584,13 +2589,13 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
2584 if (!nbase) 2589 if (!nbase)
2585 return -ENOMEM; 2590 return -ENOMEM;
2586 2591
2587 /* Cut off the dot suffixes (e.g. .const, .isra)*/ 2592 /* Cut off the dot suffixes (e.g. .const, .isra) and version suffixes */
2588 p = strchr(nbase, '.'); 2593 p = strpbrk(nbase, ".@");
2589 if (p && p != nbase) 2594 if (p && p != nbase)
2590 *p = '\0'; 2595 *p = '\0';
2591 2596
2592 /* Try no suffix number */ 2597 /* Try no suffix number */
2593 ret = e_snprintf(buf, len, "%s", nbase); 2598 ret = e_snprintf(buf, len, "%s%s", nbase, ret_event ? "__return" : "");
2594 if (ret < 0) { 2599 if (ret < 0) {
2595 pr_debug("snprintf() failed: %d\n", ret); 2600 pr_debug("snprintf() failed: %d\n", ret);
2596 goto out; 2601 goto out;
@@ -2625,6 +2630,14 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
2625 2630
2626out: 2631out:
2627 free(nbase); 2632 free(nbase);
2633
2634 /* Final validation */
2635 if (ret >= 0 && !is_c_func_name(buf)) {
2636 pr_warning("Internal error: \"%s\" is an invalid event name.\n",
2637 buf);
2638 ret = -EINVAL;
2639 }
2640
2628 return ret; 2641 return ret;
2629} 2642}
2630 2643
@@ -2681,8 +2694,8 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
2681 group = PERFPROBE_GROUP; 2694 group = PERFPROBE_GROUP;
2682 2695
2683 /* Get an unused new event name */ 2696 /* Get an unused new event name */
2684 ret = get_new_event_name(buf, 64, event, 2697 ret = get_new_event_name(buf, 64, event, namelist,
2685 namelist, allow_suffix); 2698 tev->point.retprobe, allow_suffix);
2686 if (ret < 0) 2699 if (ret < 0)
2687 return ret; 2700 return ret;
2688 2701
@@ -2792,16 +2805,40 @@ static int find_probe_functions(struct map *map, char *name,
2792 int found = 0; 2805 int found = 0;
2793 struct symbol *sym; 2806 struct symbol *sym;
2794 struct rb_node *tmp; 2807 struct rb_node *tmp;
2808 const char *norm, *ver;
2809 char *buf = NULL;
2810 bool cut_version = true;
2795 2811
2796 if (map__load(map) < 0) 2812 if (map__load(map) < 0)
2797 return 0; 2813 return 0;
2798 2814
2815 /* If user gives a version, don't cut off the version from symbols */
2816 if (strchr(name, '@'))
2817 cut_version = false;
2818
2799 map__for_each_symbol(map, sym, tmp) { 2819 map__for_each_symbol(map, sym, tmp) {
2800 if (strglobmatch(sym->name, name)) { 2820 norm = arch__normalize_symbol_name(sym->name);
2821 if (!norm)
2822 continue;
2823
2824 if (cut_version) {
2825 /* We don't care about default symbol or not */
2826 ver = strchr(norm, '@');
2827 if (ver) {
2828 buf = strndup(norm, ver - norm);
2829 if (!buf)
2830 return -ENOMEM;
2831 norm = buf;
2832 }
2833 }
2834
2835 if (strglobmatch(norm, name)) {
2801 found++; 2836 found++;
2802 if (syms && found < probe_conf.max_probes) 2837 if (syms && found < probe_conf.max_probes)
2803 syms[found - 1] = sym; 2838 syms[found - 1] = sym;
2804 } 2839 }
2840 if (buf)
2841 zfree(&buf);
2805 } 2842 }
2806 2843
2807 return found; 2844 return found;
@@ -2847,7 +2884,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2847 * same name but different addresses, this lists all the symbols. 2884 * same name but different addresses, this lists all the symbols.
2848 */ 2885 */
2849 num_matched_functions = find_probe_functions(map, pp->function, syms); 2886 num_matched_functions = find_probe_functions(map, pp->function, syms);
2850 if (num_matched_functions == 0) { 2887 if (num_matched_functions <= 0) {
2851 pr_err("Failed to find symbol %s in %s\n", pp->function, 2888 pr_err("Failed to find symbol %s in %s\n", pp->function,
2852 pev->target ? : "kernel"); 2889 pev->target ? : "kernel");
2853 ret = -ENOENT; 2890 ret = -ENOENT;