Re: [PATCH v2 4/5] perf: kretprobes: offset from reloc_sym if kernel supports it

From: Masami Hiramatsu
Date: Thu Feb 23 2017 - 04:12:05 EST


On Wed, 22 Feb 2017 19:23:40 +0530
"Naveen N. Rao" <naveen.n.rao@xxxxxxxxxxxxxxxxxx> wrote:

> We indicate support for accepting sym+offset with kretprobes through a
> line in ftrace README. Parse the same to identify support and choose the
> appropriate format for kprobe_events.
>
> Signed-off-by: Naveen N. Rao <naveen.n.rao@xxxxxxxxxxxxxxxxxx>
> ---
> tools/perf/util/probe-event.c | 47 ++++++++++++++++++++++++++++++++++++-------
> tools/perf/util/probe-event.h | 2 ++
> 2 files changed, 42 insertions(+), 7 deletions(-)
>
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 35f5b7b7715c..f6bc61c47271 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -737,6 +737,41 @@ post_process_module_probe_trace_events(struct probe_trace_event *tevs,
> return ret;
> }
>
> +bool is_kretprobe_offset_supported(void)
> +{
> + FILE *fp;
> + char *buf = NULL;
> + size_t len = 0;
> + bool target_line = false;
> + static int supported = -1;
> +
> + if (supported >= 0)
> + return !!supported;
> +
> + if (asprintf(&buf, "%s/README", tracing_path) < 0)
> + return false;
> +
> + fp = fopen(buf, "r");
> + if (!fp)
> + goto end;
> +
> + zfree(&buf);
> + while (getline(&buf, &len, fp) > 0) {
> + target_line = !!strstr(buf, "place (kretprobe): ");
> + if (!target_line)
> + continue;
> + supported = 1;
> + }
> + if (supported == -1)
> + supported = 0;
> +
> + fclose(fp);
> +end:
> + free(buf);
> +
> + return !!supported;
> +}

Could you reuse (refactoring) probe_type_is_available() in probe-file.c to share
opening README file?

Others looks good to me :)

Thank you,

> +
> static int
> post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
> int ntevs)
> @@ -757,7 +792,9 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
> }
>
> for (i = 0; i < ntevs; i++) {
> - if (!tevs[i].point.address || tevs[i].point.retprobe)
> + if (!tevs[i].point.address)
> + continue;
> + if (tevs[i].point.retprobe && !is_kretprobe_offset_supported())
> continue;
> /* If we found a wrong one, mark it by NULL symbol */
> if (kprobe_warn_out_range(tevs[i].point.symbol,
> @@ -1528,11 +1565,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> return -EINVAL;
> }
>
> - if (pp->retprobe && !pp->function) {
> - semantic_error("Return probe requires an entry function.\n");
> - return -EINVAL;
> - }
> -
> if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
> semantic_error("Offset/Line/Lazy pattern can't be used with "
> "return probe.\n");
> @@ -2841,7 +2873,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
> }
>
> /* Note that the symbols in the kmodule are not relocated */
> - if (!pev->uprobes && !pp->retprobe && !pev->target) {
> + if (!pev->uprobes && !pev->target &&
> + (!pp->retprobe || is_kretprobe_offset_supported())) {
> reloc_sym = kernel_get_ref_reloc_sym();
> if (!reloc_sym) {
> pr_warning("Relocated base symbol is not found!\n");
> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> index 5d4e94061402..449d4f311355 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -135,6 +135,8 @@ bool perf_probe_with_var(struct perf_probe_event *pev);
> /* Check the perf_probe_event needs debuginfo */
> bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
>
> +bool is_kretprobe_offset_supported(void);
> +
> /* Release event contents */
> void clear_perf_probe_event(struct perf_probe_event *pev);
> void clear_probe_trace_event(struct probe_trace_event *tev);
> --
> 2.11.0
>


--
Masami Hiramatsu <mhiramat@xxxxxxxxxx>