Skip to content

Commit

Permalink
perf inject --jit: Remove //anon mmap events
Browse files Browse the repository at this point in the history
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 superceded by the
jitdump jit-xxx.dump file.

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

When attaching to an existing process, the synthetic anon map events are
given a time stamp of -1. These should not obscure the jitdump events which
have an actual time.

Summary:

Use thread->priv to store whether a jitdump file has been processed

During "perf inject --jit", discard "//anon*" mmap events for any pid which
has sucessfully 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. dotnet/coreclr#26897.

Signed-off-by: Steve MacLean <[email protected]>
  • Loading branch information
DanielShaulov committed May 5, 2020
1 parent ba17920 commit ce37bc5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
4 changes: 2 additions & 2 deletions tools/perf/builtin-inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,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) {
Expand Down Expand Up @@ -330,7 +330,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) {
Expand Down
38 changes: 38 additions & 0 deletions tools/perf/util/jitdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "jit.h"
#include "jitdump.h"
#include "genelf.h"
#include "thread.h"

#include <linux/ctype.h>
#include <linux/zalloc.h>
Expand Down Expand Up @@ -749,6 +750,34 @@ jit_detect(char *mmap_name, pid_t pid)
return 0;
}

static void jit_add_pid(struct machine *machine, pid_t pid)
{
struct thread *thread = machine__findnew_thread(machine, pid, pid);

if (!thread)
{
pr_err("jit_add_pid() thread not found\n");

return;
}

thread->priv = (void *) 1;
}

static bool jit_has_pid(struct machine *machine, pid_t pid)
{
struct thread *thread = machine__findnew_thread(machine, pid, pid);

if (!thread)
{
pr_err("jit_has_pid() thread not found\n");

return 0;
}

return (bool) thread->priv;
}

int
jit_process(struct perf_session *session,
struct perf_data *output,
Expand All @@ -765,7 +794,15 @@ jit_process(struct perf_session *session,
* 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(machine, pid) && (strncmp(filename, "//anon", 6) == 0))
return 1;

return 0;
}

memset(&jd, 0, sizeof(jd));

Expand All @@ -784,6 +821,7 @@ jit_process(struct perf_session *session,

ret = jit_inject(&jd, filename);
if (!ret) {
jit_add_pid(machine, pid);
*nbytes = jd.bytes_written;
ret = 1;
}
Expand Down

0 comments on commit ce37bc5

Please sign in to comment.