perf jit: Add support for using TSC as a timestamp

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 <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1457426330-30226-1-git-send-email-adrian.hunter@intel.com
[ Added the fixup from He Kuang to make it build on other arches, ]
[ such as aarch64, to avoid inserting this bisectiong breakage upstream ]
Link: http://lkml.kernel.org/r/1459482572-129494-1-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Adrian Hunter 2016-03-08 10:38:50 +02:00 committed by Arnaldo Carvalho de Melo
parent 46bc29b970
commit 2a28e23049
7 changed files with 87 additions and 28 deletions

View file

@ -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;