lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Fri,  6 Dec 2013 16:34:11 -0800
From:	Sonny Rao <sonnyrao@...omium.org>
To:	linux-kernel@...r.kernel.org
Cc:	John Stultz <john.stultz@...aro.org>,
	Stephane Eranian <eranian@...gle.com>,
	Josh Triplett <josh.triplett@...el.com>,
	Pawel Moll <pawell.moll@....com>,
	Olof Johansson <olof@...om.net>,
	Ingo Molnar <mingo@...nel.org>,
	Steven Rostedt <rostedt@...dmis.org>,
	Peter Zijlstra <peterz@...radead.org>,
	Thomas Gleixner <tglx@...utronix.de>,
	Frederic Weisbecker <fweisbec@...il.com>,
	Andrew Morton <akpm@...ux-foundation.org>,
	Sonny Rao <sonnyrao@...omium.org>
Subject: [RFC PATCH] drivers: char: Add a dynamic clock for the trace clock

Based on a suggestion from John Stultz.

This adds a dynamic clock device which can be used with clock_gettime
to sample the clock source used for time stamping trace events in the
kernel.  The only use for this clock source is to associate user space
events with kernel events on a given kernel.  It is explicitly not
supposed to be used as a generic time source and won't necessarily be
consistent between kernels.

Signed-off-by: Sonny Rao <sonnyrao@...omium.org>
---
 drivers/char/Kconfig       |  8 ++++
 drivers/char/Makefile      |  1 +
 drivers/char/trace_clock.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/kernel.h     | 12 ++++++
 kernel/trace/trace.c       | 23 +++++++++++
 5 files changed, 143 insertions(+)
 create mode 100644 drivers/char/trace_clock.c

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index fa3243d..785ab73 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -599,5 +599,13 @@ config TILE_SROM
 	  device appear much like a simple EEPROM, and knows
 	  how to partition a single ROM for multiple purposes.
 
+config TRACE_CLOCK_DEV
+	tristate "Dynamic clock type which gives time used for ftrace events"
+	depends on TRACING
+	default y
+	help
+	  This device presents a posix dynamic clock which allows user
+	  space to sample the clock used for time stamps on trace events
+	  in the kernel.
 endmenu
 
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index a324f93..5cd42e0 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
 obj-$(CONFIG_TILE_SROM)		+= tile-srom.o
+obj-$(CONFIG_TRACE_CLOCK_DEV)	+= trace_clock.o
diff --git a/drivers/char/trace_clock.c b/drivers/char/trace_clock.c
new file mode 100644
index 0000000..d73b35d
--- /dev/null
+++ b/drivers/char/trace_clock.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 The Chromium OS Authors <chromium-os-dev@...omium.org>
+ *                    All Rights Reserved.
+ *
+ * This file is released under the GPL.
+ *
+ * Posix Dynamic Clock for tracing clock.
+ *
+ * This device is meant to provide a stream which userspace can sample
+ * to match up kernel generated events to user generated events, on a
+ * given kernel.  It  * is explicitly *not* trying to be a standalone
+ * time source and shouldn't be used for anything else or for
+ * comparisons between different kernels.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/posix-clock.h>
+
+static dev_t tc_devt;
+static struct class *tc_class;
+static struct device *tc_dev;
+static struct posix_clock tc_pclock;
+
+static int tc_clock_gettime(struct posix_clock *pc, struct timespec *ts)
+{
+	trace_clock_gettime(ts);
+	return 0;
+}
+
+static int tc_clock_getres(struct posix_clock *pc, struct timespec *ts)
+{
+	trace_clock_getres(ts);
+	return 0;
+}
+
+static struct posix_clock_operations tc_clock_ops = {
+	.owner		= THIS_MODULE,
+	.clock_gettime	= tc_clock_gettime,
+	.clock_getres	= tc_clock_getres,
+};
+
+static void __exit trace_clock_exit(void)
+{
+	posix_clock_unregister(&tc_pclock);
+	device_destroy(tc_class, tc_devt);
+	unregister_chrdev_region(tc_devt, 1);
+	class_destroy(tc_class);
+}
+
+static int __init trace_clock_init(void)
+{
+	int err = -ENODEV;
+
+	tc_class = class_create(THIS_MODULE, "trace_clock");
+	if (IS_ERR(tc_class)) {
+		pr_err("trace_clock: failed to allocate class\n");
+		return PTR_ERR(tc_class);
+	}
+
+	err = alloc_chrdev_region(&tc_devt, 0, 1, "trace_clock");
+	if (err < 0) {
+		pr_err("trace_clock: failed to allocate device region\n");
+		goto no_region;
+	}
+	tc_dev = device_create(tc_class, NULL, tc_devt, NULL, "trace_clock");
+	if (!tc_dev) {
+		pr_err("trace_clock: failed to create device\n");
+		goto no_device;
+	}
+
+	tc_pclock.ops = tc_clock_ops;
+
+	err = posix_clock_register(&tc_pclock, tc_devt);
+	if (err < 0) {
+		pr_err("trace_clock: failed to register posix clock %d\n",
+		       err);
+		goto no_pclock;
+	}
+	pr_info("Trace clock support registered\n");
+	return 0;
+
+no_pclock:
+	device_destroy(tc_class, tc_devt);
+
+no_device:
+	unregister_chrdev_region(tc_devt, 1);
+
+no_region:
+	class_destroy(tc_class);
+	return err;
+}
+
+subsys_initcall(trace_clock_init);
+module_exit(trace_clock_exit);
+
+MODULE_AUTHOR("Sonny Rao <sonnyrao@...omium.org>");
+MODULE_DESCRIPTION("Trace clock device support");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 2ac0277..68a922a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -510,6 +510,9 @@ void tracing_snapshot_alloc(void);
 
 extern void tracing_start(void);
 extern void tracing_stop(void);
+struct timespec;
+extern void trace_clock_gettime(struct timespec *);
+extern void trace_clock_getres(struct timespec *);
 
 static inline __printf(1, 2)
 void ____trace_printk_check_format(const char *fmt, ...)
@@ -648,6 +651,15 @@ extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
 static inline void tracing_start(void) { }
 static inline void tracing_stop(void) { }
 static inline void trace_dump_stack(int skip) { }
+struct timespec;
+static inline void trace_clock_gettime(struct timespec *tp)
+{
+	getrawmonotonic(tp);
+}
+static inline void trace_clock_getres(struct timespec *tp)
+{
+	*tp = ktime_to_timespec(KTIME_LOW_RES);
+}
 
 static inline void tracing_on(void) { }
 static inline void tracing_off(void) { }
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 9d20cd9..f30420a 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -282,6 +282,29 @@ cycle_t ftrace_now(int cpu)
 	return buffer_ftrace_now(&global_trace.trace_buffer, cpu);
 }
 
+/*
+ * Interface used by trace clock device.
+ */
+void trace_clock_getres(struct timespec *tp)
+{
+	*tp = ktime_to_timespec(KTIME_LOW_RES);
+}
+EXPORT_SYMBOL_GPL(trace_clock_getres);
+
+/*
+ * Interface used by trace clock device.
+ */
+void trace_clock_gettime(struct timespec *tp)
+{
+	u64 now;
+	u32 rem;
+
+	now = ftrace_now(raw_smp_processor_id());
+	tp->tv_sec = div_u64_rem(now, NSEC_PER_SEC, &rem);
+	tp->tv_nsec = rem;
+}
+EXPORT_SYMBOL_GPL(trace_clock_gettime);
+
 /**
  * tracing_is_enabled - Show if global_trace has been disabled
  *
-- 
1.8.5.1

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ