Messages in this thread Patch in this message | | | From | John Stultz <> | Subject | [PATCH 21/21] time: Rework debugging variables so they aren't global | Date | Wed, 1 Apr 2015 20:34:41 -0700 |
| |
Ingo suggested that the timekeeping debugging variables recently added should not be global, and should be tied to the timekeeper's read_base.
Thus this patch implements that suggestion.
I'm a little hesitant here, since the tkr structure has been carefully designed to fit in a cacheline. However, these additions are all at the end of the structure and are conditionally compiled.
Cc: Ingo Molnar <mingo@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Richard Cochran <richardcochran@gmail.com> Signed-off-by: John Stultz <john.stultz@linaro.org> --- include/linux/timekeeper_internal.h | 18 +++++++++++++++++- kernel/time/timekeeping.c | 33 ++++++++++----------------------- 2 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index fb86963..9b33027 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -20,9 +20,13 @@ * @shift: Shift value for scaled math conversion * @xtime_nsec: Shifted (fractional) nano seconds offset for readout * @base: ktime_t (nanoseconds) base time for readout + * @last_warning: Warning ratelimiter (DEBUG_TIMEKEEPING) + * @underflow_seen: Underflow warning flag (DEBUG_TIMEKEEPING) + * @overflow_seen: Overflow warning flag (DEBUG_TIMEKEEPING) * * This struct has size 56 byte on 64 bit. Together with a seqcount it - * occupies a single 64byte cache line. + * occupies a single 64byte cache line (when DEBUG_TIMEKEEPING is not + * enabled). * * The struct is separate from struct timekeeper as it is also used * for a fast NMI safe accessors. @@ -36,6 +40,18 @@ struct tk_read_base { u32 shift; u64 xtime_nsec; ktime_t base; +#ifdef CONFIG_DEBUG_TIMEKEEPING + long last_warning; + /* + * These simple flag variables are managed + * without locks, which is racy, but ok since + * we don't really care about being super + * precise about how many events were seen, + * just that a problem was observed. + */ + int underflow_seen; + int overflow_seen; +#endif }; /** diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 676896e..ad7a80f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -118,19 +118,6 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta) #ifdef CONFIG_DEBUG_TIMEKEEPING #define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */ -/* - * These simple flag variables are managed - * without locks, which is racy, but ok since - * we don't really care about being super - * precise about how many events were seen, - * just that a problem was observed. - */ -static int timekeeping_underflow_seen; -static int timekeeping_overflow_seen; - -/* last_warning is only modified under the timekeeping lock */ -static long timekeeping_last_warning; - static void timekeeping_check_update(struct tk_read_base *tkr, cycle_t offset) { @@ -149,24 +136,24 @@ static void timekeeping_check_update(struct tk_read_base *tkr, cycle_t offset) } } - if (timekeeping_underflow_seen) { - if (jiffies - timekeeping_last_warning > WARNING_FREQ) { + if (tkr->underflow_seen) { + if (jiffies - tkr->last_warning > WARNING_FREQ) { printk_deferred("WARNING: Underflow in clocksource '%s' observed, time update ignored.\n", name); printk_deferred(" Please report this, consider using a different clocksource, if possible.\n"); printk_deferred(" Your kernel is probably still fine.\n"); - timekeeping_last_warning = jiffies; + tkr->last_warning = jiffies; } - timekeeping_underflow_seen = 0; + tkr->underflow_seen = 0; } - if (timekeeping_overflow_seen) { - if (jiffies - timekeeping_last_warning > WARNING_FREQ) { + if (tkr->overflow_seen) { + if (jiffies - tkr->last_warning > WARNING_FREQ) { printk_deferred("WARNING: Overflow in clocksource '%s' observed, time update capped.\n", name); printk_deferred(" Please report this, consider using a different clocksource, if possible.\n"); printk_deferred(" Your kernel is probably still fine.\n"); - timekeeping_last_warning = jiffies; + tkr->last_warning = jiffies; } - timekeeping_overflow_seen = 0; + tkr->overflow_seen = 0; } } @@ -197,13 +184,13 @@ static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr) * mask-relative negative values. */ if (unlikely((~delta & mask) < (mask >> 3))) { - timekeeping_underflow_seen = 1; + tkr->underflow_seen = 1; delta = 0; } /* Cap delta value to the max_cycles values to avoid mult overflows */ if (unlikely(delta > max)) { - timekeeping_overflow_seen = 1; + tkr->overflow_seen = 1; delta = tkr->clock->max_cycles; } -- 1.9.1
| |