[PATCH] perf: POSIX CLOCK_PERF to report current time value

From: Pawel Moll
Date: Thu Mar 14 2013 - 15:49:09 EST


To co-relate user space events with the perf events stream
a current (as in: "what time(stamp) is it now?") time value
must be made available.

This patch adds a POSIX clock returning the perf_clock()
value and accesible from userspace:

#include <time.h>

struct timespec ts;

clock_gettime(CLOCK_PERF, &ts);

Signed-off-by: Pawel Moll <pawel.moll@xxxxxxx>
---
include/uapi/linux/time.h | 1 +
kernel/events/core.c | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)

diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 0d3c0ed..cea16b0 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -54,6 +54,7 @@ struct itimerval {
#define CLOCK_BOOTTIME 7
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9
+#define CLOCK_PERF 10

/*
* The IDs of various hardware clocks:
diff --git a/kernel/events/core.c b/kernel/events/core.c
index b0cd865..81ca459 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -37,6 +37,7 @@
#include <linux/ftrace_event.h>
#include <linux/hw_breakpoint.h>
#include <linux/mm_types.h>
+#include <linux/posix-timers.h>

#include "internal.h"

@@ -209,6 +210,19 @@ static inline u64 perf_clock(void)
return local_clock();
}

+static int perf_posix_clock_getres(const clockid_t which_clock,
+ struct timespec *tp)
+{
+ *tp = ns_to_timespec(TICK_NSEC);
+ return 0;
+}
+
+static int perf_posix_clock_get(clockid_t which_clock, struct timespec *tp)
+{
+ *tp = ns_to_timespec(perf_clock());
+ return 0;
+}
+
static inline struct perf_cpu_context *
__get_cpu_context(struct perf_event_context *ctx)
{
@@ -7391,6 +7405,10 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)

void __init perf_event_init(void)
{
+ struct k_clock perf_posix_clock = {
+ .clock_getres = perf_posix_clock_getres,
+ .clock_get = perf_posix_clock_get,
+ };
int ret;

idr_init(&pmu_idr);
@@ -7407,6 +7425,8 @@ void __init perf_event_init(void)
ret = init_hw_breakpoint();
WARN(ret, "hw_breakpoint initialization failed with: %d", ret);

+ posix_timers_register_clock(CLOCK_PERF, &perf_posix_clock);
+
/* do not patch jump label more than once per second */
jump_label_rate_limit(&perf_sched_events, HZ);

--
1.7.10.4




--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/