Messages in this thread | | | Date | Sat, 7 Mar 2015 10:40:17 +0100 | From | Ingo Molnar <> | Subject | Re: [PATCH 08/12] time: Add warnings when overflows or underflows are observed |
| |
* 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.
Typo.
> 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 consequnece.
Typo.
> The big complication is that we're only under a read > seqlock, so the data could shift under us during > our calcualtion to see if there was a problem. This
Typo.
> patch avoids this issue by nesting another seqlock > which allows us to snapshot the just required values > atomically. So we shouldn't see false positives. > > I also added some basic ratelimiting here, since > on one build machine w/ skewed TSCs it was fairly > noisy at bootup.
> +#define WARNINGFREQ (HZ*300) /* 5 minute rate-limiting */
Nit: so in general wereallytrytokeepwordsapart, so I'd suggest a name of WARNING_FREQ or so?
> cycle_t max_cycles = tk->tkr.clock->max_cycles; > const char *name = tk->tkr.clock->name; > + static long last_warning; /* we always hold write on timekeeper lock */
So I'm not sure I ever heard the phrase 'to hold write', this doesn't parse for me.
Also, static global variables should really, really not be immersed amongst on-stack variables, they are so easy to overlook. Just put them in front of the function.
> > if (offset > max_cycles) > printk_deferred("ERROR: cycle offset (%lld) is larger then" > @@ -133,28 +145,60 @@ static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset) > printk_deferred("WARNING: cycle offset (%lld) is past" > " the %s 50%% safety margin (%lld)\n", > offset, name, max_cycles>>1); > + > + if (timekeeping_underflow_seen) { > + if (jiffies - last_warning > WARNINGFREQ) { > + printk_deferred("WARNING: Clocksource underflow observed\n"); > + last_warning = jiffies; > + } > + timekeeping_underflow_seen = 0; > + } > + if (timekeeping_overflow_seen) { > + if (jiffies - last_warning > WARNINGFREQ) { > + printk_deferred("WARNING: Clocksource overflow observed\n");
I think the warning should be more informative. If a distro turns this on and a user sees this value, what will he think? Is the kernel still OK? What can he do about it?
> + 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 doign the calculation. This can cause
Typo...
> + * false positives, since we'd note a problem but throw the > + * results away. So nest another seqlock here to atomically
Spurious space. I know they are cheap, but still.
Thanks,
Ingo
| |