[PATCH perf/core v11 08/23] perf probe: Use cache entry if possible

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

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 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v6:
  - Remove fallback lookup routine by using function name
as cached event name, because it should be done by following
patch which supports %cached-event.
---
 tools/perf/util/probe-event.c |   65 -
 tools/perf/util/probe-file.c  |   20 -
 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 084756c..020c110 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2476,17 +2476,24 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
char buf[64];
int ret;
 
+   /* If probe_event or trace_event already have the name, reuse it */
if (pev->event)
event = pev->event;
-   else
+   else if (tev->event)
+   event = tev->event;
+   else {
+   /* Or generate new one from probe point */
if (pev->point.function &&
(strncmp(pev->point.function, "0x", 2) != 0) &&
!strisglob(pev->point.function))
event = pev->point.function;
else
event = tev->point.realname;
+   }
if (pev->group)
group = pev->group;
+   else if (tev->group)
+   group = tev->group;
else
group = PERFPROBE_GROUP;
 
@@ -2533,7 +2540,7 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
for (i = 0; i < ntevs; i++) {
tev = [i];
/* Skip if the symbol is out of .text or blacklisted */
-   if (!tev->point.symbol)
+   if (!tev->point.symbol && !pev->uprobes)
continue;
 
/* Set new name for tev (and update namelist) */
@@ -2846,6 +2853,55 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
+ struct probe_trace_event **tevs)
+{
+   struct probe_cache *cache;
+   struct probe_cache_entry *entry;
+   struct probe_trace_event *tev;
+   struct str_node *node;
+   int ret, i;
+
+   cache = probe_cache__new(pev->target);
+   if (!cache)
+   return 0;
+
+   entry = probe_cache__find(cache, pev);
+   if (!entry) {
+   ret = 0;
+   goto out;
+   }
+
+   ret = strlist__nr_entries(entry->tevlist);
+   if (ret > probe_conf.max_probes) {
+   pr_debug("Too many entries matched in the cache of %s\n",
+pev->target ? : "kernel");
+   ret = -E2BIG;
+   goto out;
+   }
+
+   *tevs = zalloc(ret * sizeof(*tev));
+   if (!*tevs) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   i = 0;
+   strlist__for_each(node, entry->tevlist) {
+   tev = &(*tevs)[i++];
+   ret = parse_probe_trace_command(node->s, tev);
+   if (ret < 0)
+   goto out;
+   /* Set the uprobes attribute as same as original */
+   tev->uprobes = pev->uprobes;
+   }
+   ret = i;
+
+out:
+   probe_cache__delete(cache);
+   return ret;
+}
+
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 struct probe_trace_event **tevs)
 {
@@ -2868,6 +2924,11 @@ static int convert_to_probe_trace_events(struct 
perf_probe_event *pev,
if (ret > 0)
return ret;
 
+   /* At first, we need to lookup cache entry */
+   ret = find_probe_trace_events_from_cache(pev, tevs);
+   if (ret > 0)
+   return ret; /* Found in probe cache */
+
if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
ret = find_probe_trace_events_from_map(pev, tevs);
if (ret > 0)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 25a4042..58a60b3 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)
return !strcmp(a, b);
 }
 
-static struct probe_cache_entry *
+struct probe_cache_entry *
 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 {
struct probe_cache_entry *entry = NULL;
@@ -548,6 +548,24 @@ found:
return 

[PATCH perf/core v11 08/23] perf probe: Use cache entry if possible

2016-06-14 Thread Masami Hiramatsu
From: Masami Hiramatsu 

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 
Signed-off-by: Masami Hiramatsu 
---
 Changes in v6:
  - Remove fallback lookup routine by using function name
as cached event name, because it should be done by following
patch which supports %cached-event.
---
 tools/perf/util/probe-event.c |   65 -
 tools/perf/util/probe-file.c  |   20 -
 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 084756c..020c110 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2476,17 +2476,24 @@ static int probe_trace_event__set_name(struct 
probe_trace_event *tev,
char buf[64];
int ret;
 
+   /* If probe_event or trace_event already have the name, reuse it */
if (pev->event)
event = pev->event;
-   else
+   else if (tev->event)
+   event = tev->event;
+   else {
+   /* Or generate new one from probe point */
if (pev->point.function &&
(strncmp(pev->point.function, "0x", 2) != 0) &&
!strisglob(pev->point.function))
event = pev->point.function;
else
event = tev->point.realname;
+   }
if (pev->group)
group = pev->group;
+   else if (tev->group)
+   group = tev->group;
else
group = PERFPROBE_GROUP;
 
@@ -2533,7 +2540,7 @@ static int __add_probe_trace_events(struct 
perf_probe_event *pev,
for (i = 0; i < ntevs; i++) {
tev = [i];
/* Skip if the symbol is out of .text or blacklisted */
-   if (!tev->point.symbol)
+   if (!tev->point.symbol && !pev->uprobes)
continue;
 
/* Set new name for tev (and update namelist) */
@@ -2846,6 +2853,55 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
+ struct probe_trace_event **tevs)
+{
+   struct probe_cache *cache;
+   struct probe_cache_entry *entry;
+   struct probe_trace_event *tev;
+   struct str_node *node;
+   int ret, i;
+
+   cache = probe_cache__new(pev->target);
+   if (!cache)
+   return 0;
+
+   entry = probe_cache__find(cache, pev);
+   if (!entry) {
+   ret = 0;
+   goto out;
+   }
+
+   ret = strlist__nr_entries(entry->tevlist);
+   if (ret > probe_conf.max_probes) {
+   pr_debug("Too many entries matched in the cache of %s\n",
+pev->target ? : "kernel");
+   ret = -E2BIG;
+   goto out;
+   }
+
+   *tevs = zalloc(ret * sizeof(*tev));
+   if (!*tevs) {
+   ret = -ENOMEM;
+   goto out;
+   }
+
+   i = 0;
+   strlist__for_each(node, entry->tevlist) {
+   tev = &(*tevs)[i++];
+   ret = parse_probe_trace_command(node->s, tev);
+   if (ret < 0)
+   goto out;
+   /* Set the uprobes attribute as same as original */
+   tev->uprobes = pev->uprobes;
+   }
+   ret = i;
+
+out:
+   probe_cache__delete(cache);
+   return ret;
+}
+
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 struct probe_trace_event **tevs)
 {
@@ -2868,6 +2924,11 @@ static int convert_to_probe_trace_events(struct 
perf_probe_event *pev,
if (ret > 0)
return ret;
 
+   /* At first, we need to lookup cache entry */
+   ret = find_probe_trace_events_from_cache(pev, tevs);
+   if (ret > 0)
+   return ret; /* Found in probe cache */
+
if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
ret = find_probe_trace_events_from_map(pev, tevs);
if (ret > 0)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 25a4042..58a60b3 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)
return !strcmp(a, b);
 }
 
-static struct probe_cache_entry *
+struct probe_cache_entry *
 probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 {
struct probe_cache_entry *entry = NULL;
@@ -548,6 +548,24 @@ found:
return entry;
 }
 
+struct probe_cache_entry *
+probe_cache__find_by_name(struct probe_cache