diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2016-07-01 04:03:12 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-07-01 10:34:57 -0400 |
commit | bc0622302f344551050995491b7d14176f39c628 (patch) | |
tree | aca2555b791c87c7615bcc15711af7a283fb554d | |
parent | dc29bb47a34130459fadd58f05e2acd051a6327d (diff) |
perf probe: Use cache entry if possible
Before analyzing debuginfo, try to find a corresponding entry from probe
cache always. This does not depend on --cache, the --cache enables to
store/update cache, but looking up the cache is always enabled.
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146736019226.27797.16366402884098398857.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/probe-event.c | 65 | ||||
-rw-r--r-- | tools/perf/util/probe-file.c | 20 | ||||
-rw-r--r-- | tools/perf/util/probe-file.h | 5 |
3 files changed, 86 insertions, 4 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 55f41d5e20d1..47b6b8b7206e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -2474,17 +2474,24 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev, | |||
2474 | char buf[64]; | 2474 | char buf[64]; |
2475 | int ret; | 2475 | int ret; |
2476 | 2476 | ||
2477 | /* If probe_event or trace_event already have the name, reuse it */ | ||
2477 | if (pev->event) | 2478 | if (pev->event) |
2478 | event = pev->event; | 2479 | event = pev->event; |
2479 | else | 2480 | else if (tev->event) |
2481 | event = tev->event; | ||
2482 | else { | ||
2483 | /* Or generate new one from probe point */ | ||
2480 | if (pev->point.function && | 2484 | if (pev->point.function && |
2481 | (strncmp(pev->point.function, "0x", 2) != 0) && | 2485 | (strncmp(pev->point.function, "0x", 2) != 0) && |
2482 | !strisglob(pev->point.function)) | 2486 | !strisglob(pev->point.function)) |
2483 | event = pev->point.function; | 2487 | event = pev->point.function; |
2484 | else | 2488 | else |
2485 | event = tev->point.realname; | 2489 | event = tev->point.realname; |
2490 | } | ||
2486 | if (pev->group) | 2491 | if (pev->group) |
2487 | group = pev->group; | 2492 | group = pev->group; |
2493 | else if (tev->group) | ||
2494 | group = tev->group; | ||
2488 | else | 2495 | else |
2489 | group = PERFPROBE_GROUP; | 2496 | group = PERFPROBE_GROUP; |
2490 | 2497 | ||
@@ -2531,7 +2538,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, | |||
2531 | for (i = 0; i < ntevs; i++) { | 2538 | for (i = 0; i < ntevs; i++) { |
2532 | tev = &tevs[i]; | 2539 | tev = &tevs[i]; |
2533 | /* Skip if the symbol is out of .text or blacklisted */ | 2540 | /* Skip if the symbol is out of .text or blacklisted */ |
2534 | if (!tev->point.symbol) | 2541 | if (!tev->point.symbol && !pev->uprobes) |
2535 | continue; | 2542 | continue; |
2536 | 2543 | ||
2537 | /* Set new name for tev (and update namelist) */ | 2544 | /* Set new name for tev (and update namelist) */ |
@@ -2844,6 +2851,55 @@ errout: | |||
2844 | 2851 | ||
2845 | bool __weak arch__prefers_symtab(void) { return false; } | 2852 | bool __weak arch__prefers_symtab(void) { return false; } |
2846 | 2853 | ||
2854 | static int find_probe_trace_events_from_cache(struct perf_probe_event *pev, | ||
2855 | struct probe_trace_event **tevs) | ||
2856 | { | ||
2857 | struct probe_cache *cache; | ||
2858 | struct probe_cache_entry *entry; | ||
2859 | struct probe_trace_event *tev; | ||
2860 | struct str_node *node; | ||
2861 | int ret, i; | ||
2862 | |||
2863 | cache = probe_cache__new(pev->target); | ||
2864 | if (!cache) | ||
2865 | return 0; | ||
2866 | |||
2867 | entry = probe_cache__find(cache, pev); | ||
2868 | if (!entry) { | ||
2869 | ret = 0; | ||
2870 | goto out; | ||
2871 | } | ||
2872 | |||
2873 | ret = strlist__nr_entries(entry->tevlist); | ||
2874 | if (ret > probe_conf.max_probes) { | ||
2875 | pr_debug("Too many entries matched in the cache of %s\n", | ||
2876 | pev->target ? : "kernel"); | ||
2877 | ret = -E2BIG; | ||
2878 | goto out; | ||
2879 | } | ||
2880 | |||
2881 | *tevs = zalloc(ret * sizeof(*tev)); | ||
2882 | if (!*tevs) { | ||
2883 | ret = -ENOMEM; | ||
2884 | goto out; | ||
2885 | } | ||
2886 | |||
2887 | i = 0; | ||
2888 | strlist__for_each_entry(node, entry->tevlist) { | ||
2889 | tev = &(*tevs)[i++]; | ||
2890 | ret = parse_probe_trace_command(node->s, tev); | ||
2891 | if (ret < 0) | ||
2892 | goto out; | ||
2893 | /* Set the uprobes attribute as same as original */ | ||
2894 | tev->uprobes = pev->uprobes; | ||
2895 | } | ||
2896 | ret = i; | ||
2897 | |||
2898 | out: | ||
2899 | probe_cache__delete(cache); | ||
2900 | return ret; | ||
2901 | } | ||
2902 | |||
2847 | static int convert_to_probe_trace_events(struct perf_probe_event *pev, | 2903 | static int convert_to_probe_trace_events(struct perf_probe_event *pev, |
2848 | struct probe_trace_event **tevs) | 2904 | struct probe_trace_event **tevs) |
2849 | { | 2905 | { |
@@ -2866,6 +2922,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, | |||
2866 | if (ret > 0) | 2922 | if (ret > 0) |
2867 | return ret; | 2923 | return ret; |
2868 | 2924 | ||
2925 | /* At first, we need to lookup cache entry */ | ||
2926 | ret = find_probe_trace_events_from_cache(pev, tevs); | ||
2927 | if (ret > 0) | ||
2928 | return ret; /* Found in probe cache */ | ||
2929 | |||
2869 | if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) { | 2930 | if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) { |
2870 | ret = find_probe_trace_events_from_map(pev, tevs); | 2931 | ret = find_probe_trace_events_from_map(pev, tevs); |
2871 | if (ret > 0) | 2932 | if (ret > 0) |
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 1c12c1ab19c9..a94ee478178d 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c | |||
@@ -524,7 +524,7 @@ static bool streql(const char *a, const char *b) | |||
524 | return !strcmp(a, b); | 524 | return !strcmp(a, b); |
525 | } | 525 | } |
526 | 526 | ||
527 | static struct probe_cache_entry * | 527 | struct probe_cache_entry * |
528 | probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev) | 528 | probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev) |
529 | { | 529 | { |
530 | struct probe_cache_entry *entry = NULL; | 530 | struct probe_cache_entry *entry = NULL; |
@@ -548,6 +548,24 @@ found: | |||
548 | return entry; | 548 | return entry; |
549 | } | 549 | } |
550 | 550 | ||
551 | struct probe_cache_entry * | ||
552 | probe_cache__find_by_name(struct probe_cache *pcache, | ||
553 | const char *group, const char *event) | ||
554 | { | ||
555 | struct probe_cache_entry *entry = NULL; | ||
556 | |||
557 | list_for_each_entry(entry, &pcache->entries, node) { | ||
558 | /* Hit if same event name or same command-string */ | ||
559 | if (streql(entry->pev.group, group) && | ||
560 | streql(entry->pev.event, event)) | ||
561 | goto found; | ||
562 | } | ||
563 | entry = NULL; | ||
564 | |||
565 | found: | ||
566 | return entry; | ||
567 | } | ||
568 | |||
551 | int probe_cache__add_entry(struct probe_cache *pcache, | 569 | int probe_cache__add_entry(struct probe_cache *pcache, |
552 | struct perf_probe_event *pev, | 570 | struct perf_probe_event *pev, |
553 | struct probe_trace_event *tevs, int ntevs) | 571 | struct probe_trace_event *tevs, int ntevs) |
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h index d872e3df7e59..910aa74953e9 100644 --- a/tools/perf/util/probe-file.h +++ b/tools/perf/util/probe-file.h | |||
@@ -38,5 +38,8 @@ int probe_cache__add_entry(struct probe_cache *pcache, | |||
38 | int probe_cache__commit(struct probe_cache *pcache); | 38 | int probe_cache__commit(struct probe_cache *pcache); |
39 | void probe_cache__purge(struct probe_cache *pcache); | 39 | void probe_cache__purge(struct probe_cache *pcache); |
40 | void probe_cache__delete(struct probe_cache *pcache); | 40 | void probe_cache__delete(struct probe_cache *pcache); |
41 | 41 | struct probe_cache_entry *probe_cache__find(struct probe_cache *pcache, | |
42 | struct perf_probe_event *pev); | ||
43 | struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache, | ||
44 | const char *group, const char *event); | ||
42 | #endif | 45 | #endif |