mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
time: Rework debugging variables so they aren't global
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. This version is different from the earlier versions as it keeps the variables in the timekeeper structure rather then in the tkr. 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>
This commit is contained in:
parent
6374f9124e
commit
57d05a93ad
@ -61,6 +61,9 @@ struct tk_read_base {
|
|||||||
* shifted nano seconds.
|
* shifted nano seconds.
|
||||||
* @ntp_error_shift: Shift conversion between clock shifted nano seconds and
|
* @ntp_error_shift: Shift conversion between clock shifted nano seconds and
|
||||||
* ntp shifted nano seconds.
|
* ntp shifted nano seconds.
|
||||||
|
* @last_warning: Warning ratelimiter (DEBUG_TIMEKEEPING)
|
||||||
|
* @underflow_seen: Underflow warning flag (DEBUG_TIMEKEEPING)
|
||||||
|
* @overflow_seen: Overflow warning flag (DEBUG_TIMEKEEPING)
|
||||||
*
|
*
|
||||||
* Note: For timespec(64) based interfaces wall_to_monotonic is what
|
* Note: For timespec(64) based interfaces wall_to_monotonic is what
|
||||||
* we need to add to xtime (or xtime corrected for sub jiffie times)
|
* we need to add to xtime (or xtime corrected for sub jiffie times)
|
||||||
@ -106,6 +109,18 @@ struct timekeeper {
|
|||||||
s64 ntp_error;
|
s64 ntp_error;
|
||||||
u32 ntp_error_shift;
|
u32 ntp_error_shift;
|
||||||
u32 ntp_err_mult;
|
u32 ntp_err_mult;
|
||||||
|
#ifdef CONFIG_DEBUG_TIMEKEEPING
|
||||||
|
long last_warning;
|
||||||
|
/*
|
||||||
|
* These simple flag variables are managed
|
||||||
|
* without locks, which is racy, but they are
|
||||||
|
* 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
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
||||||
|
@ -118,18 +118,6 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta)
|
|||||||
|
|
||||||
#ifdef CONFIG_DEBUG_TIMEKEEPING
|
#ifdef CONFIG_DEBUG_TIMEKEEPING
|
||||||
#define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */
|
#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 timekeeper *tk, cycle_t offset)
|
static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset)
|
||||||
{
|
{
|
||||||
@ -149,29 +137,30 @@ static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timekeeping_underflow_seen) {
|
if (tk->underflow_seen) {
|
||||||
if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
|
if (jiffies - tk->last_warning > WARNING_FREQ) {
|
||||||
printk_deferred("WARNING: Underflow in clocksource '%s' observed, time update ignored.\n", name);
|
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(" Please report this, consider using a different clocksource, if possible.\n");
|
||||||
printk_deferred(" Your kernel is probably still fine.\n");
|
printk_deferred(" Your kernel is probably still fine.\n");
|
||||||
timekeeping_last_warning = jiffies;
|
tk->last_warning = jiffies;
|
||||||
}
|
}
|
||||||
timekeeping_underflow_seen = 0;
|
tk->underflow_seen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timekeeping_overflow_seen) {
|
if (tk->overflow_seen) {
|
||||||
if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
|
if (jiffies - tk->last_warning > WARNING_FREQ) {
|
||||||
printk_deferred("WARNING: Overflow in clocksource '%s' observed, time update capped.\n", name);
|
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(" Please report this, consider using a different clocksource, if possible.\n");
|
||||||
printk_deferred(" Your kernel is probably still fine.\n");
|
printk_deferred(" Your kernel is probably still fine.\n");
|
||||||
timekeeping_last_warning = jiffies;
|
tk->last_warning = jiffies;
|
||||||
}
|
}
|
||||||
timekeeping_overflow_seen = 0;
|
tk->overflow_seen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
|
static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
|
||||||
{
|
{
|
||||||
|
struct timekeeper *tk = &tk_core.timekeeper;
|
||||||
cycle_t now, last, mask, max, delta;
|
cycle_t now, last, mask, max, delta;
|
||||||
unsigned int seq;
|
unsigned int seq;
|
||||||
|
|
||||||
@ -197,13 +186,13 @@ static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
|
|||||||
* mask-relative negative values.
|
* mask-relative negative values.
|
||||||
*/
|
*/
|
||||||
if (unlikely((~delta & mask) < (mask >> 3))) {
|
if (unlikely((~delta & mask) < (mask >> 3))) {
|
||||||
timekeeping_underflow_seen = 1;
|
tk->underflow_seen = 1;
|
||||||
delta = 0;
|
delta = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cap delta value to the max_cycles values to avoid mult overflows */
|
/* Cap delta value to the max_cycles values to avoid mult overflows */
|
||||||
if (unlikely(delta > max)) {
|
if (unlikely(delta > max)) {
|
||||||
timekeeping_overflow_seen = 1;
|
tk->overflow_seen = 1;
|
||||||
delta = tkr->clock->max_cycles;
|
delta = tkr->clock->max_cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user