mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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
					
				
					 2 changed files with 26 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -61,6 +61,9 @@ struct tk_read_base {
 | 
			
		|||
 *			shifted nano seconds.
 | 
			
		||||
 * @ntp_error_shift:	Shift conversion between clock shifted nano seconds and
 | 
			
		||||
 *			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
 | 
			
		||||
 * we need to add to xtime (or xtime corrected for sub jiffie times)
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +109,18 @@ struct timekeeper {
 | 
			
		|||
	s64			ntp_error;
 | 
			
		||||
	u32			ntp_error_shift;
 | 
			
		||||
	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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,18 +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 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 (jiffies - timekeeping_last_warning > WARNING_FREQ) {
 | 
			
		||||
	if (tk->underflow_seen) {
 | 
			
		||||
		if (jiffies - tk->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;
 | 
			
		||||
			tk->last_warning = jiffies;
 | 
			
		||||
		}
 | 
			
		||||
		timekeeping_underflow_seen = 0;
 | 
			
		||||
		tk->underflow_seen = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (timekeeping_overflow_seen) {
 | 
			
		||||
		if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
 | 
			
		||||
	if (tk->overflow_seen) {
 | 
			
		||||
		if (jiffies - tk->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;
 | 
			
		||||
			tk->last_warning = jiffies;
 | 
			
		||||
		}
 | 
			
		||||
		timekeeping_overflow_seen = 0;
 | 
			
		||||
		tk->overflow_seen = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
	unsigned int seq;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,13 +186,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;
 | 
			
		||||
		tk->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;
 | 
			
		||||
		tk->overflow_seen = 1;
 | 
			
		||||
		delta = tkr->clock->max_cycles;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue