Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1726655 > unrolled thread
| Started by | Prarit Bhargava <prarit@redhat.com> |
|---|---|
| First post | 2017-09-05 14:10 +0200 |
| Last post | 2017-09-05 14:20 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH 0/3 v11] printk: Add new timestamps Prarit Bhargava <prarit@redhat.com> - 2017-09-05 14:10 +0200
[PATCH 2/3 v11] timekeeping: Provide NMI safe access to clock realtime Prarit Bhargava <prarit@redhat.com> - 2017-09-05 14:10 +0200
[PATCH 1/3 v11] time: Make fast functions return 0 before timekeeping is initialized Prarit Bhargava <prarit@redhat.com> - 2017-09-05 14:10 +0200
Re: [PATCH 1/3 v11] time: Make fast functions return 0 before timekeeping is initialized Thomas Gleixner <tglx@linutronix.de> - 2017-09-05 14:20 +0200
| From | Prarit Bhargava <prarit@redhat.com> |
|---|---|
| Date | 2017-09-05 14:10 +0200 |
| Subject | [PATCH 0/3 v11] printk: Add new timestamps |
| Message-ID | <umkQ2-2tt-9@gated-at.bofh.it> |
printk.time=1/CONFIG_PRINTK_TIME=1 adds a unmodified local hardware clock timestamp to printk messages. The local hardware clock loses time each day making it difficult to determine exactly when an issue has occurred in the kernel log, and making it difficult to determine how kernel and hardware issues relate to each other in real time. Add monotonic, boottime, and real clock timestamps in addition to the existing local hardware clock timestamp. Signed-off-by: Prarit Bhargava <prarit@redhat.com> Cc: Mark Salyzyn <salyzyn@android.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Petr Mladek <pmladek@suse.com> Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: John Stultz <john.stultz@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: Christoffer Dall <cdall@linaro.org> Cc: Deepa Dinamani <deepa.kernel@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Joel Fernandes <joelaf@google.com> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Kees Cook <keescook@chromium.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Geert Uytterhoeven <geert+renesas@glider.be> Cc: "Luis R. Rodriguez" <mcgrof@kernel.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: "Jason A. Donenfeld" <Jason@zx2c4.com> Cc: Olof Johansson <olof@lixom.net> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: linux-doc@vger.kernel.org [jstultz: reworked Kconfig settings to avoid defconfig noise] Signed-off-by: John Stultz <john.stultz@linaro.org> Prarit Bhargava (2): time: Make fast functions return 0 before timekeeping is initialized printk: Add monotonic, boottime, and realtime timestamps Thomas Gleixner (1): timekeeping: Provide NMI safe access to clock realtime Documentation/admin-guide/kernel-parameters.txt | 6 +- include/linux/timekeeper_internal.h | 6 +- include/linux/timekeeping.h | 1 + kernel/printk/printk.c | 113 ++++++++++++++++++++++-- kernel/time/timekeeping.c | 72 +++++++++++++-- lib/Kconfig.debug | 48 +++++++++- 6 files changed, 228 insertions(+), 18 deletions(-) -- 1.8.5.5
[toc] | [next] | [standalone]
| From | Prarit Bhargava <prarit@redhat.com> |
|---|---|
| Date | 2017-09-05 14:10 +0200 |
| Subject | [PATCH 2/3 v11] timekeeping: Provide NMI safe access to clock realtime |
| Message-ID | <umkQ2-2tt-15@gated-at.bofh.it> |
| In reply to | #1726655 |
From: Thomas Gleixner <tglx@linutronix.de>
The configurable printk timestamping wants access to clock realtime. Right
now there is no ktime_get_real_fast_ns() accessor because reading the
monotonic base and the realtime offset cannot be done atomically. Contrary
to boot time this offset can change during runtime and cause half updated
readouts.
struct tk_read_base was fully packed when the fast timekeeper access was
implemented. commit ceea5e3771ed ("time: Fix clock->read(clock) race around
clocksource changes") removed the 'read' function pointer from the
structure, but of course left the comment stale.
So now the structure can fit a new 64bit member w/o violating the cache
line constraints.
Add real_base to tk_read_base and update it in the fast timekeeper update
sequence.
Implement an accessor which follows the same scheme as the accessor to
clock monotonic, but uses the new real_base to access clock real time.
The runtime overhead for updating real_base is minimal as it just adds two
cache hot values and stores into the same an already dirtied cache line.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/timekeeper_internal.h | 6 +++++-
include/linux/timekeeping.h | 1 +
kernel/time/timekeeping.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index 0a0a53daf2a2..98f645ee8409 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -13,19 +13,22 @@
/**
* struct tk_read_base - base structure for timekeeping readout
* @clock: Current clocksource used for timekeeping.
- * @read: Read function of @clock
* @mask: Bitmask for two's complement subtraction of non 64bit clocks
* @cycle_last: @clock cycle value at last update
* @mult: (NTP adjusted) multiplier for scaled math conversion
* @shift: Shift value for scaled math conversion
* @xtime_nsec: Shifted (fractional) nano seconds offset for readout
* @base: ktime_t (nanoseconds) base time for readout
+ * @base_real: Nanoseconds base value for clock REALTIME readout
*
* This struct has size 56 byte on 64 bit. Together with a seqcount it
* occupies a single 64byte cache line.
*
* The struct is separate from struct timekeeper as it is also used
* for a fast NMI safe accessors.
+ *
+ * @base_real is for the fast NMI safe accessor to allow reading clock
+ * realtime from any context.
*/
struct tk_read_base {
struct clocksource *clock;
@@ -35,6 +38,7 @@ struct tk_read_base {
u32 shift;
u64 xtime_nsec;
ktime_t base;
+ u64 base_real;
};
/**
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index ddc229ff6d1e..eb98cbdbb323 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -239,6 +239,7 @@ static inline u64 ktime_get_raw_ns(void)
extern u64 ktime_get_mono_fast_ns(void);
extern u64 ktime_get_raw_fast_ns(void);
extern u64 ktime_get_boot_fast_ns(void);
+extern u64 ktime_get_real_fast_ns(void);
/*
* Timespec interfaces utilizing the ktime based ones
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 1f8596ef7408..8b14f35d44fa 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -508,6 +508,39 @@ u64 notrace ktime_get_boot_fast_ns(void)
}
EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);
+
+/*
+ * See comment for __ktime_get_fast_ns() vs. timestamp ordering
+ */
+static __always_inline u64 __ktime_get_real_fast_ns(struct tk_fast *tkf)
+{
+ struct tk_read_base *tkr;
+ unsigned int seq;
+ u64 now;
+
+ do {
+ seq = raw_read_seqcount_latch(&tkf->seq);
+ tkr = tkf->base + (seq & 0x01);
+ now = ktime_to_ns(tkr->base_real);
+
+ now += timekeeping_delta_to_ns(tkr,
+ clocksource_delta(
+ tk_clock_read(tkr),
+ tkr->cycle_last,
+ tkr->mask));
+ } while (read_seqcount_retry(&tkf->seq, seq));
+
+ return now;
+}
+
+/**
+ * ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime.
+ */
+u64 ktime_get_real_fast_ns(void)
+{
+ return __ktime_get_real_fast_ns(&tk_fast_mono);
+}
+
/**
* halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
* @tk: Timekeeper to snapshot.
@@ -526,6 +559,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk)
memcpy(&tkr_dummy, tkr, sizeof(tkr_dummy));
cycles_at_suspend = tk_clock_read(tkr);
tkr_dummy.clock = &dummy_clock;
+ tkr_dummy.base_real = tkr->base + tk->offs_real;
update_fast_timekeeper(&tkr_dummy, &tk_fast_mono);
tkr = &tk->tkr_raw;
@@ -673,6 +707,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
update_vsyscall(tk);
update_pvclock_gtod(tk, action & TK_CLOCK_WAS_SET);
+ tk->tkr_mono.base_real = tk->tkr_mono.base + tk->offs_real;
update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono);
update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw);
--
1.8.5.5
[toc] | [prev] | [next] | [standalone]
| From | Prarit Bhargava <prarit@redhat.com> |
|---|---|
| Date | 2017-09-05 14:10 +0200 |
| Subject | [PATCH 1/3 v11] time: Make fast functions return 0 before timekeeping is initialized |
| Message-ID | <umkQ2-2tt-13@gated-at.bofh.it> |
| In reply to | #1726655 |
printk timestamps will be extended to include mono and boot time by using
the fast timekeeping functions ktime_get_mono|boot_fast_ns() functions.
The functions can return garbage before timekeeping is initialized
resulting in garbage timestamps.
The fast time functions must return 0 before timekeeping is initialized.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Stephen Boyd <sboyd@codeaurora.org>
---
kernel/time/timekeeping.c | 47 +++++++++++++++++++++++++++++++++--------------
1 file changed, 33 insertions(+), 14 deletions(-)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 7e7e61c00d61..1f8596ef7408 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -60,8 +60,39 @@ struct tk_fast {
struct tk_read_base base[2];
};
-static struct tk_fast tk_fast_mono ____cacheline_aligned;
-static struct tk_fast tk_fast_raw ____cacheline_aligned;
+/* Suspend-time cycles value for halted fast timekeeper. */
+static u64 cycles_at_suspend;
+
+static u64 dummy_clock_read(struct clocksource *cs)
+{
+ return cycles_at_suspend;
+}
+
+static struct clocksource dummy_clock = {
+ .read = dummy_clock_read,
+};
+
+static struct tk_fast tk_fast_mono ____cacheline_aligned = {
+ .base = {
+ (struct tk_read_base){
+ .clock = &dummy_clock,
+ },
+ (struct tk_read_base){
+ .clock = &dummy_clock,
+ },
+ },
+};
+
+static struct tk_fast tk_fast_raw ____cacheline_aligned = {
+ .base = {
+ (struct tk_read_base){
+ .clock = &dummy_clock,
+ },
+ (struct tk_read_base){
+ .clock = &dummy_clock,
+ },
+ },
+};
/* flag for if timekeeping is suspended */
int __read_mostly timekeeping_suspended;
@@ -477,18 +508,6 @@ u64 notrace ktime_get_boot_fast_ns(void)
}
EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);
-/* Suspend-time cycles value for halted fast timekeeper. */
-static u64 cycles_at_suspend;
-
-static u64 dummy_clock_read(struct clocksource *cs)
-{
- return cycles_at_suspend;
-}
-
-static struct clocksource dummy_clock = {
- .read = dummy_clock_read,
-};
-
/**
* halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource.
* @tk: Timekeeper to snapshot.
--
1.8.5.5
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-09-05 14:20 +0200 |
| Subject | Re: [PATCH 1/3 v11] time: Make fast functions return 0 before timekeeping is initialized |
| Message-ID | <umkZH-2wz-1@gated-at.bofh.it> |
| In reply to | #1726657 |
On Tue, 5 Sep 2017, Prarit Bhargava wrote:
> +static struct tk_fast tk_fast_mono ____cacheline_aligned = {
> + .base = {
> + (struct tk_read_base){
> + .clock = &dummy_clock,
> + },
> + (struct tk_read_base){
> + .clock = &dummy_clock,
> + },
> + },
> +};
http://lkml.kernel.org/r/alpine.DEB.2.20.1708281658370.1867@nanos
Sigh
tglx
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web