From: Thomas Gleixner <tglx@linutronix.de>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: Ludovic Desroches <ludovic.desroches@atmel.com>,
Russell King - ARM Linux <linux@arm.linux.org.uk>,
Marc Kleine-Budde <mkl@pengutronix.de>,
nicolas.ferre@atmel.com, LKML <linux-kernel@vger.kernel.org>,
Marc Pignat <marc.pignat@hevs.ch>,
john.stultz@linaro.org, kernel@pengutronix.de,
Ronald Wahl <ronald.wahl@raritan.com>,
LAK <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH] clockevents: Sanitize ticks to nsec conversion
Date: Thu, 19 Sep 2013 00:01:25 +0200 (CEST) [thread overview]
Message-ID: <alpine.DEB.2.02.1309182201000.4089@ionos.tec.linutronix.de> (raw)
In-Reply-To: <20130918150958.GO24802@pengutronix.de>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 3397 bytes --]
On Wed, 18 Sep 2013, Uwe Kleine-König wrote:
> On Wed, Sep 18, 2013 at 11:38:07AM +0200, Thomas Gleixner wrote:
> > On Wed, 18 Sep 2013, Uwe Kleine-König wrote:
> > > Another doubt I have is: You changed clockevent_delta2ns to round up now
> > > unconditionally. For the numbers on at91 that doesn't matter, but I
> > > wonder if there are situations that make the timer core violate the
> > > max_delta_ticks condition now.
> >
> > And how so? The + (mult - 1) ensures, that the conversion back to
> > ticks results in the same value as latch. So how should it violate
> > the max boundary?
> That is wrong:
> With max_delta_ticks << shift = n * mult - k for k in [0 .. mult-1] and
> an integer n:
>
> (max_delta_ns * mult) >> shift
> = ((((max_delta_ticks << shift) + mult - 1) / mult) * mult) >> shift
> = (((n * mult - k + mult - 1) / mult) * mult) >> shift
> = n * mult >> shift
> = ((max_delta_ticks << shift) + k) >> shift
> = max_delta_ticks + (k >> shift)
>
> k >> shift is only known to be zero if mult <= 1 << shift (i.e. the same
> condition as above where your 64bit overflow detection is wrong). So
> this can result in values > max_delta_ticks.
Right, should have waited for coffee actually activating the right
brain cells.
So the rounding thing works nicely for mult <= (1 << sft). For the
other cases the conversion is wrong by (mult / (1 << sft)) - 1. So for
a 3 GHz clock it's off by 2. That's not an issue for the min value,
but for the max value it might overflow the hardware limit. Not a real
functional issue as we'd just get a pointless short interrupt, but for
correctness reasons and for the sake of NOHZ we need to fix that.
There is no real correct solution for these cases, which will result
in a correct backwards conversion. We could validate against the max
delta ticks in program_event, but that adds another boundary check to
the hotpath so I rather want to avoid it.
The simple solution is to check for the following in the conversion
routine:
if (latch == dev->min_delta_ticks || dev->mult <= (1 << dev->sft))
clc += mult - 1
That ensures, that we never violate the lower boundary independent of
the mult/sft relation. For the max_delta_ticks conversion in the "mult
> (1 << sft)" case we end up with a slightly smaller value, but well
inside the boundaries and close enough to the hardware limitations.
Versus the 64bit overflow check, we need to be even more careful. We
need to check for overflowing (1 << 63) - 1 (i.e. the max positive
value which fits into a s64). See clockevents_program_event().
So this check needs to be:
u64 clc = (u64)latch << sft;
if ((s64)clc < 0 || (clc >> sft ) != latch)
clc = (1 << 63) - 1;
And the above rounding magic, which has to be applied after this
needs to take the following condition into account as well:
(1 << 63) - 1 - clc >= mult - 1
If that's not true, we can't do the rounding add, but we know that
we are well at the upper limit of the hardware, so no issue
either.
> > > > for boundary violation and can limit "clc" to (1 << 63) - 1 before the
> > > Where does this magic constant come from?
> >
> > Rolling my magic hex dice gave me that.
> Wow, how many sides does your dice have? Couldn't it have choosen
> (u64)-1 for improved results?
No it's restricted to s64 positiv values due to software
limitations. See above.
Thanks,
tglx
next prev parent reply other threads:[~2013-09-18 22:01 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-13 13:02 [PATCH] [PATCH] clocksource: tcb: fix min_delta calculation Marc Kleine-Budde
[not found] ` <20130917095600.GJ26819@ludovic.desroches@atmel.com>
2013-09-17 10:04 ` Russell King - ARM Linux
2013-09-17 11:26 ` Thomas Gleixner
[not found] ` <20130917130153.GL26819@ludovic.desroches@atmel.com>
2013-09-17 21:15 ` [PATCH] clockevents: Sanitize ticks to nsec conversion Thomas Gleixner
2013-09-17 22:25 ` Marc Kleine-Budde
2013-09-17 23:20 ` Thomas Gleixner
2013-09-18 8:56 ` Uwe Kleine-König
2013-09-18 9:38 ` Thomas Gleixner
2013-09-18 15:09 ` Uwe Kleine-König
2013-09-18 22:01 ` Thomas Gleixner [this message]
2013-09-19 10:02 ` Uwe Kleine-König
2013-09-19 10:15 ` Thomas Gleixner
2013-09-19 12:48 ` Uwe Kleine-König
2013-09-19 13:12 ` Thomas Gleixner
2013-09-19 14:30 ` Thomas Gleixner
2013-09-19 20:03 ` Uwe Kleine-König
2013-09-20 9:56 ` Thomas Gleixner
2013-09-20 20:41 ` Uwe Kleine-König
2013-09-20 21:30 ` Thomas Gleixner
2013-09-24 19:50 ` [PATCH v2] " Uwe Kleine-König
2013-09-24 21:11 ` Timekeeping on at91rm9200 [Was: [PATCH v2] clockevents: Sanitize ticks to nsec conversion] Uwe Kleine-König
2013-10-04 10:00 ` Nicolas Ferre
2013-09-24 21:16 ` [PATCH v2] clockevents: Sanitize ticks to nsec conversion Uwe Kleine-König
2013-10-08 10:08 ` Marc Kleine-Budde
2013-10-08 15:31 ` [GIT PULL] fixes for integer rounding in timer core (Was: [PATCH v2] clockevents: Sanitize ticks to nsec conversion) Uwe Kleine-König
2013-10-14 7:34 ` [GIT PULL] fixes for integer rounding in timer core Uwe Kleine-König
2013-10-16 14:19 ` Nicolas Ferre
2013-10-21 7:12 ` Uwe Kleine-König
2013-10-21 20:53 ` Daniel Lezcano
2013-10-23 10:56 ` [tip:timers/urgent] clockevents: Sanitize ticks to nsec conversion tip-bot for Thomas Gleixner
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=alpine.DEB.2.02.1309182201000.4089@ionos.tec.linutronix.de \
--to=tglx@linutronix.de \
--cc=john.stultz@linaro.org \
--cc=kernel@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=ludovic.desroches@atmel.com \
--cc=marc.pignat@hevs.ch \
--cc=mkl@pengutronix.de \
--cc=nicolas.ferre@atmel.com \
--cc=ronald.wahl@raritan.com \
--cc=u.kleine-koenig@pengutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®