Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1349064 > unrolled thread
| Started by | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| First post | 2016-03-03 13:00 +0100 |
| Last post | 2016-03-03 13:00 +0100 |
| Articles | 2 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH 0/8] perf tools: Add Intel PT support for jitdump Adrian Hunter <adrian.hunter@intel.com> - 2016-03-03 13:00 +0100
[PATCH 6/8] perf jit: Add support for using TSC as a timestamp Adrian Hunter <adrian.hunter@intel.com> - 2016-03-03 13:00 +0100
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2016-03-03 13:00 +0100 |
| Subject | [PATCH 0/8] perf tools: Add Intel PT support for jitdump |
| Message-ID | <r8A5c-6Bm-13@gated-at.bofh.it> |
Hi
In order to use Intel PT with jitdump, changes are needed
because Intel PT uses TSC as a timestamp not the monotonic clock.
These patches enable TSC to be used which allows the following
using a simple HelloWorld java app:
perf record -e intel_pt//u -o java.perf.data java -agentpath:/home/ahunter/git/linux-perf/tools/perf/jvmti/libjvmti.so HelloWorldApp
perf inject -i java.perf.data --jit -o java.perf.data.jitted
perf report -i java.perf.data.jitted
perf script -i java.perf.data.jitted | less
Note, there will be some decoder errors because not all the
generated code is reported to the agent.
Lazily, there is also an unrelated patch:
perf tools: Use 64-bit shifts with (TSC) time conversion"
Adrian Hunter (8):
perf inject: Hit all DSOs for AUX data in JIT and other cases
perf session: Simplify tool stubs
perf tools: Add time conversion event
perf jit: Let jit_process() return errors
perf jit: Move clockid validation
perf jit: Add support for using TSC as a timestamp
perf intel-pt/bts: Define JITDUMP_USE_ARCH_TIMESTAMP
perf tools: Use 64-bit shifts with (TSC) time conversion
tools/perf/arch/x86/tests/rdpmc.c | 2 +-
tools/perf/arch/x86/util/intel-bts.c | 5 +++
tools/perf/arch/x86/util/intel-pt.c | 5 +++
tools/perf/arch/x86/util/tsc.c | 31 +++++++++++++++++
tools/perf/builtin-inject.c | 53 ++++++++++++-----------------
tools/perf/builtin-record.c | 15 +++++++++
tools/perf/jvmti/jvmti_agent.c | 43 ++++++++++++++++++++++--
tools/perf/util/event.c | 1 +
tools/perf/util/event.h | 9 +++++
tools/perf/util/jitdump.c | 64 ++++++++++++++++++++++++++++++++----
tools/perf/util/jitdump.h | 3 ++
tools/perf/util/session.c | 46 ++++++++------------------
tools/perf/util/session.h | 1 +
tools/perf/util/tool.h | 1 +
tools/perf/util/tsc.c | 2 +-
tools/perf/util/tsc.h | 10 ++++++
16 files changed, 216 insertions(+), 75 deletions(-)
Regards
Adrian
[toc] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2016-03-03 13:00 +0100 |
| Subject | [PATCH 6/8] perf jit: Add support for using TSC as a timestamp |
| Message-ID | <r8A5e-6Bm-49@gated-at.bofh.it> |
| In reply to | #1349064 |
From: Adrian Hunter <ajhunter@gmail.com>
Intel PT uses TSC as a timestamp, so add support for using TSC
instead of the monotonic clock. Use of TSC is selected by
an environment variable "JITDUMP_USE_ARCH_TIMESTAMP" and flagged
in the jitdump file with flag JITDUMP_FLAGS_ARCH_TIMESTAMP.
Signed-off-by: Adrian Hunter <ajhunter@gmail.com>
---
tools/perf/jvmti/jvmti_agent.c | 43 ++++++++++++++++++++++++++++++++++++++++--
tools/perf/util/jitdump.c | 37 +++++++++++++++++++++++++++++++-----
tools/perf/util/jitdump.h | 3 +++
3 files changed, 76 insertions(+), 7 deletions(-)
diff --git a/tools/perf/jvmti/jvmti_agent.c b/tools/perf/jvmti/jvmti_agent.c
index 6461e02ab940..3573f315f955 100644
--- a/tools/perf/jvmti/jvmti_agent.c
+++ b/tools/perf/jvmti/jvmti_agent.c
@@ -92,6 +92,22 @@ error:
return ret;
}
+static int use_arch_timestamp;
+
+static inline uint64_t
+get_arch_timestamp(void)
+{
+#if defined(__i386__) || defined(__x86_64__)
+ unsigned int low, high;
+
+ asm volatile("rdtsc" : "=a" (low), "=d" (high));
+
+ return low | ((uint64_t)high) << 32;
+#else
+ return 0;
+#endif
+}
+
#define NSEC_PER_SEC 1000000000
static int perf_clk_id = CLOCK_MONOTONIC;
@@ -107,6 +123,9 @@ perf_get_timestamp(void)
struct timespec ts;
int ret;
+ if (use_arch_timestamp)
+ return get_arch_timestamp();
+
ret = clock_gettime(perf_clk_id, &ts);
if (ret)
return 0;
@@ -203,6 +222,17 @@ perf_close_marker_file(void)
munmap(marker_addr, pgsz);
}
+static void
+init_arch_timestamp(void)
+{
+ char *str = getenv("JITDUMP_USE_ARCH_TIMESTAMP");
+
+ if (!str || !*str || !strcmp(str, "0"))
+ return;
+
+ use_arch_timestamp = 1;
+}
+
void *jvmti_open(void)
{
int pad_cnt;
@@ -211,11 +241,17 @@ void *jvmti_open(void)
int fd;
FILE *fp;
+ init_arch_timestamp();
+
/*
* check if clockid is supported
*/
- if (!perf_get_timestamp())
- warnx("jvmti: kernel does not support %d clock id", perf_clk_id);
+ if (!perf_get_timestamp()) {
+ if (use_arch_timestamp)
+ warnx("jvmti: arch timestamp not supported");
+ else
+ warnx("jvmti: kernel does not support %d clock id", perf_clk_id);
+ }
memset(&header, 0, sizeof(header));
@@ -263,6 +299,9 @@ void *jvmti_open(void)
header.timestamp = perf_get_timestamp();
+ if (use_arch_timestamp)
+ header.flags |= JITDUMP_FLAGS_ARCH_TIMESTAMP;
+
if (!fwrite(&header, sizeof(header), 1, fp)) {
warn("jvmti: cannot write dumpfile header");
goto error;
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c
index cd272cc21e05..5608179dff34 100644
--- a/tools/perf/util/jitdump.c
+++ b/tools/perf/util/jitdump.c
@@ -17,6 +17,7 @@
#include "strlist.h"
#include <elf.h>
+#include "tsc.h"
#include "session.h"
#include "jit.h"
#include "jitdump.h"
@@ -33,6 +34,7 @@ struct jit_buf_desc {
size_t bufsize;
FILE *in;
bool needs_bswap; /* handles cross-endianess */
+ bool use_arch_timestamp;
void *debug_data;
size_t nr_debug_entries;
uint32_t code_load_count;
@@ -158,13 +160,16 @@ jit_open(struct jit_buf_desc *jd, const char *name)
header.flags = bswap_64(header.flags);
}
+ jd->use_arch_timestamp = header.flags & JITDUMP_FLAGS_ARCH_TIMESTAMP;
+
if (verbose > 2)
- pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\n",
+ pr_debug("version=%u\nhdr.size=%u\nts=0x%llx\npid=%d\nelf_mach=%d\nuse_arch_timestamp=%d\n",
header.version,
header.total_size,
(unsigned long long)header.timestamp,
header.pid,
- header.elf_mach);
+ header.elf_mach,
+ jd->use_arch_timestamp);
if (header.flags & JITDUMP_FLAGS_RESERVED) {
pr_err("jitdump file contains invalid or unsupported flags 0x%llx\n",
@@ -172,10 +177,15 @@ jit_open(struct jit_buf_desc *jd, const char *name)
goto error;
}
+ if (jd->use_arch_timestamp && !jd->session->time_conv.time_mult) {
+ pr_err("jitdump file uses arch timestamps but there is no timestamp conversion\n");
+ goto error;
+ }
+
/*
* validate event is using the correct clockid
*/
- if (jit_validate_events(jd->session)) {
+ if (!jd->use_arch_timestamp && jit_validate_events(jd->session)) {
pr_err("error, jitted code must be sampled with perf record -k 1\n");
goto error;
}
@@ -329,6 +339,23 @@ jit_inject_event(struct jit_buf_desc *jd, union perf_event *event)
return 0;
}
+static uint64_t convert_timestamp(struct jit_buf_desc *jd, uint64_t timestamp)
+{
+ struct perf_tsc_conversion tc;
+
+ if (!jd->use_arch_timestamp)
+ return timestamp;
+
+ tc.time_shift = jd->session->time_conv.time_shift;
+ tc.time_mult = jd->session->time_conv.time_mult;
+ tc.time_zero = jd->session->time_conv.time_zero;
+
+ if (!tc.time_mult)
+ return 0;
+
+ return tsc_to_perf_time(timestamp, &tc);
+}
+
static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
{
struct perf_sample sample;
@@ -410,7 +437,7 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr)
id->tid = tid;
}
if (jd->sample_type & PERF_SAMPLE_TIME)
- id->time = jr->load.p.timestamp;
+ id->time = convert_timestamp(jd, jr->load.p.timestamp);
/*
* create pseudo sample to induce dso hit increment
@@ -498,7 +525,7 @@ static int jit_repipe_code_move(struct jit_buf_desc *jd, union jr_entry *jr)
id->tid = tid;
}
if (jd->sample_type & PERF_SAMPLE_TIME)
- id->time = jr->load.p.timestamp;
+ id->time = convert_timestamp(jd, jr->load.p.timestamp);
/*
* create pseudo sample to induce dso hit increment
diff --git a/tools/perf/util/jitdump.h b/tools/perf/util/jitdump.h
index b66c1f503d9e..bcacd20d0c1c 100644
--- a/tools/perf/util/jitdump.h
+++ b/tools/perf/util/jitdump.h
@@ -23,9 +23,12 @@
#define JITHEADER_VERSION 1
enum jitdump_flags_bits {
+ JITDUMP_FLAGS_ARCH_TIMESTAMP_BIT,
JITDUMP_FLAGS_MAX_BIT,
};
+#define JITDUMP_FLAGS_ARCH_TIMESTAMP (1ULL << JITDUMP_FLAGS_ARCH_TIMESTAMP_BIT)
+
#define JITDUMP_FLAGS_RESERVED (JITDUMP_FLAGS_MAX_BIT < 64 ? \
(~((1ULL << JITDUMP_FLAGS_MAX_BIT) - 1)) : 0)
--
1.9.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web