All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: "Wangnan (F)" <wangnan0@huawei.com>
To: Hou Pengyang <houpengyang@huawei.com>, <acme@kernel.org>,
	<mingo@redhat.com>, <namhyung@kernel.org>,
	<a.p.zijlstra@chello.nl>
Cc: <linux-kernel@vger.kernel.org>
Subject: Re: [RFC] perf report: introduce --map-anon-mem for anon-executable-memory symbols parsing
Date: Fri, 19 Jun 2015 17:27:36 +0800	[thread overview]
Message-ID: <5583E088.6080202@huawei.com> (raw)
In-Reply-To: <1434636076-13502-1-git-send-email-houpengyang@huawei.com>



On 2015/6/18 22:01, Hou Pengyang wrote:
> This patch introduces a --map-anon-mem argument to perf report to deal
> with anon-executable-memory symbol parsing.

--map-anon-mem is not a good name. The user defined map area list
introduced in this patch can be used on not only anon mapping but
also file mapping.

>
> Sometimes, we mmap() executable memory area, and copy some '.so' or '.o'
> files to the area, and then do the relocation and code fixing to make the
> code work well. However, perf could not parse symbol info in those files,
> since the memory area is not file-backended.
>
> The problem was first discussed in :
>      https://lkml.org/lkml/2015/4/1/203
>
> In this discussion, we finally preferred to something like 'perf inject'
> to inject fake mmap events into perf.data. However, for embeded system
> whose space is limited, it's not so wise to make another big perf.data
> by 'perf inject'. So we still adopt the previous solution: introduce
> '--map-anon-mem' argument and let user directly hint perf-report about
> the private mapping info.
>
> The content of this patch:
>   1) A new field mapping_strlist is introduced to struct report, in order
>      to store --map-anon-mem string for afterwards parsing.
>   2) A new field maps_anon is introduced to struct map_groups. maps_anon is used
>   	to store the maps user defines directly for anon-mapping. when searching maps
> 	in map_groups, we prefer to the maps stored in maps_anon.
>   3) The main part of this patch resides in builtin-report.c and session.c.
>      the part in builtin-report.c is charge of storing --map-anon-mem string,
>      while the part in session.c parses the string, create maps, and store maps
>      in map_groups->maps_anon.
>
> Here is an example:
>   $ perf report --map-anon-mem=./libtesta.o@257,0x7f864c0000,0x60,0 \
>   				--map-anon-mem=./libtestb.o@257,0x7f864c0060,0x1000,0
>
> Where 257 is the pid and 0x76864c0000 is private map area got through:
>
>      mmap(NULL, 4096 * 4, PROT_EXEC|PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, \
>            -1, 0);
>
> and libtesta.o is copied to [0x7f864c0000,0x7f864c0060),
> 	libtestb.o is copied to [0x7f864c0060,0x7f864c1060).

Please describe how we implement it briefly.

> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> Signed-off-by: Hou Pengyang <houpengyang@huawei.com>
> ---
>   tools/perf/Documentation/perf-report.txt |   8 +++
>   tools/perf/builtin-report.c              |  39 +++++++++++
>   tools/perf/util/map.c                    |   3 +-
>   tools/perf/util/map.h                    |  10 ++-
>   tools/perf/util/session.c                | 117 +++++++++++++++++++++++++++++++
>   tools/perf/util/session.h                |   4 ++
>   6 files changed, 178 insertions(+), 3 deletions(-)
>
[SNIP]
> +
>   int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
>   {
>   	struct perf_session *session;
> @@ -728,6 +755,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
>   	OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
>   			    "Instruction Tracing options",
>   			    itrace_parse_synth_opts),
> +	OPT_CALLBACK_OPTARG(0, "map-anon-mem", &report.mapping_strlist, NULL,
> +			    "objfile@pid,start,length[,offset]",
> +			    "Provide map adjustment hinting",
> +			    append_to_strlist),
>   	OPT_END()
>   	};
>   	struct perf_data_file file = {
> @@ -767,6 +798,14 @@ repeat:
>   	if (session == NULL)
>   		return -1;
>   
> +	if (perf_session__map_anon(session,
> +				      report.mapping_strlist)) {
> +		parse_options_usage(report_usage, options,
> +				    "map-anon-mem", 0);
> +		goto error;
> +	}
> +
> +
>   	if (report.queue_size) {
>   		ordered_events__set_alloc_size(&session->ordered_events,
>   					       report.queue_size);
>
[SNIP]
> +static int
> +__perf_session__map_anon(struct perf_session *session, int pid,
> +			    char *path, u64 addr, u64 length,
> +			    u64 offset)
> +{
> +	struct thread *thread;
> +	struct map *map;
> +	int err = -1;
> +
> +	thread = perf_session__findnew(session, pid);
> +	if (!thread)
> +		return -1;

Here is a problem: if there is a FORK event in perf.data for that thread,
the thread created here will be cleared, the user defined mapping is also
removed.

> +
> +	map = map__new(&session->machines.host, addr, length, offset,
> +		       pid, 0, 0, 0, 0, PROT_READ | PROT_EXEC, 0, path,
> +		       MAP__FUNCTION, thread);
> +	if (!map)
> +		goto out;
> +
> +	maps__fixup_overlappings(&thread->mg->maps_anon, map, stderr);
> +	maps__insert(&thread->mg->maps_anon, map);
> +	map->groups = thread->mg;
> +
> +	err = 0;
> +out:
> +	thread__put(thread);
> +	return err;
> +}
> +
> +int perf_session__map_anon(struct perf_session *session,
> +			      struct strlist *slist)
> +{
> +	struct str_node *node;
> +	int err;
> +
> +	if (!slist)
> +		return 0;
> +
> +	strlist__for_each(node, slist) {
> +		int pid;
> +		u64 addr, length, offset;
> +		const char *map_anon_cmd = node->s;
> +		char path[PATH_MAX];
> +
> +		if (parse_map_anon_mem(map_anon_cmd, path,
> +				      &pid, &addr, &length, &offset))
> +			return -1;
> +
> +		err = __perf_session__map_anon(session,
> +						  pid, path, addr,
> +						  length, offset);
> +		if (err)
> +			return -1;
> +	}
> +
> +	return 0;
> +}
>
[SNIP]


I think splitting this patch into small pieces can make it easier to read:

perf tools: map: Search user defined map area list before areas get from 
perf.data
perf tools: Creat user defined map area list when creating 'struct thread'
perf record: Introduce --custom-map options

Thank you.


  reply	other threads:[~2015-06-19  9:28 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-18 14:01 [RFC] perf report: introduce --map-anon-mem for anon-executable-memory symbols parsing Hou Pengyang
2015-06-19  9:27 ` Wangnan (F) [this message]
2015-06-19 10:42   ` Ingo Molnar
2015-06-19 20:10     ` Arnaldo Carvalho de Melo
2015-06-22 15:22     ` Hou Pengyang
2015-06-22 15:53       ` Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5583E088.6080202@huawei.com \
    --to=wangnan0@huawei.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@kernel.org \
    --cc=houpengyang@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.