* [PATCH -tip v3] perf probe: Add fastpath to do lookup by function name
@ 2011-03-25 8:27 Lin Ming
2011-03-28 1:02 ` Masami Hiramatsu
2011-03-30 7:16 ` [tip:perf/core] " tip-bot for Lin Ming
0 siblings, 2 replies; 3+ messages in thread
From: Lin Ming @ 2011-03-25 8:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Masami Hiramatsu
Cc: Peter Zijlstra, Ingo Molnar, linux-kernel
v3 -> v2:
- Make pubname_search_cb more generic
- Add fastpath to find_probes also
v2 -> v1:
- Don't compare file names with cu_find_realpath(...), instead, compare
them with the name returned by dwarf_decl_file(sp_die)
The vmlinux file may have thousands of CUs.
We can lookup function name from .debug_pubnames section
to avoid the slow loop on CUs.
1. Improvement data for find_line_range
./perf stat -e cycles -r 10 -- ./perf probe -k /home/mlin/vmlinux \
-s /home/mlin/linux-2.6 \
--line csum_partial_copy_to_user > tmp.log
before patch applied
=====================
847,988,276 cycles
0.355075856 seconds time elapsed
after patch applied
=====================
206,102,622 cycles
0.086883555 seconds time elapsed
2. Improvement data for find_probes
./perf stat -e cycles -r 10 -- ./perf probe -k /home/mlin/vmlinux \
-s /home/mlin/linux-2.6 \
--vars csum_partial_copy_to_user > tmp.log
before patch applied
=====================
848,490,844 cycles
0.355307901 seconds time elapsed
after patch applied
=====================
205,684,469 cycles
0.086694010 seconds time elapsed
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
tools/perf/util/probe-finder.c | 68 ++++++++++++++++++++++++++++++++++++++++
tools/perf/util/probe-finder.h | 2 +
2 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 194f9e2..23fc9eb 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1435,6 +1435,38 @@ static int find_probe_point_by_func(struct probe_finder *pf)
return _param.retval;
}
+struct pubname_callback_param {
+ char *function;
+ char *file;
+ Dwarf_Die *cu_die;
+ Dwarf_Die *sp_die;
+ int found;
+};
+
+static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
+{
+ struct pubname_callback_param *param = data;
+
+ if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
+ if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
+ return DWARF_CB_OK;
+
+ if (die_compare_name(param->sp_die, param->function)) {
+ if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
+ return DWARF_CB_OK;
+
+ if (param->file &&
+ strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
+ return DWARF_CB_OK;
+
+ param->found = 1;
+ return DWARF_CB_ABORT;
+ }
+ }
+
+ return DWARF_CB_OK;
+}
+
/* Find probe points from debuginfo */
static int find_probes(int fd, struct probe_finder *pf)
{
@@ -1461,6 +1493,23 @@ static int find_probes(int fd, struct probe_finder *pf)
off = 0;
line_list__init(&pf->lcache);
+
+ /* Fastpath: lookup by function name from .debug_pubnames section */
+ if (pp->function) {
+ struct pubname_callback_param pubname_param = {
+ .function = pp->function, .file = pp->file,
+ .cu_die = &pf->cu_die, .sp_die = &pf->sp_die, .found = 0};
+ struct dwarf_callback_param probe_param = {
+ .data = (void *)pf, .retval = 0};
+
+ dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
+ if (pubname_param.found) {
+ ret = probe_point_search_cb(&pf->sp_die, &probe_param);
+ if (ret)
+ goto found;
+ }
+ }
+
/* Loop on CUs (Compilation Unit) */
while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
/* Get the DIE(Debugging Information Entry) of this CU */
@@ -1488,6 +1537,8 @@ static int find_probes(int fd, struct probe_finder *pf)
}
off = noff;
}
+
+found:
line_list__free(&pf->lcache);
if (dwfl)
dwfl_end(dwfl);
@@ -1895,6 +1946,22 @@ int find_line_range(int fd, struct line_range *lr)
return -EBADF;
}
+ /* Fastpath: lookup by function name from .debug_pubnames section */
+ if (lr->function) {
+ struct pubname_callback_param pubname_param = {
+ .function = lr->function, .file = lr->file,
+ .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
+ struct dwarf_callback_param line_range_param = {
+ .data = (void *)&lf, .retval = 0};
+
+ dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
+ if (pubname_param.found) {
+ line_range_search_cb(&lf.sp_die, &line_range_param);
+ if (lf.found)
+ goto found;
+ }
+ }
+
/* Loop on CUs (Compilation Unit) */
while (!lf.found && ret >= 0) {
if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
@@ -1923,6 +1990,7 @@ int find_line_range(int fd, struct line_range *lr)
off = noff;
}
+found:
/* Store comp_dir */
if (lf.found) {
comp_dir = cu_get_comp_dir(&lf.cu_die);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index beaefc3..605730a 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -49,6 +49,7 @@ struct probe_finder {
Dwarf_Addr addr; /* Address */
const char *fname; /* Real file name */
Dwarf_Die cu_die; /* Current CU */
+ Dwarf_Die sp_die;
struct list_head lcache; /* Line cache for lazy match */
/* For variable searching */
@@ -83,6 +84,7 @@ struct line_finder {
int lno_s; /* Start line number */
int lno_e; /* End line number */
Dwarf_Die cu_die; /* Current CU */
+ Dwarf_Die sp_die;
int found;
};
--
1.7.2.3
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH -tip v3] perf probe: Add fastpath to do lookup by function name
2011-03-25 8:27 [PATCH -tip v3] perf probe: Add fastpath to do lookup by function name Lin Ming
@ 2011-03-28 1:02 ` Masami Hiramatsu
2011-03-30 7:16 ` [tip:perf/core] " tip-bot for Lin Ming
1 sibling, 0 replies; 3+ messages in thread
From: Masami Hiramatsu @ 2011-03-28 1:02 UTC (permalink / raw)
To: Lin Ming
Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
linux-kernel
(2011/03/25 17:27), Lin Ming wrote:
> v3 -> v2:
> - Make pubname_search_cb more generic
> - Add fastpath to find_probes also
Good catch! :)
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Thank you,
>
> v2 -> v1:
> - Don't compare file names with cu_find_realpath(...), instead, compare
> them with the name returned by dwarf_decl_file(sp_die)
>
> The vmlinux file may have thousands of CUs.
> We can lookup function name from .debug_pubnames section
> to avoid the slow loop on CUs.
>
> 1. Improvement data for find_line_range
>
> ./perf stat -e cycles -r 10 -- ./perf probe -k /home/mlin/vmlinux \
> -s /home/mlin/linux-2.6 \
> --line csum_partial_copy_to_user > tmp.log
>
> before patch applied
> =====================
> 847,988,276 cycles
>
> 0.355075856 seconds time elapsed
>
> after patch applied
> =====================
> 206,102,622 cycles
>
> 0.086883555 seconds time elapsed
>
> 2. Improvement data for find_probes
>
> ./perf stat -e cycles -r 10 -- ./perf probe -k /home/mlin/vmlinux \
> -s /home/mlin/linux-2.6 \
> --vars csum_partial_copy_to_user > tmp.log
>
> before patch applied
> =====================
> 848,490,844 cycles
>
> 0.355307901 seconds time elapsed
>
> after patch applied
> =====================
> 205,684,469 cycles
>
> 0.086694010 seconds time elapsed
>
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> ---
> tools/perf/util/probe-finder.c | 68 ++++++++++++++++++++++++++++++++++++++++
> tools/perf/util/probe-finder.h | 2 +
> 2 files changed, 70 insertions(+), 0 deletions(-)
>
> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> index 194f9e2..23fc9eb 100644
> --- a/tools/perf/util/probe-finder.c
> +++ b/tools/perf/util/probe-finder.c
> @@ -1435,6 +1435,38 @@ static int find_probe_point_by_func(struct probe_finder *pf)
> return _param.retval;
> }
>
> +struct pubname_callback_param {
> + char *function;
> + char *file;
> + Dwarf_Die *cu_die;
> + Dwarf_Die *sp_die;
> + int found;
> +};
> +
> +static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
> +{
> + struct pubname_callback_param *param = data;
> +
> + if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
> + if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
> + return DWARF_CB_OK;
> +
> + if (die_compare_name(param->sp_die, param->function)) {
> + if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
> + return DWARF_CB_OK;
> +
> + if (param->file &&
> + strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
> + return DWARF_CB_OK;
> +
> + param->found = 1;
> + return DWARF_CB_ABORT;
> + }
> + }
> +
> + return DWARF_CB_OK;
> +}
> +
> /* Find probe points from debuginfo */
> static int find_probes(int fd, struct probe_finder *pf)
> {
> @@ -1461,6 +1493,23 @@ static int find_probes(int fd, struct probe_finder *pf)
>
> off = 0;
> line_list__init(&pf->lcache);
> +
> + /* Fastpath: lookup by function name from .debug_pubnames section */
> + if (pp->function) {
> + struct pubname_callback_param pubname_param = {
> + .function = pp->function, .file = pp->file,
> + .cu_die = &pf->cu_die, .sp_die = &pf->sp_die, .found = 0};
> + struct dwarf_callback_param probe_param = {
> + .data = (void *)pf, .retval = 0};
> +
> + dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
> + if (pubname_param.found) {
> + ret = probe_point_search_cb(&pf->sp_die, &probe_param);
> + if (ret)
> + goto found;
> + }
> + }
> +
> /* Loop on CUs (Compilation Unit) */
> while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
> /* Get the DIE(Debugging Information Entry) of this CU */
> @@ -1488,6 +1537,8 @@ static int find_probes(int fd, struct probe_finder *pf)
> }
> off = noff;
> }
> +
> +found:
> line_list__free(&pf->lcache);
> if (dwfl)
> dwfl_end(dwfl);
> @@ -1895,6 +1946,22 @@ int find_line_range(int fd, struct line_range *lr)
> return -EBADF;
> }
>
> + /* Fastpath: lookup by function name from .debug_pubnames section */
> + if (lr->function) {
> + struct pubname_callback_param pubname_param = {
> + .function = lr->function, .file = lr->file,
> + .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
> + struct dwarf_callback_param line_range_param = {
> + .data = (void *)&lf, .retval = 0};
> +
> + dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
> + if (pubname_param.found) {
> + line_range_search_cb(&lf.sp_die, &line_range_param);
> + if (lf.found)
> + goto found;
> + }
> + }
> +
> /* Loop on CUs (Compilation Unit) */
> while (!lf.found && ret >= 0) {
> if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
> @@ -1923,6 +1990,7 @@ int find_line_range(int fd, struct line_range *lr)
> off = noff;
> }
>
> +found:
> /* Store comp_dir */
> if (lf.found) {
> comp_dir = cu_get_comp_dir(&lf.cu_die);
> diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
> index beaefc3..605730a 100644
> --- a/tools/perf/util/probe-finder.h
> +++ b/tools/perf/util/probe-finder.h
> @@ -49,6 +49,7 @@ struct probe_finder {
> Dwarf_Addr addr; /* Address */
> const char *fname; /* Real file name */
> Dwarf_Die cu_die; /* Current CU */
> + Dwarf_Die sp_die;
> struct list_head lcache; /* Line cache for lazy match */
>
> /* For variable searching */
> @@ -83,6 +84,7 @@ struct line_finder {
> int lno_s; /* Start line number */
> int lno_e; /* End line number */
> Dwarf_Die cu_die; /* Current CU */
> + Dwarf_Die sp_die;
> int found;
> };
>
--
Masami HIRAMATSU
2nd Dept. Linux Technology Center
Hitachi, Ltd., Systems Development Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com
^ permalink raw reply [flat|nested] 3+ messages in thread* [tip:perf/core] perf probe: Add fastpath to do lookup by function name
2011-03-25 8:27 [PATCH -tip v3] perf probe: Add fastpath to do lookup by function name Lin Ming
2011-03-28 1:02 ` Masami Hiramatsu
@ 2011-03-30 7:16 ` tip-bot for Lin Ming
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Lin Ming @ 2011-03-30 7:16 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, hpa, mingo, a.p.zijlstra, masami.hiramatsu.pt,
ming.m.lin, tglx, mingo
Commit-ID: cd25f8bc2696664877b21d33b7994e12fa570919
Gitweb: http://git.kernel.org/tip/cd25f8bc2696664877b21d33b7994e12fa570919
Author: Lin Ming <ming.m.lin@intel.com>
AuthorDate: Fri, 25 Mar 2011 16:27:48 +0800
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 29 Mar 2011 13:40:27 -0300
perf probe: Add fastpath to do lookup by function name
v3 -> v2:
- Make pubname_search_cb more generic
- Add fastpath to find_probes also
v2 -> v1:
- Don't compare file names with cu_find_realpath(...), instead, compare
them with the name returned by dwarf_decl_file(sp_die)
The vmlinux file may have thousands of CUs.
We can lookup function name from .debug_pubnames section
to avoid the slow loop on CUs.
1. Improvement data for find_line_range
./perf stat -e cycles -r 10 -- ./perf probe -k /home/mlin/vmlinux \
-s /home/mlin/linux-2.6 \
--line csum_partial_copy_to_user > tmp.log
before patch applied
=====================
847,988,276 cycles
0.355075856 seconds time elapsed
after patch applied
=====================
206,102,622 cycles
0.086883555 seconds time elapsed
2. Improvement data for find_probes
./perf stat -e cycles -r 10 -- ./perf probe -k /home/mlin/vmlinux \
-s /home/mlin/linux-2.6 \
--vars csum_partial_copy_to_user > tmp.log
before patch applied
=====================
848,490,844 cycles
0.355307901 seconds time elapsed
after patch applied
=====================
205,684,469 cycles
0.086694010 seconds time elapsed
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: linux-kernel <linux-kernel@vger.kernel.org>
LKML-Reference: <1301041668.14111.52.camel@minggr.sh.intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/probe-finder.c | 72 ++++++++++++++++++++++++++++++++++++++++
tools/perf/util/probe-finder.h | 2 +
2 files changed, 74 insertions(+), 0 deletions(-)
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 194f9e2..ff416b8 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1435,6 +1435,38 @@ static int find_probe_point_by_func(struct probe_finder *pf)
return _param.retval;
}
+struct pubname_callback_param {
+ char *function;
+ char *file;
+ Dwarf_Die *cu_die;
+ Dwarf_Die *sp_die;
+ int found;
+};
+
+static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
+{
+ struct pubname_callback_param *param = data;
+
+ if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
+ if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
+ return DWARF_CB_OK;
+
+ if (die_compare_name(param->sp_die, param->function)) {
+ if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
+ return DWARF_CB_OK;
+
+ if (param->file &&
+ strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
+ return DWARF_CB_OK;
+
+ param->found = 1;
+ return DWARF_CB_ABORT;
+ }
+ }
+
+ return DWARF_CB_OK;
+}
+
/* Find probe points from debuginfo */
static int find_probes(int fd, struct probe_finder *pf)
{
@@ -1461,6 +1493,27 @@ static int find_probes(int fd, struct probe_finder *pf)
off = 0;
line_list__init(&pf->lcache);
+
+ /* Fastpath: lookup by function name from .debug_pubnames section */
+ if (pp->function) {
+ struct pubname_callback_param pubname_param = {
+ .function = pp->function,
+ .file = pp->file,
+ .cu_die = &pf->cu_die,
+ .sp_die = &pf->sp_die,
+ };
+ struct dwarf_callback_param probe_param = {
+ .data = pf,
+ };
+
+ dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
+ if (pubname_param.found) {
+ ret = probe_point_search_cb(&pf->sp_die, &probe_param);
+ if (ret)
+ goto found;
+ }
+ }
+
/* Loop on CUs (Compilation Unit) */
while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
/* Get the DIE(Debugging Information Entry) of this CU */
@@ -1488,6 +1541,8 @@ static int find_probes(int fd, struct probe_finder *pf)
}
off = noff;
}
+
+found:
line_list__free(&pf->lcache);
if (dwfl)
dwfl_end(dwfl);
@@ -1895,6 +1950,22 @@ int find_line_range(int fd, struct line_range *lr)
return -EBADF;
}
+ /* Fastpath: lookup by function name from .debug_pubnames section */
+ if (lr->function) {
+ struct pubname_callback_param pubname_param = {
+ .function = lr->function, .file = lr->file,
+ .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
+ struct dwarf_callback_param line_range_param = {
+ .data = (void *)&lf, .retval = 0};
+
+ dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
+ if (pubname_param.found) {
+ line_range_search_cb(&lf.sp_die, &line_range_param);
+ if (lf.found)
+ goto found;
+ }
+ }
+
/* Loop on CUs (Compilation Unit) */
while (!lf.found && ret >= 0) {
if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
@@ -1923,6 +1994,7 @@ int find_line_range(int fd, struct line_range *lr)
off = noff;
}
+found:
/* Store comp_dir */
if (lf.found) {
comp_dir = cu_get_comp_dir(&lf.cu_die);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index beaefc3..605730a 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -49,6 +49,7 @@ struct probe_finder {
Dwarf_Addr addr; /* Address */
const char *fname; /* Real file name */
Dwarf_Die cu_die; /* Current CU */
+ Dwarf_Die sp_die;
struct list_head lcache; /* Line cache for lazy match */
/* For variable searching */
@@ -83,6 +84,7 @@ struct line_finder {
int lno_s; /* Start line number */
int lno_e; /* End line number */
Dwarf_Die cu_die; /* Current CU */
+ Dwarf_Die sp_die;
int found;
};
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-03-30 7:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-25 8:27 [PATCH -tip v3] perf probe: Add fastpath to do lookup by function name Lin Ming
2011-03-28 1:02 ` Masami Hiramatsu
2011-03-30 7:16 ` [tip:perf/core] " tip-bot for Lin Ming
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.