linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/4] perf inject --jit: Remove //anon mmap events
@ 2019-09-28  1:45 Steve MacLean
  2019-09-29 15:29 ` Jiri Olsa
  0 siblings, 1 reply; 7+ messages in thread
From: Steve MacLean @ 2019-09-28  1:45 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim
  Cc: Eric Saint-Etienne, John Keeping, Andi Kleen, Song Liu,
	Davidlohr Bueso, Leo Yan, linux-kernel, Brian Robbins,
	Tom McDonald, John Salem, Stephane Eranian

While a JIT is jitting code it will eventually need to commit more pages and
change these pages to executable permissions.

Typically the JIT will want these co-located to minimize branch displacements.

The kernel will coalesce these anonymous mapping with identical permissions
before sending an mmap event for the new pages. This means the mmap event for
the new pages will include the older pages.

These anonymous mmap events will obscure the jitdump injected pseudo events.
This means that the jitdump generated symbols, machine code, debugging info,
and unwind info will no longer be used.

Observations:

When a process emits a jit dump marker and a jitdump file, the perf-xxx.map
file represents inferior information which has been superseded by the
jitdump jit-xxx.dump file.

Further the '//anon*' mmap events are only required for the legacy
perf-xxx.map mapping.

Summary:

Add rbtree to track which pids have successfully injected a jitdump file.

During "perf inject --jit", discard "//anon*" mmap events for any pid which
has successfully processed a jitdump file.

Committer testing:

// jitdump case
perf record <app with jitdump>
perf inject --jit --input perf.data --output perfjit.data

// verify mmap "//anon" events present initially
perf script --input perf.data --show-mmap-events | grep '//anon'
// verify mmap "//anon" events removed
perf script --input perfjit.data --show-mmap-events | grep '//anon'

// no jitdump case
perf record <app without jitdump>
perf inject --jit --input perf.data --output perfjit.data

// verify mmap "//anon" events present initially
perf script --input perf.data --show-mmap-events | grep '//anon'
// verify mmap "//anon" events not removed
perf script --input perfjit.data --show-mmap-events | grep '//anon'

Repro:

This issue was discovered while testing the initial CoreCLR jitdump
implementation. https://github.com/dotnet/coreclr/pull/26897.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Steve MacLean <Steve.MacLean@Microsoft.com>
---
 tools/perf/builtin-inject.c |  4 +--
 tools/perf/util/jitdump.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 372ecb3..0f38862 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -263,7 +263,7 @@ static int perf_event__jit_repipe_mmap(struct perf_tool *tool,
         * if jit marker, then inject jit mmaps and generate ELF images
         */
        ret = jit_process(inject->session, &inject->output, machine,
-                         event->mmap.filename, sample->pid, &n);
+                         event->mmap.filename, event->mmap.pid, &n);
        if (ret < 0)
                return ret;
        if (ret) {
@@ -301,7 +301,7 @@ static int perf_event__jit_repipe_mmap2(struct perf_tool *tool,
         * if jit marker, then inject jit mmaps and generate ELF images
         */
        ret = jit_process(inject->session, &inject->output, machine,
-                         event->mmap2.filename, sample->pid, &n);
+                         event->mmap2.filename, event->mmap2.pid, &n);
        if (ret < 0)
                return ret;
        if (ret) {
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index e3ccb0c..6d891d1 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -749,6 +749,59 @@ jit_detect(char *mmap_name, pid_t pid)
        return 0;
 }
 
+struct pid_rbtree
+{
+       struct rb_node node;
+       pid_t pid;
+};
+
+static void jit_add_pid(struct rb_root *root, pid_t pid)
+{
+       struct rb_node **new = &(root->rb_node), *parent = NULL;
+       struct pid_rbtree* data = NULL;
+
+       /* Figure out where to put new node */
+       while (*new) {
+               struct pid_rbtree *this = container_of(*new, struct pid_rbtree, node);
+               pid_t nodePid = this->pid;
+
+               parent = *new;
+               if (pid < nodePid)
+                       new = &((*new)->rb_left);
+               else if (pid > nodePid)
+                       new = &((*new)->rb_right);
+               else
+                       return;
+       }
+
+       data = malloc(sizeof(struct pid_rbtree));
+       data->pid = pid;
+
+       /* Add new node and rebalance tree. */
+       rb_link_node(&data->node, parent, new);
+       rb_insert_color(&data->node, root);
+
+       return;
+}
+
+static bool jit_has_pid(struct rb_root *root, pid_t pid)
+{
+       struct rb_node *node = root->rb_node;
+
+       while (node) {
+               struct pid_rbtree *this = container_of(node, struct pid_rbtree, node);
+               pid_t nodePid = this->pid;
+
+               if (pid < nodePid)
+                       node = node->rb_left;
+               else if (pid > nodePid)
+                       node = node->rb_right;
+               else
+                       return 1;
+       }
+       return 0;
+}
+
 int
 jit_process(struct perf_session *session,
            struct perf_data *output,
@@ -760,12 +813,21 @@ jit_process(struct perf_session *session,
        struct evsel *first;
        struct jit_buf_desc jd;
        int ret;
+       static struct rb_root jitdump_pids = RB_ROOT;
 
        /*
         * first, detect marker mmap (i.e., the jitdump mmap)
         */
        if (jit_detect(filename, pid))
+       {
+               /*
+                * Strip //anon* mmaps if we processed a jitdump for this pid
+                */
+               if (jit_has_pid(&jitdump_pids, pid) && (strncmp(filename, "//anon", 6) == 0))
+                       return 1;
+
                return 0;
+       }
 
        memset(&jd, 0, sizeof(jd));
 
@@ -784,6 +846,7 @@ jit_process(struct perf_session *session,
 
        ret = jit_inject(&jd, filename);
        if (!ret) {
+               jit_add_pid(&jitdump_pids, pid);
                *nbytes = jd.bytes_written;
                ret = 1;
        }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/4] perf inject --jit: Remove //anon mmap events
  2019-09-28  1:45 [PATCH 3/4] perf inject --jit: Remove //anon mmap events Steve MacLean
@ 2019-09-29 15:29 ` Jiri Olsa
  2019-09-30 20:49   ` Steve MacLean
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Olsa @ 2019-09-29 15:29 UTC (permalink / raw)
  To: Steve MacLean
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Mark Rutland, Alexander Shishkin, Namhyung Kim,
	Eric Saint-Etienne, John Keeping, Andi Kleen, Song Liu,
	Davidlohr Bueso, Leo Yan, linux-kernel, Brian Robbins,
	Tom McDonald, John Salem, Stephane Eranian

On Sat, Sep 28, 2019 at 01:45:36AM +0000, Steve MacLean wrote:
> While a JIT is jitting code it will eventually need to commit more pages and
> change these pages to executable permissions.
> 
> Typically the JIT will want these co-located to minimize branch displacements.
> 
> The kernel will coalesce these anonymous mapping with identical permissions
> before sending an mmap event for the new pages. This means the mmap event for
> the new pages will include the older pages.
> 
> These anonymous mmap events will obscure the jitdump injected pseudo events.
> This means that the jitdump generated symbols, machine code, debugging info,
> and unwind info will no longer be used.
> 
> Observations:
> 
> When a process emits a jit dump marker and a jitdump file, the perf-xxx.map
> file represents inferior information which has been superseded by the
> jitdump jit-xxx.dump file.
> 
> Further the '//anon*' mmap events are only required for the legacy
> perf-xxx.map mapping.
> 
> Summary:
> 
> Add rbtree to track which pids have successfully injected a jitdump file.
> 
> During "perf inject --jit", discard "//anon*" mmap events for any pid which
> has successfully processed a jitdump file.
> 
> Committer testing:
> 
> // jitdump case
> perf record <app with jitdump>
> perf inject --jit --input perf.data --output perfjit.data
> 
> // verify mmap "//anon" events present initially
> perf script --input perf.data --show-mmap-events | grep '//anon'
> // verify mmap "//anon" events removed
> perf script --input perfjit.data --show-mmap-events | grep '//anon'
> 
> // no jitdump case
> perf record <app without jitdump>
> perf inject --jit --input perf.data --output perfjit.data
> 
> // verify mmap "//anon" events present initially
> perf script --input perf.data --show-mmap-events | grep '//anon'
> // verify mmap "//anon" events not removed
> perf script --input perfjit.data --show-mmap-events | grep '//anon'
> 
> Repro:
> 
> This issue was discovered while testing the initial CoreCLR jitdump
> implementation. https://github.com/dotnet/coreclr/pull/26897.

I can't apply this one:

patching file builtin-inject.c
Hunk #1 FAILED at 263.
1 out of 1 hunk FAILED -- saving rejects to file builtin-inject.c.rej
patching file util/jitdump.c
patch: **** malformed patch at line 236: btree, node);

jirka

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH 3/4] perf inject --jit: Remove //anon mmap events
  2019-09-29 15:29 ` Jiri Olsa
@ 2019-09-30 20:49   ` Steve MacLean
  2019-10-01  2:20     ` Andi Kleen
  0 siblings, 1 reply; 7+ messages in thread
From: Steve MacLean @ 2019-09-30 20:49 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Mark Rutland, Alexander Shishkin, Namhyung Kim,
	Eric Saint-Etienne, John Keeping, Andi Kleen, Song Liu,
	Davidlohr Bueso, Leo Yan, linux-kernel, Brian Robbins,
	Tom McDonald, John Salem, Stephane Eranian

SNIP

> I can't apply this one:

> patching file builtin-inject.c
> Hunk #1 FAILED at 263.
> 1 out of 1 hunk FAILED -- saving rejects to file builtin-inject.c.rej 

I assume this is because I based my patches on the wrong tip.

> patching file util/jitdump.c
> patch: **** malformed patch at line 236: btree, node);

This doesn't make sense to me.  The patch doesn't try to inject near line 236. There aren't 236 lines in the e-mail....

Looking at the MAINTAINERS file, it looks like I should have based my changes on:
	git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core

I'll rebase the patch and resend.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/4] perf inject --jit: Remove //anon mmap events
  2019-09-30 20:49   ` Steve MacLean
@ 2019-10-01  2:20     ` Andi Kleen
  0 siblings, 0 replies; 7+ messages in thread
From: Andi Kleen @ 2019-10-01  2:20 UTC (permalink / raw)
  To: Steve MacLean
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Mark Rutland, Alexander Shishkin, Namhyung Kim,
	Eric Saint-Etienne, John Keeping, Song Liu, Davidlohr Bueso,
	Leo Yan, linux-kernel, Brian Robbins, Tom McDonald, John Salem,
	Stephane Eranian

On Mon, Sep 30, 2019 at 08:49:00PM +0000, Steve MacLean wrote:
> SNIP
> 
> > I can't apply this one:
> 
> > patching file builtin-inject.c
> > Hunk #1 FAILED at 263.
> > 1 out of 1 hunk FAILED -- saving rejects to file builtin-inject.c.rej 
> 
> I assume this is because I based my patches on the wrong tip.
> 
> > patching file util/jitdump.c
> > patch: **** malformed patch at line 236: btree, node);
> 
> This doesn't make sense to me.  The patch doesn't try to inject near line 236. There aren't 236 lines in the e-mail....

Most likely your mail client did line wrap.

See Documentation/process/email-clients.rst

-Andi

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH 3/4] perf inject --jit: Remove //anon mmap events
  2019-10-03 10:57 ` Jiri Olsa
@ 2019-10-30  3:10   ` Steve MacLean
  0 siblings, 0 replies; 7+ messages in thread
From: Steve MacLean @ 2019-10-30  3:10 UTC (permalink / raw)
  To: Jiri Olsa, Steve MacLean
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Namhyung Kim, Stephane Eranian,
	linux-kernel

> anyway, I wonder if you could just use thread::priv flag for that, like:
>
>  thread = machine__findnew_thread(machine, pid, pid);
>  if (!thread)
>    bad
>
>  (int) thread->priv = 1;
>
> and check on thread->priv when ruling the pid out, should be faster then maintain rb tree
>
> thanks,
> jirka

I agree reusing the existing data structure is a better approach. I have drafted a change reusing the void* priv field. It seems looks like it is currently safe to use during perf inject.

I will test it tomorrow then send the new patch

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/4] perf inject --jit: Remove //anon mmap events
  2019-10-02 20:58 Steve MacLean
@ 2019-10-03 10:57 ` Jiri Olsa
  2019-10-30  3:10   ` Steve MacLean
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Olsa @ 2019-10-03 10:57 UTC (permalink / raw)
  To: Steve MacLean
  Cc: Steve MacLean, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Namhyung Kim, Stephane Eranian, linux-kernel

On Wed, Oct 02, 2019 at 01:58:21PM -0700, Steve MacLean wrote:
> From: Steve MacLean <Steve.MacLean@Microsoft.com>
> 
> While a JIT is jitting code it will eventually need to commit more pages and
> change these pages to executable permissions.
> 
> Typically the JIT will want these colocated to minimize branch displacements.
> 
> The kernel will coalesce these anonymous mapping with identical permissions
> before sending an MMAP event for the new pages. This means the mmap event for
> the new pages will include the older pages.
> 
> These anonymous mmap events will obscure the jitdump injected pseudo events.
> This means that the jitdump generated symbols, machine code, debugging info,
> and unwind info will no longer be used.
> 
> Observations:
> 
> When a process emits a jit dump marker and a jitdump file, the perf-xxx.map
> file represents inferior information which has been superseded by the
> jitdump jit-xxx.dump file.
> 
> Further the '//anon*' mmap events are only required for the legacy
> perf-xxx.map mapping.

it's been some time I saw the code, Stephane?

I added some comments below

> 
> Summary:
> 
> Add rbtree to track which pids have successfully injected a jitdump file.
> 
> During "perf inject --jit", discard "//anon*" mmap events for any pid which
> has successfully processed a jitdump file.
> 
> Committer testing:
> 
> // jitdump case
> perf record <app with jitdump>
> perf inject --jit --input perf.data --output perfjit.data
> 
> // verify mmap "//anon" events present initially
> perf script --input perf.data --show-mmap-events | grep '//anon'
> // verify mmap "//anon" events removed
> perf script --input perfjit.data --show-mmap-events | grep '//anon'
> 
> // no jitdump case
> perf record <app without jitdump>
> perf inject --jit --input perf.data --output perfjit.data
> 
> // verify mmap "//anon" events present initially
> perf script --input perf.data --show-mmap-events | grep '//anon'
> // verify mmap "//anon" events not removed
> perf script --input perfjit.data --show-mmap-events | grep '//anon'
> 
> Repro:
> 
> This issue was discovered while testing the initial CoreCLR jitdump
> implementation. https://github.com/dotnet/coreclr/pull/26897.
> 
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Stephane Eranian <eranian@google.com>
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Steve MacLean <Steve.MacLean@Microsoft.com>
> ---
>  tools/perf/builtin-inject.c |  4 +--
>  tools/perf/util/jitdump.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 65 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
> index c14f40b8..4c921e0 100644
> --- a/tools/perf/builtin-inject.c
> +++ b/tools/perf/builtin-inject.c
> @@ -261,7 +261,7 @@ static int perf_event__jit_repipe_mmap(struct perf_tool *tool,
>  	 * if jit marker, then inject jit mmaps and generate ELF images
>  	 */
>  	ret = jit_process(inject->session, &inject->output, machine,
> -			  event->mmap.filename, sample->pid, &n);
> +			  event->mmap.filename, event->mmap.pid, &n);
>  	if (ret < 0)
>  		return ret;
>  	if (ret) {
> @@ -299,7 +299,7 @@ static int perf_event__jit_repipe_mmap2(struct perf_tool *tool,
>  	 * if jit marker, then inject jit mmaps and generate ELF images
>  	 */
>  	ret = jit_process(inject->session, &inject->output, machine,
> -			  event->mmap2.filename, sample->pid, &n);
> +			  event->mmap2.filename, event->mmap2.pid, &n);
>  	if (ret < 0)
>  		return ret;
>  	if (ret) {
> diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
> index 22d09c4..6a1563f 100644
> --- a/tools/perf/util/jitdump.c
> +++ b/tools/perf/util/jitdump.c
> @@ -751,6 +751,59 @@ static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr)
>  	return 0;
>  }
>  
> +struct pid_rbtree
> +{
> +	struct rb_node node;
> +	pid_t pid;
> +};
> +
> +static void jit_add_pid(struct rb_root *root, pid_t pid)
> +{
> +	struct rb_node **new = &(root->rb_node), *parent = NULL;

we don't use the parenthesis like that

> +	struct pid_rbtree* data = NULL;
> +
> +	/* Figure out where to put new node */
> +	while (*new) {
> +		struct pid_rbtree *this = container_of(*new, struct pid_rbtree, node);

there's rb_entry macro for this

> +		pid_t nodePid = this->pid;
> +
> +		parent = *new;
> +		if (pid < nodePid)
> +			new = &((*new)->rb_left);
> +		else if (pid > nodePid)
> +			new = &((*new)->rb_right);
> +		else
> +			return;
> +	}
> +
> +	data = malloc(sizeof(struct pid_rbtree));

plz check every allocation

anyway, I wonder if you could just use thread::priv flag for that, like:

  thread = machine__findnew_thread(machine, pid, pid);
  if (!thread)
    bad

  (int) thread->priv = 1;

and check on thread->priv when ruling the pid out, should be faster
then maintain rb tree

thanks,
jirka

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/4] perf inject --jit: Remove //anon mmap events
@ 2019-10-02 20:58 Steve MacLean
  2019-10-03 10:57 ` Jiri Olsa
  0 siblings, 1 reply; 7+ messages in thread
From: Steve MacLean @ 2019-10-02 20:58 UTC (permalink / raw)
  Cc: Steve MacLean, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Stephane Eranian, linux-kernel

From: Steve MacLean <Steve.MacLean@Microsoft.com>

While a JIT is jitting code it will eventually need to commit more pages and
change these pages to executable permissions.

Typically the JIT will want these colocated to minimize branch displacements.

The kernel will coalesce these anonymous mapping with identical permissions
before sending an MMAP event for the new pages. This means the mmap event for
the new pages will include the older pages.

These anonymous mmap events will obscure the jitdump injected pseudo events.
This means that the jitdump generated symbols, machine code, debugging info,
and unwind info will no longer be used.

Observations:

When a process emits a jit dump marker and a jitdump file, the perf-xxx.map
file represents inferior information which has been superseded by the
jitdump jit-xxx.dump file.

Further the '//anon*' mmap events are only required for the legacy
perf-xxx.map mapping.

Summary:

Add rbtree to track which pids have successfully injected a jitdump file.

During "perf inject --jit", discard "//anon*" mmap events for any pid which
has successfully processed a jitdump file.

Committer testing:

// jitdump case
perf record <app with jitdump>
perf inject --jit --input perf.data --output perfjit.data

// verify mmap "//anon" events present initially
perf script --input perf.data --show-mmap-events | grep '//anon'
// verify mmap "//anon" events removed
perf script --input perfjit.data --show-mmap-events | grep '//anon'

// no jitdump case
perf record <app without jitdump>
perf inject --jit --input perf.data --output perfjit.data

// verify mmap "//anon" events present initially
perf script --input perf.data --show-mmap-events | grep '//anon'
// verify mmap "//anon" events not removed
perf script --input perfjit.data --show-mmap-events | grep '//anon'

Repro:

This issue was discovered while testing the initial CoreCLR jitdump
implementation. https://github.com/dotnet/coreclr/pull/26897.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Steve MacLean <Steve.MacLean@Microsoft.com>
---
 tools/perf/builtin-inject.c |  4 +--
 tools/perf/util/jitdump.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index c14f40b8..4c921e0 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -261,7 +261,7 @@ static int perf_event__jit_repipe_mmap(struct perf_tool *tool,
 	 * if jit marker, then inject jit mmaps and generate ELF images
 	 */
 	ret = jit_process(inject->session, &inject->output, machine,
-			  event->mmap.filename, sample->pid, &n);
+			  event->mmap.filename, event->mmap.pid, &n);
 	if (ret < 0)
 		return ret;
 	if (ret) {
@@ -299,7 +299,7 @@ static int perf_event__jit_repipe_mmap2(struct perf_tool *tool,
 	 * if jit marker, then inject jit mmaps and generate ELF images
 	 */
 	ret = jit_process(inject->session, &inject->output, machine,
-			  event->mmap2.filename, sample->pid, &n);
+			  event->mmap2.filename, event->mmap2.pid, &n);
 	if (ret < 0)
 		return ret;
 	if (ret) {
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index 22d09c4..6a1563f 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -751,6 +751,59 @@ static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr)
 	return 0;
 }
 
+struct pid_rbtree
+{
+	struct rb_node node;
+	pid_t pid;
+};
+
+static void jit_add_pid(struct rb_root *root, pid_t pid)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+	struct pid_rbtree* data = NULL;
+
+	/* Figure out where to put new node */
+	while (*new) {
+		struct pid_rbtree *this = container_of(*new, struct pid_rbtree, node);
+		pid_t nodePid = this->pid;
+
+		parent = *new;
+		if (pid < nodePid)
+			new = &((*new)->rb_left);
+		else if (pid > nodePid)
+			new = &((*new)->rb_right);
+		else
+			return;
+	}
+
+	data = malloc(sizeof(struct pid_rbtree));
+	data->pid = pid;
+
+	/* Add new node and rebalance tree. */
+	rb_link_node(&data->node, parent, new);
+	rb_insert_color(&data->node, root);
+
+	return;
+}
+
+static bool jit_has_pid(struct rb_root *root, pid_t pid)
+{
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct pid_rbtree *this = container_of(node, struct pid_rbtree, node);
+		pid_t nodePid = this->pid;
+
+		if (pid < nodePid)
+			node = node->rb_left;
+		else if (pid > nodePid)
+			node = node->rb_right;
+		else
+			return 1;
+	}
+	return 0;
+}
+
 int
 jit_process(struct perf_session *session,
 	    struct perf_data *output,
@@ -762,12 +815,21 @@ static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr)
 	struct evsel *first;
 	struct jit_buf_desc jd;
 	int ret;
+	static struct rb_root jitdump_pids = RB_ROOT;
 
 	/*
 	 * first, detect marker mmap (i.e., the jitdump mmap)
 	 */
 	if (jit_detect(filename, pid))
+	{
+		/*
+		 * Strip //anon* mmaps if we processed a jitdump for this pid
+		 */
+		if (jit_has_pid(&jitdump_pids, pid) && (strncmp(filename, "//anon", 6) == 0))
+			return 1;
+
 		return 0;
+	}
 
 	memset(&jd, 0, sizeof(jd));
 
@@ -786,6 +848,7 @@ static int jit_repipe_debug_info(struct jit_buf_desc *jd, union jr_entry *jr)
 
 	ret = jit_inject(&jd, filename);
 	if (!ret) {
+		jit_add_pid(&jitdump_pids, pid);
 		*nbytes = jd.bytes_written;
 		ret = 1;
 	}
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-10-30  3:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-28  1:45 [PATCH 3/4] perf inject --jit: Remove //anon mmap events Steve MacLean
2019-09-29 15:29 ` Jiri Olsa
2019-09-30 20:49   ` Steve MacLean
2019-10-01  2:20     ` Andi Kleen
2019-10-02 20:58 Steve MacLean
2019-10-03 10:57 ` Jiri Olsa
2019-10-30  3:10   ` Steve MacLean

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).