Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7737af01 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo
Browse files

perf probe: Speed up perf probe --list by caching debuginfo



Speed up the "perf probe --list" by caching the last used debuginfo.
perf probe --list always open and load debuginfo for each entry of probe
list. This takes very a long time.

E.g. with vfs_* events (total 96 probes)

  [root@localhost perf]# time  ./perf probe -l &> /dev/null

  real    0m25.376s
  user    0m24.381s
  sys     0m1.012s

To solve this issue, this adds debuginfo_cache to cache the
last used debuginfo on memory.

With this fix, the perf-probe --list significantly improves
its speed.

  [root@localhost perf]#  time  ./perf probe -l &> /dev/null

  real    0m0.161s
  user    0m0.136s
  sys     0m0.025s

Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Naohiro Aota <naota@elisp.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150617145854.19715.15314.stgit@localhost.localdomain


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d350bd57
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -429,6 +429,41 @@ static struct debuginfo *open_debuginfo(const char *module, bool silent)
	return ret;
}

/* For caching the last debuginfo */
static struct debuginfo *debuginfo_cache;
static char *debuginfo_cache_path;

static struct debuginfo *debuginfo_cache__open(const char *module, bool silent)
{
	if ((debuginfo_cache_path && !strcmp(debuginfo_cache_path, module)) ||
	    (!debuginfo_cache_path && !module && debuginfo_cache))
		goto out;

	/* Copy module path */
	free(debuginfo_cache_path);
	if (module) {
		debuginfo_cache_path = strdup(module);
		if (!debuginfo_cache_path) {
			debuginfo__delete(debuginfo_cache);
			debuginfo_cache = NULL;
			goto out;
		}
	}

	debuginfo_cache = open_debuginfo(module, silent);
	if (!debuginfo_cache)
		zfree(&debuginfo_cache_path);
out:
	return debuginfo_cache;
}

static void debuginfo_cache__exit(void)
{
	debuginfo__delete(debuginfo_cache);
	debuginfo_cache = NULL;
	zfree(&debuginfo_cache_path);
}


static int get_text_start_address(const char *exec, unsigned long *address)
{
@@ -490,12 +525,11 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
	pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
		 tp->module ? : "kernel");

	dinfo = open_debuginfo(tp->module, verbose == 0);
	if (dinfo) {
	dinfo = debuginfo_cache__open(tp->module, verbose == 0);
	if (dinfo)
		ret = debuginfo__find_probe_point(dinfo,
						 (unsigned long)addr, pp);
		debuginfo__delete(dinfo);
	} else
	else
		ret = -ENOENT;

	if (ret > 0) {
@@ -930,6 +964,10 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,

#else	/* !HAVE_DWARF_SUPPORT */

static void debuginfo_cache__exit(void)
{
}

static int
find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
				 struct perf_probe_point *pp __maybe_unused,
@@ -2266,6 +2304,8 @@ static int __show_perf_probe_events(int fd, bool is_kprobe,
			break;
	}
	strlist__delete(rawlist);
	/* Cleanup cached debuginfo if needed */
	debuginfo_cache__exit();

	return ret;
}