All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: John Stultz <john.stultz@linaro.org>
Cc: lkml <linux-kernel@vger.kernel.org>,
	Dave Jones <davej@codemonkey.org.uk>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Richard Cochran <richardcochran@gmail.com>,
	Prarit Bhargava <prarit@redhat.com>,
	Stephen Boyd <sboyd@codeaurora.org>,
	Peter Zijlstra <peterz@infradead.org>
Subject: Re: [PATCH 07/12] time: Add warnings when overflows or underflows are observed
Date: Thu, 12 Mar 2015 08:37:39 +0100	[thread overview]
Message-ID: <20150312073739.GA15123@gmail.com> (raw)
In-Reply-To: <1426133800-29329-8-git-send-email-john.stultz@linaro.org>


* John Stultz <john.stultz@linaro.org> wrote:

> It was suggested that the underflow/overflow protection
> should probably throw some sort of warning out, rather
> then just silently fixing the issue.
> 
> So this patch adds some warnings here. The flag variables
> used are not protected by locks, but since we can't print
> from the reading functions, just being able to say we
> saw an issue in the update interval is useful enough,
> and can be slightly racy without real consequence.

> + * 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)
>  {
>  
> @@ -134,28 +148,62 @@ static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset)
>  					offset, name, max_cycles>>1);
>  		}
>  	}
> +
> +	if (timekeeping_underflow_seen) {
> +		if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
> +			printk_deferred("WARNING: Clocksource %s underflow observed. You should report\n", name);
> +			printk_deferred("         this, consider using a different clocksource.\n");
> +			timekeeping_last_warning = jiffies;
> +		}
> +		timekeeping_underflow_seen = 0;
> +	}
> +
> +	if (timekeeping_overflow_seen) {
> +		if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
> +			printk_deferred("WARNING: Clocksource %s overflow observed. You should report\n", name);
> +			printk_deferred("         this, consider using a different clocksource.\n");
> +			timekeeping_last_warning = jiffies;
> +		}
> +		timekeeping_overflow_seen = 0;
> +	}
>  }
>  
>  static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
>  {
> -	cycle_t cycle_now, delta;
> +	cycle_t now, last, mask, max, delta;
> +	unsigned int seq;
>  
> -	/* read clocksource */
> -	cycle_now = tkr->read(tkr->clock);
> +	/*
> +	 * Since we're called holding a seqlock, the data may shift
> +	 * under us while we're doing the calculation. This can cause
> +	 * false positives, since we'd note a problem but throw the
> +	 * results away. So nest another seqlock here to atomically
> +	 * grab the points we are checking with.
> +	 */
> +	do {
> +		seq = read_seqcount_begin(&tk_core.seq);
> +		now = tkr->read(tkr->clock);
> +		last = tkr->cycle_last;
> +		mask = tkr->mask;
> +		max = tkr->clock->max_cycles;
> +	} while (read_seqcount_retry(&tk_core.seq, seq));
>  
> -	/* calculate the delta since the last update_wall_time */
> -	delta = clocksource_delta(cycle_now, tkr->cycle_last, tkr->mask);
> +	delta = clocksource_delta(now, last, mask);
>  
>  	/*
>  	 * Try to catch underflows by checking if we are seeing small
>  	 * mask-relative negative values.
>  	 */
> -	if (unlikely((~delta & tkr->mask) < (tkr->mask >> 3)))
> +	if (unlikely((~delta & mask) < (mask >> 3))) {
> +		timekeeping_underflow_seen = 1;
>  		delta = 0;
> +	}
>  
>  	/* Cap delta value to the max_cycles values to avoid mult overflows */
> -	if (unlikely(delta > tkr->clock->max_cycles))
> +	if (unlikely(delta > max)) {
> +		timekeeping_overflow_seen = 1;
>  		delta = tkr->clock->max_cycles;
> +	}

Please add the flags as new fields in the 'struct tk_read_base' data 
structure in include/linux/timekeeper_internal.h - we don't want to go 
back to the old pattern of adding globals to the timekeeping code, 
even if they are just for debugging!

also, timekeeping_check_update() should pass in 'struct tk_read_base', 
not 'struct timekeeper' - it's really only using the tkr bits and 
doing this change would make it similar to timekeeping_get_delta(). It 
would also shorten:

        cycle_t max_cycles = tk->tkr.clock->max_cycles;
        const char *name = tk->tkr.clock->name;

to the more natural looking:

        cycle_t max_cycles = tkr->clock->max_cycles;
        const char *name = tkr->clock->name;

hm?

Thanks,

	Ingo

  reply	other threads:[~2015-03-12  7:37 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-12  4:16 [PATCH 00/12] Increased clocksource validation and cleanups (v4) John Stultz
2015-03-12  4:16 ` [PATCH 01/12] clocksource: Simplify clocks_calc_max_nsecs logic John Stultz
2015-03-13  9:01   ` [tip:timers/core] clocksource: Simplify the clocks_calc_max_nsecs () logic tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 02/12] clocksource: Simplify logic around clocksource wrapping safety margins John Stultz
2015-03-12  5:55   ` Ingo Molnar
2015-03-13  9:01   ` [tip:timers/core] clocksource: Simplify the " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 03/12] clocksource: Add max_cycles to clocksource structure John Stultz
2015-03-13  9:01   ` [tip:timers/core] clocksource: Add 'max_cycles' to ' struct clocksource' tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 04/12] time: Add debugging checks to warn if we see delays John Stultz
2015-03-12  6:32   ` Ingo Molnar
2015-03-13  9:02   ` [tip:timers/core] timekeeping: " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 05/12] time: Add infrastructure to cap clocksource reads to the max_cycles value John Stultz
2015-03-13  9:02   ` [tip:timers/core] timekeeping: Add checks to cap clocksource reads to the 'max_cycles' value tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 06/12] time: Try to catch clocksource delta underflows John Stultz
2015-03-13  9:02   ` [tip:timers/core] timekeeping: " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 07/12] time: Add warnings when overflows or underflows are observed John Stultz
2015-03-12  7:37   ` Ingo Molnar [this message]
2015-03-13  9:03   ` [tip:timers/core] timekeeping: " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 08/12] clocksource: Improve clocksource watchdog reporting John Stultz
2015-03-13  9:03   ` [tip:timers/core] " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 09/12] clocksource: Mostly kill clocksource_register() John Stultz
2015-03-13  9:03   ` [tip:timers/core] " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 10/12] sparc: Convert to using clocksource_register_hz() John Stultz
2015-03-13  9:04   ` [tip:timers/core] clocksource, sparc32: " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 11/12] clocksource: Add some debug info about clocksources being registered John Stultz
2015-03-13  9:04   ` [tip:timers/core] " tip-bot for John Stultz
2015-03-12  4:16 ` [PATCH 12/12] clocksource: Rename __clocksource_updatefreq_* to __clocksource_update_freq_* John Stultz
2015-03-13  9:04   ` [tip:timers/core] clocksource: Rename __clocksource_updatefreq_*( ) to __clocksource_update_freq_*() tip-bot for John Stultz
2015-03-12  9:19 ` [PATCH 00/12] Increased clocksource validation and cleanups (v4) Ingo Molnar
2015-03-12 16:26   ` John Stultz
2015-03-13  8:58     ` Ingo Molnar
2015-03-13 17:54       ` John Stultz
2015-03-16  8:28         ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150312073739.GA15123@gmail.com \
    --to=mingo@kernel.org \
    --cc=davej@codemonkey.org.uk \
    --cc=john.stultz@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=prarit@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=sboyd@codeaurora.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.