* [PATCH 0/5] clocksource patches
@ 2006-04-03 19:54 Roman Zippel
2006-04-03 20:08 ` Roman Zippel
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Roman Zippel @ 2006-04-03 19:54 UTC (permalink / raw)
To: johnstul; +Cc: linux-kernel, Andrew Morton
Hi,
It unfortunately took a bit longer when I planned, but here is now an
update to the clocksource patches.
Patch 1 depends on the generic clocksource patches.
Patches 2-4 are a replacement for these patches in -mm:
time-use-clocksource-infrastructure-for-update_wall_time.patch
time-use-clocksource-infrastructure-for-update_wall_time-mark-few-functions-as-__init.patch
time-let-user-request-precision-from-current_tick_length.patch
time-use-clocksource-abstraction-for-ntp-adjustments.patch
time-introduce-arch-generic-time-accessors.patch
Patch 5 depends on the clocksource drivers.
Some more notes about the patches:
1. generic clocksource updates:
The most important change is probably clocksource_get_nsec_offset(), it
returns the nsec part of the realtime clock and is adjusted once a second.
Other time services can be built on top of this and also only have to be
updated once a second via second_overflow(). I changed the return value to
an unsigned long which gives us a 3 second window, which should be more
than enough (anyone not allowing the timer interrupt for that long gets
what he is asking for). This function should become clocksource specific
so arch/clocks can optimize this function themselves (e.g. changing
resolution, making some parameters constant). The generic clocksource
currently still deals a bit too much with cycles, more of this should be
moved into the clocksource drivers (using library functions).
I'm also still interested in opinions about different possibilities to
organize the clocksource infrastructure (although I'd more appreciate
pro/con arguments than outright rejections). One possibility here would be
to also shorten the function names a bit (clocksource_ is a lot to type :)
), cs_... or clock_... would IMO work too.
2. periodic clocksource update
I updated the error adjustment algorithm to be more robust and optimized
it a bit for the more common cases. It does everything in 64bit right now,
which is fine for 64bit archs and it allows resolutions of less then
1nsec, but as long as e.g. gettimeofday() takes longer than 1nsec that's
a little wasteful and nobody will see a difference if we "restrict" the
resolution to 1nsec, which would allow to keep parts of it in 32bit.
I also kept it separate from the do_timer() callback and simply created a
new callback function, which archs can use. This makes it less likely to
break any existing setup and even allows to coexists both methods until
archs have been completely converted.
The userspace version I used to test this can be found at
http://www.xs4all.nl/~zippel/ntp/clocktest.c
Another general comment from an arch/driver specific perspective: right
now everything is rather concentrated on getting the time, but AFAICT it's
more common that the subsystem which is used to read the time is also used
as timer (i.e. for the scheduler tick), this means the clocksource driver
should also include the interrupt setup. Consequently this means the
update callback isn't sufficient anymore and we need at least something
like start/stop callbacks. This also means the jiffie clocksource becomes
basically obsolete, since every arch already needs at least a basic
clocksource to provide the scheduler tick (which is setup via
time_init()).
i386 is currently rather hardcoded to use the i8253 timer, but AFAIK it
would be desirable to e.g. use HPET for that (especially for hrtimer).
Something like TSC should internally use another clocksource to provide
the timer interrupt. Anyway, i386 is quite a mess here right now and I can
understand that you wanted to stay away from it with the generic
gettimeofday infrastructure. :-)
This is not important right now, but I wanted to mention it, it's IMO
something to keep in mind for the next steps and what at least I'll
look out for.
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-03 19:54 [PATCH 0/5] clocksource patches Roman Zippel
@ 2006-04-03 20:08 ` Roman Zippel
2006-04-04 4:53 ` Thomas Gleixner
2006-04-07 17:57 ` john stultz
2 siblings, 0 replies; 16+ messages in thread
From: Roman Zippel @ 2006-04-03 20:08 UTC (permalink / raw)
To: johnstul; +Cc: linux-kernel, Andrew Morton
Hi,
Below is a first draft of some documentation which hopefully helps to
better understand the clock update function. It tries to introduce the
various concepts in small logical steps from the basic xtime updates to
the continuous clocks with full error adjustment.
It's still rather raw, but it contains all the information one has to
understand to adjust and customize the clock update code.
Feedback welcome. :)
bye, Roman
There are three basic time variables related to time management:
- cycles: managed by the hardware clock
- ntp_time: managed by the NTP system and is updated in regular
intervals (ticks)
- xtime: local base time as used by gettimeofday
Each variable is regularly updated:
- cycle_update: defines the basic tick frequency and is initialized with
(frequency / HZ)
- ntp_update: is calculated by the NTP system
- xtime_update: is derived from cycle_update using a conversion factor
(cycle_update*mult)
gettimeofday uses xtime and the cycle counter to calculate the current
time:
timeofday = xtime + cycle_offset * mult;
cycle_offset is the offset to the last timer tick and mult is a fixed
point conversion factor from cycles to seconds. mult is initialized
based on the equivalence of 1 sec to frequency cycles:
1 sec = frequency * mult
mult = 10^9 nsec / frequency
Time is updated at every tick (after cycle_update cycles), which for a
simple system system looks like this:
xtime = ntp_time += ntp_update;
if (xtime.tv_nsec >= NSEC_PER_SEC) {
ntp_time -= NSEC_PER_SEC;
xtime.tv_nsec -= NSEC_PER_SEC;
xtime.tv_sec++;
second_overflow();
}
xtime and ntp_time are basically identical, which means at every update
step gettimeofday can jump by a small error value (ntp_update -
xtime_update). To avoid this jump we have to update ntp_time and xtime
separately:
ntp_time += ntp_update;
xtime += cycle_update * mult;
if (xtime.tv_nsec >= NSEC_PER_SEC) {
ntp_time -= NSEC_PER_SEC;
xtime.tv_nsec -= NSEC_PER_SEC;
xtime.tv_sec++;
second_overflow();
}
error = ntp_time - xtime;
mult_adj = error / cycle_update;
mult += mult_adj;
This produces an error between ntp_time and xtime and to keep both
synchronized, we have to modify mult (the only other variable in the
timeofday calculation). mult_adj is the difference between the new and
old multiplier and is derived from:
cycle_update * mult_new = cycle_update * mult + error
One big problem with this is that we only look at the current error,
which causes the multiplier to oscillate if ntp_update changes (the
adjustments are applied too late), so it's better to look ahead to the
next update:
ntp_time += ntp_update;
xtime += cycle_update * mult;
if (xtime.tv_nsec >= NSEC_PER_SEC) {
ntp_time -= NSEC_PER_SEC;
xtime.tv_nsec -= NSEC_PER_SEC;
xtime.tv_sec++;
second_overflow();
}
error = (ntp_time + ntp_update) - (xtime + cycle_update * mult);
mult_adj = error / cycle_update;
mult += mult_adj;
The important thing here is that the error calculation happens after
calling second_overflow(), which is the main callback for the NTP system
to update ntp_update.
Instead of calculating the complete error every time, we can also update
the error incrementally and avoid maintaining ntp_time:
xtime += cycle_update * mult;
if (xtime.tv_nsec >= NSEC_PER_SEC) {
xtime.tv_nsec -= NSEC_PER_SEC;
xtime.tv_sec++;
second_overflow();
}
error += ntp_update - cycle_update * mult;
mult_adj = error / cycle_update;
mult += mult_adj;
error -= cycle_update * mult_adj;
This is probably the step, which makes the calculation less obvious as
there is no explicit ntp_time anymore and is instead maintained via the
difference to xtime. It's very important to keep in mind that the error
is for the next update step, so if we change the multiplier for the next
tick, we also have to adjust the error:
cycle_update * mult - cycle_update * mult_new
as at the next step xtime is not advanced by (cycle_update * mult)
anymore but (cycle_update * mult_new) instead.
Note that although we don't maintain the ntp_time value anymore, the
complexity has only shifted to the error calculation, but since under
normal circumstances (clock is synchronized and stable) adjustments to
the multiplier are less common events, the calculation becomes cheaper
with a simple error update and occasional error adjustments.
This is already sufficient for simple systems, but interrupts can delay
the update step, so that we can see small time jumps due to the
multiplier adjustments. To avoid this we have to include the current
cycle_offset into the calculation:
xtime += cycle_update * mult;
if (xtime.tv_nsec >= NSEC_PER_SEC) {
xtime.tv_nsec -= NSEC_PER_SEC;
xtime.tv_sec++;
second_overflow();
}
error += ntp_update - cycle_update * mult;
mult_adj = error / cycle_update;
mult += mult_adj;
xtime -= cycle_offset * mult_adj;
error -= (cycle_update - cycle_offset) * mult_adj;
We adjust xtime to keep the current time the same after the multiplier
change:
xtime_new + cycle_offset * mult_new = xtime + cycle_offset * mult
Since we change xtime, we don't have to forget to also adjust the error
by the same amount.
If the time is now updated in very irregular intervals, it can happen
that we skipped an update step, where we can either just repeat
everything or skip a few error adjustment steps and do them at the end
instead:
while (cycle_offset >= cycle_update) {
cycles_last += cycle_update;
cycle_offset -= cycle_update;
xtime += cycle_update * mult;
if (xtime.tv_nsec >= NSEC_PER_SEC) {
xtime.tv_nsec -= NSEC_PER_SEC;
xtime.tv_sec++;
second_overflow();
}
error += ntp_update - cycle_update * mult;
}
mult_adj = error / cycle_update;
mult += mult_adj;
xtime -= cycle_offset * mult_adj;
error -= (cycle_update - cycle_offset) * mult_adj;
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-03 19:54 [PATCH 0/5] clocksource patches Roman Zippel
2006-04-03 20:08 ` Roman Zippel
@ 2006-04-04 4:53 ` Thomas Gleixner
2006-04-04 19:06 ` Roman Zippel
2006-04-07 17:57 ` john stultz
2 siblings, 1 reply; 16+ messages in thread
From: Thomas Gleixner @ 2006-04-04 4:53 UTC (permalink / raw)
To: Roman Zippel; +Cc: johnstul, linux-kernel, Andrew Morton, Ingo Molnar
On Mon, 2006-04-03 at 21:54 +0200, Roman Zippel wrote:
> Another general comment from an arch/driver specific perspective: right
> now everything is rather concentrated on getting the time, but AFAICT it's
> more common that the subsystem which is used to read the time is also used
> as timer (i.e. for the scheduler tick), this means the clocksource driver
> should also include the interrupt setup.
I don't think so. Coupling the clock sources to clock event sources is
wrong. In many systems the clock event source delivering the next event
interrupt - either periodic or per event programmed - is independend
from the clock source which is used to read the time.
Also we want to distribute multiple clock event sources for various
services. Hardwiring those into combos is counter productive.
> i386 is currently rather hardcoded to use the i8253 timer, but AFAIK it
> would be desirable to e.g. use HPET for that (especially for hrtimer).
> Something like TSC should internally use another clocksource to provide
> the timer interrupt.
This is exactly the result of such an artificial combo. "Use internally
something else." Thats fundamentally wrong and violates every basic rule
of abstraction.
> Anyway, i386 is quite a mess here right now and I can
> understand that you wanted to stay away from it with the generic
> gettimeofday infrastructure. :-)
He ? John addressed the clock source (timeofday) related problem in
x386. He never claimed that his timeofday code is solving the clock
event source problem. gettimeofday() exactly does what it says: it gets
the time of day. And it does it independend of any interrupt source in
the first place.
Clock event sources need their own independent abstraction layer, as one
can be found in my high resolution timer patch queue. There is
interaction between the timekeeping and the next event interrupt
programming, but it's important to keep them seperate.
How should a combo solution allow to add special hardware, which
provides only one of the services ? By using "something else
internally" ? No, thanks.
tglx
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-04 4:53 ` Thomas Gleixner
@ 2006-04-04 19:06 ` Roman Zippel
2006-04-05 11:22 ` Thomas Gleixner
0 siblings, 1 reply; 16+ messages in thread
From: Roman Zippel @ 2006-04-04 19:06 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: johnstul, linux-kernel, Andrew Morton, Ingo Molnar
Hi,
On Tue, 4 Apr 2006, Thomas Gleixner wrote:
> On Mon, 2006-04-03 at 21:54 +0200, Roman Zippel wrote:
> > Another general comment from an arch/driver specific perspective: right
> > now everything is rather concentrated on getting the time, but AFAICT it's
> > more common that the subsystem which is used to read the time is also used
> > as timer (i.e. for the scheduler tick), this means the clocksource driver
> > should also include the interrupt setup.
>
> I don't think so. Coupling the clock sources to clock event sources is
> wrong. In many systems the clock event source delivering the next event
> interrupt - either periodic or per event programmed - is independend
> from the clock source which is used to read the time.
Why? In order to program a clock event you have to be able to read the
clock somehow. In many systems it's the same hardware.
> Also we want to distribute multiple clock event sources for various
> services. Hardwiring those into combos is counter productive.
What suggest I want to hardwire everything?
> > i386 is currently rather hardcoded to use the i8253 timer, but AFAIK it
> > would be desirable to e.g. use HPET for that (especially for hrtimer).
> > Something like TSC should internally use another clocksource to provide
> > the timer interrupt.
>
> This is exactly the result of such an artificial combo. "Use internally
> something else." Thats fundamentally wrong and violates every basic rule
> of abstraction.
Why and what "basic rule of abstraction"?
> Clock event sources need their own independent abstraction layer, as one
> can be found in my high resolution timer patch queue. There is
> interaction between the timekeeping and the next event interrupt
> programming, but it's important to keep them seperate.
>
> How should a combo solution allow to add special hardware, which
> provides only one of the services ? By using "something else
> internally" ? No, thanks.
Again, why? Please explain.
Thomas, I would really appreciate if you actually started to argue your
point instead of just disagreeing with me every time. I have no problem to
admit that I'm wrong, but it takes a bit more than you just saying it is
so.
This is not the first time and I have a really hard time to actually get
you to explain your position and then it's even harder to discuss this
with you. This is very frustrating and I can't lose the feeling that you
think I'm a complete idiot, who should know better and isn't worth the
time to answer, which makes me feel disrespected.
I don't mind really that you mainly just disagree with me and if you
argued your point, it would make for some interesting and challenging
conversations, but this isn't possible if you only voice just your
disagreement.
For example above you bascially only state that your clock event source
is superior and the correct way of doing this without any explanation why
(and the "No, thanks." doesn't exactly imply that you're even interested
in alternatives). This may be true, but it still would be interesting to
know the advantages of keeping this separate. Why is it such a bad idea to
have a single base abstraction for reading and setting time(r)?
Do you really expect me to believe you just because you say so?
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-04 19:06 ` Roman Zippel
@ 2006-04-05 11:22 ` Thomas Gleixner
2006-04-05 13:40 ` Ingo Molnar
2006-04-05 20:44 ` Roman Zippel
0 siblings, 2 replies; 16+ messages in thread
From: Thomas Gleixner @ 2006-04-05 11:22 UTC (permalink / raw)
To: Roman Zippel; +Cc: johnstul, linux-kernel, Andrew Morton, Ingo Molnar
Roman,
> Thomas, I would really appreciate if you actually started to argue your
> point instead of just disagreeing with me every time. I have no problem to
> admit that I'm wrong, but it takes a bit more than you just saying it is
> so.
I on my side would appreciate, if you would stop to take every line I
write as a personal offense.
> For example above you bascially only state that your clock event source
> is superior and the correct way of doing this without any explanation why
> (and the "No, thanks." doesn't exactly imply that you're even interested
> in alternatives).
The question arises, who is not interested in alternatives. You are well
aware about the efforts others made, but you don't even think about
working together with them. Do you really expect people to jump on your
train, when you entirely ignore their work and efforts and just propose
your own view of the world?
I did nowhere say that I'm not interested in alternative solutions. You
interpret it into my words for whatever reason.
Your way to rip out a single statement of its context and making your
argument on that is simply annoying.
Thats the original quote:
> How should a combo solution allow to add special hardware, which
> provides only one of the services ? By using "something else
> internally" ? No, thanks.
It is entirely clear, that "No thanks" is related to "something else
internally".
Thats the point I made further up in my first reply. It was your
proposal to combine clock sources and clock events. This works nice
where both are in the same hardware device, but its not a compulsory
argument for a combined abstraction layer. You said that in case there
is one element missing (e.g. TSC has no clock event source) it should
internally use "something else".
That's excatly the point I'm referring to. Do you think that "Use
something else" is a real good and convincing technical argument? No,
such a statement is simply the evidence that your design is flawed.
I assume we agree that we want abstraction of clock soures (read time)
and clock event sources (periodic / next event interrupts).
Why are those seperate items ?
Looking at the various hardware implementations there are three types of
devices:
1. Read only devices (e.g. TSC)
2. Next interrupt only devices (e.g. various timer implementations on
SoC CPUs)
3. Devices which combine both functions
Building an abstraction layer which handles all device types requires
either
- that e.g. a read only device needs to be combined with a next
interrupt device in some way. This introduces artifical combos of
functionality which can and should be handled completely seperate.
or
- to handle all the corner cases where a device has to be handled which
only provides one of the functionalies. Also the selection of different
combinations of devices will introduce extra handling code.
Futhermore the functionalites of clock sources and clock event source
can be used completely independent. In case of a periodic event there is
no interaction with the clock source at all. The readout of the clock
source is independent of any kind of event.
So we have two functional domains, which provide a high level interface:
The clock source abstraction provides:
- gettimeofday()
- getmonotonic()
- settimeofday()
- clock skew adjustment functions()
The clock event source abstraction provides:
- setup periodic events()
- setup one shot events()
- associate services (function to call on an event) to a clock event
source
This is a clear seperation and there is no combined functionality.
The availability of devices which combine both functions is not changing
the clear functional seperation of clock sources and clock event sources
at all.
Programming one shot events might need information from the clock source
layer e.g. to calculate the delta to the next event, but it does not
need this information on a low level base. The information is read from
the high level interface. Moving this to the low level interfaces would
enforce particular combinations of clock sources and clock event sources
and remove the flexibility to use arbitrary combinations on a best fit
selection.
Back to your questions:
> Why? In order to program a clock event you have to be able to read the
> clock somehow. In many systems it's the same hardware.
Yes, it is the same hardware. It is not the same level of abstraction.
The next event is defined by a absolute time in human units (i.e.
nanoseconds). The delta to the next event is calculated by
delta = next_event - now
Then delta is converted to the time units of the underlying hardware
device.
You might argue, that you also can convert the next_event time to the
time units of the underlying hardware first and then caclulate the delta
for the next event interrupt hardware.
This is only true, when those devices are combined and it results in
different handling of the same problem for different combinations of
hardware or even restricts the possible combinations depending on the
implementation details. Thats why I said it violates the basic rule of
abstraction.
> Why and what "basic rule of abstraction"?
Whats abstraction ? The generic way to access a functional domain to
allow users of the functional domain to be hardware agnostic.
As I showed above there are two functional domains:
clock sources and clock event sources
The high level interfaces of the functional domains use an hardware
independent representation of time, i.e. human time units (nano
seconds). Any interaction between the functional domains also uses the
hardware independent representation.
This is the basic guarantee, that such abstraction layers are flexible
and of general use.
Interaction or interdependencies of functional domains are not a reason
to combine them into one "handle it all" domain.
tglx
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-05 11:22 ` Thomas Gleixner
@ 2006-04-05 13:40 ` Ingo Molnar
2006-04-05 20:44 ` Roman Zippel
1 sibling, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2006-04-05 13:40 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: Roman Zippel, johnstul, linux-kernel, Andrew Morton
* Thomas Gleixner <tglx@linutronix.de> wrote:
> > For example above you bascially only state that your clock event source
> > is superior and the correct way of doing this without any explanation why
> > (and the "No, thanks." doesn't exactly imply that you're even interested
> > in alternatives).
>
> The question arises, who is not interested in alternatives. You are
> well aware about the efforts others made, but you don't even think
> about working together with them. Do you really expect people to jump
> on your train, when you entirely ignore their work and efforts and
> just propose your own view of the world?
>
> I did nowhere say that I'm not interested in alternative solutions.
> You interpret it into my words for whatever reason.
just to explain it to everyone: the code Thomas refers to and which we
are working on is John's GTOD patchset with Thomas' high-resolution
timers patches ontop of it. [all of that (and more) is glued together in
the -rt tree as well].
Thomas' hrtimers queue (ontop of 2.6.16) is a practical, working
implementation of the clock-event design Thomas is talking about,
resulting in a working high-resolution timers solution that spans all
the relevant Linux APIs: nanosleep() and POSIX timers. So Thomas'
arguments derive straight from that experience.
for more details, the latest hrtimers code can be found at:
http://tglx.de/projects/hrtimers
the merge of the hrtimers subsystem into 2.6.16 was just the first step,
and the next steps are expressed in the patches above.
Ingo
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-05 11:22 ` Thomas Gleixner
2006-04-05 13:40 ` Ingo Molnar
@ 2006-04-05 20:44 ` Roman Zippel
2006-04-05 22:18 ` Thomas Gleixner
1 sibling, 1 reply; 16+ messages in thread
From: Roman Zippel @ 2006-04-05 20:44 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: johnstul, linux-kernel, Andrew Morton, Ingo Molnar
Hi,
On Wed, 5 Apr 2006, Thomas Gleixner wrote:
> > Thomas, I would really appreciate if you actually started to argue your
> > point instead of just disagreeing with me every time. I have no problem to
> > admit that I'm wrong, but it takes a bit more than you just saying it is
> > so.
>
> I on my side would appreciate, if you would stop to take every line I
> write as a personal offense.
Believe me, I'm trying very hard and I'm not easily offended, but you
don't exactly make it easy.
For example I get very little positive feedback from you and I'd be happy
if you gave me at least constructive criticism, but you mainly just
contradict me. An important indicator here is asking questions, you barely
ask me any questions, which would show you're interested in my opinion and
would help to avoid misunderstandings as shown further below.
> > For example above you bascially only state that your clock event source
> > is superior and the correct way of doing this without any explanation why
> > (and the "No, thanks." doesn't exactly imply that you're even interested
> > in alternatives).
>
> The question arises, who is not interested in alternatives. You are well
> aware about the efforts others made, but you don't even think about
> working together with them. Do you really expect people to jump on your
> train, when you entirely ignore their work and efforts and just propose
> your own view of the world?
First off please leave other people out of this, I get along with other
people quite well, it's you I continuously have these problems with.
Secondly considering my contributions to John's work, it's fucking rude of
you to accuse me of "not interested in alternatives" and "don't even
think about working together". There is a simple reason that e.g. I'm not
working on the -rt tree - lack of time. For weeks now I already had no
time to work on the m68k tree, for months now I already sit on a batch of
kconfig patches I'm trying to make ready. As long as your stuff doesn't
appear on lkml, I consider as in development and I spent my time on more
important things (which may be not so important to you).
> I did nowhere say that I'm not interested in alternative solutions. You
> interpret it into my words for whatever reason.
>
> Your way to rip out a single statement of its context and making your
> argument on that is simply annoying.
>
> Thats the original quote:
> > How should a combo solution allow to add special hardware, which
> > provides only one of the services ? By using "something else
> > internally" ? No, thanks.
>
> It is entirely clear, that "No thanks" is related to "something else
> internally".
The interesting part is that I never said "something else internally",
more specifically I said "internally use another clocksource". It's you
who made the generalization and then only talks about clock events, so
it's easy to come to the conclusion that the "No, thanks." is not related
to something specific I said, but to the generic "something else (than
clock events)". I had nothing "to rip out".
> Thats the point I made further up in my first reply. It was your
> proposal to combine clock sources and clock events.
This is the point were you could have saved us a lot of grief by simply
asking me instead of jumping to conclusions. Nowhere in my initial mail
did I make such a proposal, I'm not even mentioning clock events.
The original quote:
> > AFAICT it's
> > more common that the subsystem which is used to read the time is also used
> > as timer (i.e. for the scheduler tick), this means the clocksource driver
> > should also include the interrupt setup.
>
> I don't think so. Coupling the clock sources to clock event sources is
> wrong.
What I had in mind is the _current_ setup, that e.g. the scheduler tick
can be generated by a clock event is a possibility, but since your
clockevent patch is not even in -mm, it wasn't something I had in mind
when I wrote this comment. This comment was specifically about the
_current_ way time.c sets up the timer interrupt and i8253.c sets up the
timer hardware.
I also specifically said "This is not important right now, but ...
something to keep in mind" to indicate this needs further discussion,
nowhere did I ever exclude the possibility to do this via clock events,
but you just jumped at me with "this is wrong".
> Why are those seperate items ?
>
> Looking at the various hardware implementations there are three types of
> devices:
>
> 1. Read only devices (e.g. TSC)
> 2. Next interrupt only devices (e.g. various timer implementations on
> SoC CPUs)
> 3. Devices which combine both functions
>
> Building an abstraction layer which handles all device types requires
> either
>
> - that e.g. a read only device needs to be combined with a next
> interrupt device in some way. This introduces artifical combos of
> functionality which can and should be handled completely seperate.
>
> or
>
> - to handle all the corner cases where a device has to be handled which
> only provides one of the functionalies. Also the selection of different
> combinations of devices will introduce extra handling code.
Neither excludes a basic clock source abstraction, which can create any
kind of clock events. The basic question is should any clock source be
able to create every kind of clock events?
The problem here is that we may have to synchronize reading time with the
timer interrupt. To make an extreme example let's assume the TSC clock is
updated every 1msec and the PIT generates an interrupt every 1.01msec,
this means jiffies is updated every 100th interrupt by 2. Also the NTP
error adjustment algorithm works better with small offsets, my latest
version compensates better for that, but a smaller offset still means a
smaller jitter.
These kinds of problems I had in mind when I wrote "Something like TSC
should internally use another clocksource" and if you had asked I could
have explained this, but I had no chance as you simply jumped to your own
conclusions. :-(
> So we have two functional domains, which provide a high level interface:
>
> The clock source abstraction provides:
> - gettimeofday()
> - getmonotonic()
> - settimeofday()
> - clock skew adjustment functions()
>
> The clock event source abstraction provides:
> - setup periodic events()
> - setup one shot events()
> - associate services (function to call on an event) to a clock event
> source
>
> This is a clear seperation and there is no combined functionality.
Unfortunately it's not that simple, e.g. generating gettimeofday()
requires a periodic event. At some point you have to combine
functionality, whether it's done inside the clocksource or by something
else is a different discussion. My proposal to do it inside the clock
source was because we don't have that "something else" yet (which may be
your clock events, I don't know).
I have to skip the rest of your mail, as it's so generic and so out of
context that I don't really disagree with it, if there was something
important, please put back it into some context.
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-05 20:44 ` Roman Zippel
@ 2006-04-05 22:18 ` Thomas Gleixner
0 siblings, 0 replies; 16+ messages in thread
From: Thomas Gleixner @ 2006-04-05 22:18 UTC (permalink / raw)
To: Roman Zippel; +Cc: johnstul, linux-kernel, Andrew Morton, Ingo Molnar
Roman,
On Wed, 2006-04-05 at 22:44 +0200, Roman Zippel wrote:
> What I had in mind is the _current_ setup, that e.g. the scheduler tick
> can be generated by a clock event is a possibility, but since your
> clockevent patch is not even in -mm, it wasn't something I had in mind
> when I wrote this comment. This comment was specifically about the
> _current_ way time.c sets up the timer interrupt and i8253.c sets up the
> timer hardware.
> I also specifically said "This is not important right now, but ...
> something to keep in mind" to indicate this needs further discussion,
> nowhere did I ever exclude the possibility to do this via clock events,
> but you just jumped at me with "this is wrong".
Can we stop missquoting on both sides please ? I did not jump in. I
said:
> I don't think so. Coupling the clock sources to clock event sources is
> wrong.
I unfortunately forgot to add an IMHO to every single sentence, but "I
don't think so." should have made it clear, that this is my opinion.
Maybe my knowledge of the English language is worse than I thought.
> > Why are those seperate items ?
> >
> > Looking at the various hardware implementations there are three types of
> > devices:
> >
> > 1. Read only devices (e.g. TSC)
> > 2. Next interrupt only devices (e.g. various timer implementations on
> > SoC CPUs)
> > 3. Devices which combine both functions
> >
> > Building an abstraction layer which handles all device types requires
> > either
> >
> > - that e.g. a read only device needs to be combined with a next
> > interrupt device in some way. This introduces artifical combos of
> > functionality which can and should be handled completely seperate.
> >
> > or
> >
> > - to handle all the corner cases where a device has to be handled which
> > only provides one of the functionalies. Also the selection of different
> > combinations of devices will introduce extra handling code.
>
> Neither excludes a basic clock source abstraction, which can create any
> kind of clock events. The basic question is should any clock source be
> able to create every kind of clock events?
At least should the design allow that. Making restrictions in such a
layer upfront due to requirements of some known hardware devices would
be bad.
> The problem here is that we may have to synchronize reading time with the
> timer interrupt. To make an extreme example let's assume the TSC clock is
> updated every 1msec and the PIT generates an interrupt every 1.01msec,
> this means jiffies is updated every 100th interrupt by 2. Also the NTP
> error adjustment algorithm works better with small offsets, my latest
> version compensates better for that, but a smaller offset still means a
> smaller jitter.
Why does this require a hard coupled design ? You want a periodic event
for X with as much precision as available. Let the system choose one
which fits this best.
> > This is a clear seperation and there is no combined functionality.
>
> Unfortunately it's not that simple, e.g. generating gettimeofday()
> requires a periodic event.
It does not necessarily require a periodic event. It depends on the type
of clock source you are using and the requirements of synchronization.
The DCF-77 card in one of my boxen gives me auto sychronized time with
1nsec resolution without any periodic event. Also embedded systems which
do not use NTP do not need a periodic event for gettimeofday() when
there is a continous clock source available.
If the NTP mechanisms needs a precise periodic event, then it can
request it from the layer which manages those events.
> At some point you have to combine
> functionality, whether it's done inside the clocksource or by something
> else is a different discussion. My proposal to do it inside the clock
> source was because we don't have that "something else" yet (which may be
> your clock events, I don't know).
So we move it into clock source because there is nothing else right
now ? That sounds like moving the mess you identified in x386 from there
to a another place.
IMO this is well worth a discussion how we want to solve this in a solid
and generic way.
> I have to skip the rest of your mail, as it's so generic and so out of
> context that I don't really disagree with it, if there was something
> important, please put back it into some context.
Sorry Roman, your way of discussion is not understandable to me. On one
hand you ask for explanations. When you get them, you just brush them
aside. Thanks for reminding me that my efforts to communicate with you
just produce unimportant blurb.
tglx
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-03 19:54 [PATCH 0/5] clocksource patches Roman Zippel
2006-04-03 20:08 ` Roman Zippel
2006-04-04 4:53 ` Thomas Gleixner
@ 2006-04-07 17:57 ` john stultz
2006-04-27 20:33 ` Roman Zippel
2 siblings, 1 reply; 16+ messages in thread
From: john stultz @ 2006-04-07 17:57 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
On Mon, 2006-04-03 at 21:54 +0200, Roman Zippel wrote:
> Some more notes about the patches:
Hey Roman,
I'll reply to more specifics to the patches themselves, but I'll try to
get some general clarifications here.
> 1. generic clocksource updates:
> The most important change is probably clocksource_get_nsec_offset(), it
> returns the nsec part of the realtime clock and is adjusted once a second.
> Other time services can be built on top of this and also only have to be
> updated once a second via second_overflow(). I changed the return value to
> an unsigned long which gives us a 3 second window, which should be more
> than enough (anyone not allowing the timer interrupt for that long gets
> what he is asking for). This function should become clocksource specific
> so arch/clocks can optimize this function themselves (e.g. changing
> resolution, making some parameters constant). The generic clocksource
> currently still deals a bit too much with cycles, more of this should be
> moved into the clocksource drivers (using library functions).
I'm still not convinced for the need of clocksource specific
get_nsec_offset() functions. I really want to limit the clocksource
structure to be as stateless as possible and to only provide an
abstraction to the hardware counter below.
But clearly you are pretty concerned about it, so maybe could you share
the case you have in mind where it would be necessary?
> I'm also still interested in opinions about different possibilities to
> organize the clocksource infrastructure (although I'd more appreciate
> pro/con arguments than outright rejections). One possibility here would be
> to also shorten the function names a bit (clocksource_ is a lot to type :)
> ), cs_... or clock_... would IMO work too.
I *much* prefer the clarity of clocksource over the wear and tear typing
it might take on my fingers.
> 2. periodic clocksource update
> I updated the error adjustment algorithm to be more robust and optimized
> it a bit for the more common cases. It does everything in 64bit right now,
> which is fine for 64bit archs and it allows resolutions of less then
> 1nsec, but as long as e.g. gettimeofday() takes longer than 1nsec that's
> a little wasteful and nobody will see a difference if we "restrict" the
> resolution to 1nsec, which would allow to keep parts of it in 32bit.
>
> I also kept it separate from the do_timer() callback and simply created a
> new callback function, which archs can use. This makes it less likely to
> break any existing setup and even allows to coexists both methods until
> archs have been completely converted.
One of the reasons I did the significant rework of the TOD patches was
so that we could generically introduce the clocksource abstraction first
(using jiffies) for all arches. I feel this provides a much smoother
transition to the generic timekeeping code (and greatly reduces the
amount of CONFIG_GENERIC_TIME specific code), so I'm not sure I
understand why you want to go back to separate do_timer() functions.
I guess what I'm asking for is what was wrong with the way my code did
it? What breakage are you concerned about?
> Another general comment from an arch/driver specific perspective: right
> now everything is rather concentrated on getting the time, but AFAICT it's
> more common that the subsystem which is used to read the time is also used
> as timer (i.e. for the scheduler tick), this means the clocksource driver
> should also include the interrupt setup. Consequently this means the
> update callback isn't sufficient anymore and we need at least something
> like start/stop callbacks. This also means the jiffie clocksource becomes
> basically obsolete, since every arch already needs at least a basic
> clocksource to provide the scheduler tick (which is setup via
> time_init()).
> i386 is currently rather hardcoded to use the i8253 timer, but AFAIK it
> would be desirable to e.g. use HPET for that (especially for hrtimer).
> Something like TSC should internally use another clocksource to provide
> the timer interrupt. Anyway, i386 is quite a mess here right now and I can
> understand that you wanted to stay away from it with the generic
> gettimeofday infrastructure. :-)
> This is not important right now, but I wanted to mention it, it's IMO
> something to keep in mind for the next steps and what at least I'll
> look out for.
Thomas has already commented on this, and maybe we both misunderstand
what your suggesting here, but I am pretty hesitant to bind the clock
source / hardware interrupt timer code together. The reason for that is
in my experience w/ i386 (and I'll take my lumps for my part in the i386
timekeeping mess) the number of combinations of clock/timers is
something like: PIT/PIT, TSC/PIT, CYCLONE/PIT, ACPIPM/PIT, HPET/PIT,
TSC/HPET, HPET/HPET. And with some of Andi's patches x86-64 patches you
can do them all over /APIC.
My goal with the clocksources is to take just the counter aspect of any
hardware and export it generically so we can use that inside generic
code. I also would support a similar timer interrupt source abstraction,
like what Thomas has started in his clockevent patches in his hrt
patchset. The hope being we can later freely mix and match
clocksources/clockevents, allowing for some of the features needed for
dynamic ticks and virtualization.
Do these concerns make sense to you? Or was it something else you were
suggesting?
thanks
-john
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-07 17:57 ` john stultz
@ 2006-04-27 20:33 ` Roman Zippel
2006-05-06 2:04 ` john stultz
0 siblings, 1 reply; 16+ messages in thread
From: Roman Zippel @ 2006-04-27 20:33 UTC (permalink / raw)
To: john stultz; +Cc: linux-kernel, Andrew Morton
Hi,
On Fri, 7 Apr 2006, john stultz wrote:
Sorry about the long delay, I was engrossed in other problems and I had to
check a few things for a proper reply, which I've put off. Anyway, sorry. :)
> I'm still not convinced for the need of clocksource specific
> get_nsec_offset() functions. I really want to limit the clocksource
> structure to be as stateless as possible and to only provide an
> abstraction to the hardware counter below.
>
> But clearly you are pretty concerned about it, so maybe could you share
> the case you have in mind where it would be necessary?
The main point is performance. This is a very important function and your
approach requires to assume the worst case, e.g. it has to be done in
64bit, which OTOH can be easily optimized in the driver.
I can understand that you want to keep the clock driver as simple as
possible, but that's not how Linux works - we usually don't abstract away
every detail. It's always a compromise between simplicity, flexibility and
performance. This means sometimes we do leave things to the drivers which
can simply use some generic functions if they don't have any special
requirements.
By pushing all the complexity into a middle layer you're running the risk
of creating a bloated middle layer with a big runtime complexity, which
has to deal with every little special case. Pushing at least part of this
complexity into the driver allows us to make some decisions already at
compile time and thus reducing runtime complexity.
Simply look at the various kernel APIs, middle layers tend to be rather
light weight, provide _common_ services and leave the real work to the
drivers, e.g. the fs layer does the path translation and the basic
locking, but we have no special handling for block vs net fs drivers,
instead we provide library functions which also deal with such special
cases as support for holes in files.
I really don't understand your problem with a clocksource specific
nsec_offset(), the author already has to provide most of the basic
parameters, it's not that difficult to put them together and for the
really lazy we can provide a:
my_clock_nsec_offset(struct clocksource *cs)
{
return generic_nsec_offset(cs, my_get_cycles(), MASK, SHIFT);
}
this is _very_ simple and if some of the parameters are constant you
already saved a few cycles.
John, we have to find some compromise here, but I think sacrificing
everything to driver simplicity is IMO a huge mistake. A "simple" driver
gives you a lot of flexibility on the generic side, but you remove this
flexibility from the driver side, i.e. if a driver doesn't fit into this
cycle model (e.g. tick based drivers) it has to do extra work to provide
this abstraction.
A good abstraction should concentrate on the _common_ properties and I
don't think that the continous cycle model is a good general abstraction
for all types of clocks. Tick based clocks are already more complex due
the extra work needed to emulate the cycle counter. Some clocks may
already provide a nsec value (e.g. virtual clocks in a virtualized
environment), where your generic nsec calculation is a complete waste of
time. A common property of all clocks is that we want a nsec value from
them, so why not simply ask the clock for some kind of nsec value and
provide the clock driver with the necessary library routines to convert
the cycle value to a nsec value, where you actually have the necessary
information to create efficient code. As long as you try to pull the cycle
model into the generic model it will seriously suck from a performance
perspective, as you separate the cycle value from the information how to
deal with it efficiently.
> > I'm also still interested in opinions about different possibilities to
> > organize the clocksource infrastructure (although I'd more appreciate
> > pro/con arguments than outright rejections). One possibility here would be
> > to also shorten the function names a bit (clocksource_ is a lot to type :)
> > ), cs_... or clock_... would IMO work too.
>
> I *much* prefer the clarity of clocksource over the wear and tear typing
> it might take on my fingers.
What is the special meaning of "clocksource" vs e.g. just "clock"?
> > I also kept it separate from the do_timer() callback and simply created a
> > new callback function, which archs can use. This makes it less likely to
> > break any existing setup and even allows to coexists both methods until
> > archs have been completely converted.
>
> One of the reasons I did the significant rework of the TOD patches was
> so that we could generically introduce the clocksource abstraction first
> (using jiffies) for all arches. I feel this provides a much smoother
> transition to the generic timekeeping code (and greatly reduces the
> amount of CONFIG_GENERIC_TIME specific code), so I'm not sure I
> understand why you want to go back to separate do_timer() functions.
Apropos code size: I checked the generated code size of timer.o (default
i386 config), before it was 3248 bytes, with your patches it goes to 5907
bytes and by disabling CONFIG_GENERIC_TIME it still is 4554. With my
patches it's 4767/4347 bytes (removing the old time code saves another
315 bytes).
In my version I was very careful to keep the common interrupt paths as
short as possible, so that most of this code is not even executed most of
the time. You can't just "hope" that gcc does the work for you (especially
with 64bit math), you actually have to check the code and you would have
the noticed the bloated code it generates.
Keeping the old time code separate makes it easier to optimize the new
code and is more flexible, e.g. for a tick based clock source we can
provide an update function which does something like this:
clocksource_update_tick();
clocksource_adjust(0);
This means the loop is gone and the adjustment code becomes simpler due to
the constant offset.
> Thomas has already commented on this, and maybe we both misunderstand
> what your suggesting here, but I am pretty hesitant to bind the clock
> source / hardware interrupt timer code together. The reason for that is
> in my experience w/ i386 (and I'll take my lumps for my part in the i386
> timekeeping mess) the number of combinations of clock/timers is
> something like: PIT/PIT, TSC/PIT, CYCLONE/PIT, ACPIPM/PIT, HPET/PIT,
> TSC/HPET, HPET/HPET. And with some of Andi's patches x86-64 patches you
> can do them all over /APIC.
I really don't want to hardcode anything, it's not my intention to
recreate a mess similiar to timer_tsc.c.
My basic idea of clock abstraction would be something you can use to read
the time and which you can set to generate an interrupt. This doesn't mean
every clock driver has to provide everything, it should be not that
difficult to _dynamically_ bind two drivers to provide this functionality
(where and how this is done is not important here).
In the simple cases clock and timer functionality are provided by the same
hardware and I really don't understand where the advantage is to
artifically separate this functionality, _if_ this comes from the same
hardware. If I want to write a driver for a _simple_ timer chip, I want to
export its functionality via one interface, so e.g. I can use it as the
system clock, this means the driver simply registers itself as a clock
driver and the generic system sets it up as a system clock. This is what I
need from an arch perspective and I want to keep this as simple as
possible and splitting this simple thing into different abstractions runs
contrary to that.
> My goal with the clocksources is to take just the counter aspect of any
> hardware and export it generically so we can use that inside generic
> code. I also would support a similar timer interrupt source abstraction,
> like what Thomas has started in his clockevent patches in his hrt
> patchset. The hope being we can later freely mix and match
> clocksources/clockevents, allowing for some of the features needed for
> dynamic ticks and virtualization.
I have looked at the clockevent code, I can see what I does, but I don't
really understand why it does it this way, it simply doesn't match my
expectations/needs from a clock. The code is barely documented and
there is no explanation of the basic design ideas and requirements it's
based on. As long as this is missing it's useless to me and my attempts so
far at getting Thomas to explain his code have been rather fruitless. :(
It's possible it's some ingenious piece of code, but if I have trouble
understanding the code, I don't think I'm going to be the only one.
Maybe I have a completely different idea of this, which prevents me from
understanding this, so it would really help if someone would explain the
advantages of the clocksource/clockevent abstraction and connect the dots
of how it fits into the general model between clock hardware/driver and
the generic kernel clock/timer services.
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-04-27 20:33 ` Roman Zippel
@ 2006-05-06 2:04 ` john stultz
2006-05-06 16:25 ` Roman Zippel
0 siblings, 1 reply; 16+ messages in thread
From: john stultz @ 2006-05-06 2:04 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
On Thu, 2006-04-27 at 22:33 +0200, Roman Zippel wrote:
> I really don't understand your problem with a clocksource specific
> nsec_offset(), the author already has to provide most of the basic
> parameters, it's not that difficult to put them together and for the
> really lazy we can provide a:
>
> my_clock_nsec_offset(struct clocksource *cs)
> {
> return generic_nsec_offset(cs, my_get_cycles(), MASK, SHIFT);
> }
>
> this is _very_ simple and if some of the parameters are constant you
> already saved a few cycles.
We already have this, its the per-arch gettimeofday().
My issue here is that by pushing this functionality off into the
clocksource driver, not only do you complicate the driver, you also are
implicitly binding the driver to a form of tick based timekeeping
(question: from what point is the nsec_offset measuring from?). Also,
this has implications w/ NTP, as the nsec_offset() function now must do
its own scaling internally.
I think this sort of get_nsec_offset() interface is needed, but it
doesn't belong in the clocksource driver, because that fouls the
abstraction.
Instead, why don't we have two implementations of __get_nsec_offset()?
One which uses the clean clocksource abstraction, and one that can call
your arch_get_nsec_offset()?
Here's what I'm proposing for generic code:
do_get(ns)timeofday():
xtime + __get_nsec_offset()
update_wall_time():
now = clocksource_read() /* <- that's jiffies in tick-clock case */
while (now - last > interval_cycles):
last += interval_cycles
xtime += interval_nsecs
error += interval_ntp - interval_nsecs
ntp_adjust(...)
...
#ifdef CONTINUOUS_CLOCK
__get_nsec_offset():
now = clock_read
return ((now - last)*mult)>>shift
#else /*TICK_CLOCK*/
__get_nsec_offset():
return arch_get_nsec_offset()
#endif
How's that sound?
> John, we have to find some compromise here, but I think sacrificing
> everything to driver simplicity is IMO a huge mistake.
We're coming up on the one year mark for this discussion. Every pass
I've taken your feedback, worked to understand it (which, i admit can
take me awhile :), and implemented parts of your ideas into the code. I
really do appreciate this cycle, so I hope you don't find me
thick-headed or stubborn. I believe I've been happy to compromise every
step of the way.
I do want to find a solution that we both like, but I am feeling some
fatigue and we need to make some progress. The existing tick based
assumptions in mainline is blocking the ability to sanely implement both
bug fixes and new features.
> A "simple" driver
> gives you a lot of flexibility on the generic side, but you remove this
> flexibility from the driver side, i.e. if a driver doesn't fit into this
> cycle model (e.g. tick based drivers) it has to do extra work to provide
> this abstraction.
I'm not trying to fit tick based clocks into the continuous model. I'm
trying to allow the currently jiffies based timekeeping code to possibly
use something else, cleaning up a lot of code in the process.
> A good abstraction should concentrate on the _common_ properties and I
> don't think that the continous cycle model is a good general abstraction
> for all types of clocks. Tick based clocks are already more complex due
> the extra work needed to emulate the cycle counter. Some clocks may
> already provide a nsec value (e.g. virtual clocks in a virtualized
> environment), where your generic nsec calculation is a complete waste of
> time. A common property of all clocks is that we want a nsec value from
> them, so why not simply ask the clock for some kind of nsec value and
> provide the clock driver with the necessary library routines to convert
> the cycle value to a nsec value, where you actually have the necessary
> information to create efficient code. As long as you try to pull the cycle
> model into the generic model it will seriously suck from a performance
> perspective, as you separate the cycle value from the information how to
> deal with it efficiently.
For features like robust timekeeping in the face of lost ticks (needed
for virtualization, and realtime), as well as high-res timers and
dynamic/no-idle ticks, we *NEED* a continuous clock.
I made a quick audit of the arches to see what the breakdown was for
continuous vs tick clocks:
Continuous:
i386,x86-64, ia64, powerpc, ppc, sparc, alpha, mips, parisc, s390,
xtensa, and arm (pxa, sa1100, plat-omap)
Tick:
arm (other), cris, m32, m68k, sh
xtime/no intertick resolution:
frv, h8300, v850
I'll admit, the continuos cycle model doesn't fit tick based clocks, but
we shouldn't limit the abstraction to the lowest common denominator. By
providing what I suggested above (w/ the two __get_nsec_offset()
implementations), we reduce code for both models, and allow progress for
systems w/ continuous clocks in a generic fashion.
> > > I'm also still interested in opinions about different possibilities to
> > > organize the clocksource infrastructure (although I'd more appreciate
> > > pro/con arguments than outright rejections). One possibility here would be
> > > to also shorten the function names a bit (clocksource_ is a lot to type :)
> > > ), cs_... or clock_... would IMO work too.
> >
> > I *much* prefer the clarity of clocksource over the wear and tear typing
> > it might take on my fingers.
>
> What is the special meaning of "clocksource" vs e.g. just "clock"?
"clock" is already overloaded. We have the
CLOCK_MONOTONIC/CLOCK_REALTIME clocks, we have the RTC clocks... Its a
cycle counter we're using to accumulate time, thus clocksource seemed
understandable and unique.
> > > I also kept it separate from the do_timer() callback and simply created a
> > > new callback function, which archs can use. This makes it less likely to
> > > break any existing setup and even allows to coexists both methods until
> > > archs have been completely converted.
> >
> > One of the reasons I did the significant rework of the TOD patches was
> > so that we could generically introduce the clocksource abstraction first
> > (using jiffies) for all arches. I feel this provides a much smoother
> > transition to the generic timekeeping code (and greatly reduces the
> > amount of CONFIG_GENERIC_TIME specific code), so I'm not sure I
> > understand why you want to go back to separate do_timer() functions.
>
> Apropos code size: I checked the generated code size of timer.o (default
> i386 config), before it was 3248 bytes, with your patches it goes to 5907
> bytes and by disabling CONFIG_GENERIC_TIME it still is 4554. With my
> patches it's 4767/4347 bytes (removing the old time code saves another
> 315 bytes).
This isn't really a fair comparison (yet atleast), as your patches don't
appear to handle suspend/resume correctly. Nor did your patches even
boot on my laptop. :(
I'll admit that my code could use more low-level optimization, and I
welcome patches against my code to improve it. My code has already
gotten a good amount of testing in both -mm and -rt, so I know it works.
Lets make it fast too, but just in steps.
> In my version I was very careful to keep the common interrupt paths as
> short as possible, so that most of this code is not even executed most of
> the time. You can't just "hope" that gcc does the work for you (especially
> with 64bit math), you actually have to check the code and you would have
> the noticed the bloated code it generates.
Good point. I just sent a patch to Andrew fixing the assumption that gcc
could avoid a few of the mults. And I'm working on more patches to
reduce the text size as well.
Once again, I do appreciate the feedback.
thanks
-john
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-05-06 2:04 ` john stultz
@ 2006-05-06 16:25 ` Roman Zippel
2006-05-08 18:33 ` john stultz
0 siblings, 1 reply; 16+ messages in thread
From: Roman Zippel @ 2006-05-06 16:25 UTC (permalink / raw)
To: john stultz; +Cc: linux-kernel, Andrew Morton
Hi,
On Fri, 5 May 2006, john stultz wrote:
> > A good abstraction should concentrate on the _common_ properties and I
> > don't think that the continous cycle model is a good general abstraction
> > for all types of clocks. Tick based clocks are already more complex due
> > the extra work needed to emulate the cycle counter. Some clocks may
> > already provide a nsec value (e.g. virtual clocks in a virtualized
> > environment), where your generic nsec calculation is a complete waste of
> > time. A common property of all clocks is that we want a nsec value from
> > them, so why not simply ask the clock for some kind of nsec value and
> > provide the clock driver with the necessary library routines to convert
> > the cycle value to a nsec value, where you actually have the necessary
> > information to create efficient code. As long as you try to pull the cycle
> > model into the generic model it will seriously suck from a performance
> > perspective, as you separate the cycle value from the information how to
> > deal with it efficiently.
>
>
> For features like robust timekeeping in the face of lost ticks (needed
> for virtualization, and realtime), as well as high-res timers and
> dynamic/no-idle ticks, we *NEED* a continuous clock.
Let's concentrate on the core issue.
I do agree that we need a continuous clock, but why has this clock to be
cycle based? As I tried to explain above the cycle based abstraction hurts
performance, as it cuts us off from further optimizations.
What we want in the end is continous _nanosecond_ value, so why not let
the abstraction base on this? Why is the cycle value so important?
> I made a quick audit of the arches to see what the breakdown was for
> continuous vs tick clocks:
>
> Continuous:
> i386,x86-64, ia64, powerpc, ppc, sparc, alpha, mips, parisc, s390,
> xtensa, and arm (pxa, sa1100, plat-omap)
>
> Tick:
> arm (other), cris, m32, m68k, sh
>
> xtime/no intertick resolution:
> frv, h8300, v850
>
> I'll admit, the continuos cycle model doesn't fit tick based clocks, but
> we shouldn't limit the abstraction to the lowest common denominator. By
> providing what I suggested above (w/ the two __get_nsec_offset()
> implementations), we reduce code for both models, and allow progress for
> systems w/ continuous clocks in a generic fashion.
Why can't we reach the same goal by providing library functions to the
drivers, which would allow far better optimizations?
Of these archs ppc has a higly optimized lock and condition free
gettimeofday implementation, which you simply throw away. I'm afraid that
archs which care about performance have to work around your slow generic
implementation. I have a big problem seeing progress in this.
John, I see three options:
1. I'm missing the point in your design which allows for further
optimizations in a generic way.
2. Something is wrong with your cycle based design.
3. Performance isn't important anymore.
> > > I *much* prefer the clarity of clocksource over the wear and tear typing
> > > it might take on my fingers.
> >
> > What is the special meaning of "clocksource" vs e.g. just "clock"?
>
>
> "clock" is already overloaded. We have the
> CLOCK_MONOTONIC/CLOCK_REALTIME clocks, we have the RTC clocks... Its a
> cycle counter we're using to accumulate time, thus clocksource seemed
> understandable and unique.
The first would actually be my reason for calling it "clock", i.e. if this
is going to be _the_ central abstraction for further time based services,
it deserves the shorter and concise "clock" name.
> This isn't really a fair comparison (yet atleast), as your patches don't
> appear to handle suspend/resume correctly. Nor did your patches even
> boot on my laptop. :(
Why didn't you mentioned this earlier? :(
> I'll admit that my code could use more low-level optimization, and I
> welcome patches against my code to improve it. My code has already
> gotten a good amount of testing in both -mm and -rt, so I know it works.
Andrew immediately drops my patches, so they don't even get a chance to
get any testing. This is a complete unfair argument, I don't even get the
chance to prove that my code might be better. :-(
> Lets make it fast too, but just in steps.
The first step would be to keep it separate from the current
update_wall_time() code. I just got rid of clock read in the hrtimer
interrupt code you are about to introduce it again here. Many clocks don't
need that much precision, and especially if it's an expensive operation
it's a complete waste of time.
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-05-06 16:25 ` Roman Zippel
@ 2006-05-08 18:33 ` john stultz
2006-05-08 21:15 ` Roman Zippel
0 siblings, 1 reply; 16+ messages in thread
From: john stultz @ 2006-05-08 18:33 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
On Sat, 2006-05-06 at 18:25 +0200, Roman Zippel wrote:
> On Fri, 5 May 2006, john stultz wrote:
>
> > > A good abstraction should concentrate on the _common_ properties and I
> > > don't think that the continous cycle model is a good general abstraction
> > > for all types of clocks. Tick based clocks are already more complex due
> > > the extra work needed to emulate the cycle counter. Some clocks may
> > > already provide a nsec value (e.g. virtual clocks in a virtualized
> > > environment), where your generic nsec calculation is a complete waste of
> > > time. A common property of all clocks is that we want a nsec value from
> > > them, so why not simply ask the clock for some kind of nsec value and
> > > provide the clock driver with the necessary library routines to convert
> > > the cycle value to a nsec value, where you actually have the necessary
> > > information to create efficient code. As long as you try to pull the cycle
> > > model into the generic model it will seriously suck from a performance
> > > perspective, as you separate the cycle value from the information how to
> > > deal with it efficiently.
> >
> >
> > For features like robust timekeeping in the face of lost ticks (needed
> > for virtualization, and realtime), as well as high-res timers and
> > dynamic/no-idle ticks, we *NEED* a continuous clock.
>
> Let's concentrate on the core issue.
> I do agree that we need a continuous clock, but why has this clock to be
> cycle based? As I tried to explain above the cycle based abstraction hurts
> performance, as it cuts us off from further optimizations.
First of all, you didn't reply specifically, but I hope we're in
agreement w/ the tick based clocks being not part of this specific
discussion. I'm fine letting systems w/ tick based clocks have an
get_nsec_offset() that is fully arch specific. And I don't love it, but
I can deal w/ having two update_wall_time() paths so tick based systems
can get some extra constant based optimizations.
Now, on to the continuous clocksource discussion :)
What arch specific optimizations for continuous clocks do you have in
mind? In other words, what would be an example of an architecture
specific optimization for generating time from a continuous counter?
For the sake of this discussion, I claim that optimizations made on
converting a continuous cycle based clock to an NTP adjusted time can be
made to all arches, and pushing the nanosecond conversion into the
driver is messy and needless. What are examples contrary to this claim?
> What we want in the end is continous _nanosecond_ value, so why not let
> the abstraction base on this? Why is the cycle value so important?
Because doing the NTP adjustment correctly on a cycle based clock is
difficult with the current code (I think ppc is the only one that does
it correctly, in my mind, by changing the frequency multiplier).
It can be done generically, and I do not see what sort of optimizations
you're imagining, so why keep it arch specific?
> Of these archs ppc has a higly optimized lock and condition free
> gettimeofday implementation, which you simply throw away. I'm afraid that
> archs which care about performance have to work around your slow generic
> implementation. I have a big problem seeing progress in this.
The ppc's lockfree implementation is interesting (putting aside for a
moment the fact that the current ppc vsyscall-gtod added locks back to
the code).
However I don't see how its an arch specific optimization! Its simply
doing atomic updates via pointer switches between two structures. This
doesn't need to be ppc specific, yet because of the current mess it is.
This is a great example of why the generic code would be useful.
> > This isn't really a fair comparison (yet atleast), as your patches don't
> > appear to handle suspend/resume correctly. Nor did your patches even
> > boot on my laptop. :(
>
> Why didn't you mentioned this earlier? :(
I apologize for not trying to run your patches earlier, but being time
constrained as well, I have been trying to focus understand the
algorithmic differences.
> > Lets make it fast too, but just in steps.
>
> The first step would be to keep it separate from the current
> update_wall_time() code. I just got rid of clock read in the hrtimer
> interrupt code you are about to introduce it again here. Many clocks don't
> need that much precision, and especially if it's an expensive operation
> it's a complete waste of time.
With continuous cycle based counters, the clock read is *necessary* when
updating xtime for robust timekeeping. We can move update_wall_time so
we don't run it every timer interrupt, but we cannot keep correct time
by just guessing how much time has passed and adding it in.
On tick based systems, the code in -mm, would just be reading jiffies
which is equivalent to how its done in mainline. But I'll grant you we
probably miss out on some of the optimizations where we could use
constants, so I'll add in a tick based update_wall_time path soon.
thanks
-john
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-05-08 18:33 ` john stultz
@ 2006-05-08 21:15 ` Roman Zippel
2006-05-09 0:29 ` john stultz
0 siblings, 1 reply; 16+ messages in thread
From: Roman Zippel @ 2006-05-08 21:15 UTC (permalink / raw)
To: john stultz; +Cc: linux-kernel, Andrew Morton
Hi,
On Mon, 8 May 2006, john stultz wrote:
> > Let's concentrate on the core issue.
> > I do agree that we need a continuous clock, but why has this clock to be
> > cycle based? As I tried to explain above the cycle based abstraction hurts
> > performance, as it cuts us off from further optimizations.
>
>
> First of all, you didn't reply specifically, but I hope we're in
> agreement w/ the tick based clocks being not part of this specific
> discussion. I'm fine letting systems w/ tick based clocks have an
> get_nsec_offset() that is fully arch specific. And I don't love it, but
> I can deal w/ having two update_wall_time() paths so tick based systems
> can get some extra constant based optimizations.
Please leave the tick based stuff out of this completely. We want to get
rid of the arch specific hooks and not add them back.
The point is to give the _clock_ control over this kind of stuff, only the
clock driver knows how to deal with this efficiently, so as long as you
try to create a "dumb" clock driver you're going to make things only
worse. Now the archs have most control over it, but creating a single
bloated and slow blop instead will not be an improvement.
It's not about moving everything into the clock driver here, it's about
creating a _powerful_ API, which leaves control in the hands of the clock
driver, but at the same time keeps them as _simple_ (and not as dumb) as
possible.
> What arch specific optimizations for continuous clocks do you have in
> mind? In other words, what would be an example of an architecture
> specific optimization for generating time from a continuous counter?
The best example is the powerpc gettimeofday.
> For the sake of this discussion, I claim that optimizations made on
> converting a continuous cycle based clock to an NTP adjusted time can be
> made to all arches, and pushing the nanosecond conversion into the
> driver is messy and needless. What are examples contrary to this claim?
What kind of NTP adjustments are you talking about? A nsec_offset function
could look like this:
unsigned long nsec_offset(cs)
{
return ((cs->xtime_nsec + get_cycles() - cs->last_offset) * cs->mult) >> SHIFT;
}
This is fucking simple, what about this is "messy"? There is no NTP
adjustment here, this is all happening somewhere else. Keeping it in the
driver allows to make parameter constant, skip unnecessary steps and
allows to do it within 32bit. This is something you can _never_ do in a
generic centralized way without making it truly messy. I'd be happy to be
proven otherwise, but I simply don't see it.
> > What we want in the end is continous _nanosecond_ value, so why not let
> > the abstraction base on this? Why is the cycle value so important?
>
> Because doing the NTP adjustment correctly on a cycle based clock is
> difficult with the current code (I think ppc is the only one that does
> it correctly, in my mind, by changing the frequency multiplier).
I was talking about the nsec offset (see above), which is outside of the
NTP business. What is your fascination with the cycle counter, that you
want to make it so generic?
> It can be done generically, and I do not see what sort of optimizations
> you're imagining, so why keep it arch specific?
John, it's _clock_ specific.
> > Of these archs ppc has a higly optimized lock and condition free
> > gettimeofday implementation, which you simply throw away. I'm afraid that
> > archs which care about performance have to work around your slow generic
> > implementation. I have a big problem seeing progress in this.
>
> The ppc's lockfree implementation is interesting (putting aside for a
> moment the fact that the current ppc vsyscall-gtod added locks back to
> the code).
>
> However I don't see how its an arch specific optimization! Its simply
> doing atomic updates via pointer switches between two structures. This
> doesn't need to be ppc specific, yet because of the current mess it is.
> This is a great example of why the generic code would be useful.
Part of this can be done generically and I'd like to see it implemented,
but not all the optimizations can be done generically, e.g. not every arch
has a convenient mulhdu instruction like ppc64.
The arch can provide some base optimizations, but in the end it's the
clock which knows best (e.g. 32bit vs. 64bit resolution). Only the clock
driver knows the basic clock parameters at _compile_ time and can generate
an efficient implementation. With the help of some library functions we
can keep the amount of source needed in the driver to a minimum and
simple. Where is the problem with this?
> > The first step would be to keep it separate from the current
> > update_wall_time() code. I just got rid of clock read in the hrtimer
> > interrupt code you are about to introduce it again here. Many clocks don't
> > need that much precision, and especially if it's an expensive operation
> > it's a complete waste of time.
>
> With continuous cycle based counters, the clock read is *necessary* when
> updating xtime for robust timekeeping. We can move update_wall_time so
> we don't run it every timer interrupt, but we cannot keep correct time
> by just guessing how much time has passed and adding it in.
It has almost nothing to do with continuous cycles. On an UP system only
anything running with a higher priority than the timer interrupt or if the
cycle adjustment happens asynchron to the timer interrupt (e.g. TSC) can
see the adjustment. Again it depends on the clock whether the common
adjustment is significant bigger than the time needed to read the clock,
otherwise it's just a waste of time.
> On tick based systems, the code in -mm, would just be reading jiffies
> which is equivalent to how its done in mainline. But I'll grant you we
> probably miss out on some of the optimizations where we could use
> constants, so I'll add in a tick based update_wall_time path soon.
John, again, it's not about tick based systems, you'll get it wrong as
long as you think it's about special exceptions for tick based systems.
It's about creating a flexible system, which can handle about anything and
only the clock driver really knows what this is, otherwise you create a
bloated and slow generic system.
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-05-08 21:15 ` Roman Zippel
@ 2006-05-09 0:29 ` john stultz
2006-05-09 22:48 ` Roman Zippel
0 siblings, 1 reply; 16+ messages in thread
From: john stultz @ 2006-05-09 0:29 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
On Mon, 2006-05-08 at 23:15 +0200, Roman Zippel wrote:
> The point is to give the _clock_ control over this kind of stuff, only the
> clock driver knows how to deal with this efficiently, so as long as you
> try to create a "dumb" clock driver you're going to make things only
> worse. Now the archs have most control over it, but creating a single
> bloated and slow blop instead will not be an improvement.
> It's not about moving everything into the clock driver here, it's about
> creating a _powerful_ API, which leaves control in the hands of the clock
> driver, but at the same time keeps them as _simple_ (and not as dumb) as
> possible.
Part of my concern here is keeping the code manageable and hackable.
What you're suggesting sounds very similar to what we have for the i386
timer_opts code, which I don't want to duplicate.
Maybe it would help here if you would better define the API for this
abstraction. As it stands, it appears incomplete. Define the state
values stored, and list what interfaces modify which state values, etc.
ie: clock->get_nsec_offset():
What exactly does this measure? Is this strictly defined by the state
stored in the clocksource? If not, how will this interact w/ dynamic
ticks? What is the maximum time we can delay interrupts before the clock
wraps? How do we know if its tick based?
Another issue: if get_nsec_offset() is clock specific in its
implementation, but the state values it uses in at least the common case
are modified by generic code, how can we implement something like the
ppc lock free read? That will affect both the generic code and the clock
specific code.
> > What arch specific optimizations for continuous clocks do you have in
> > mind? In other words, what would be an example of an architecture
> > specific optimization for generating time from a continuous counter?
>
> The best example is the powerpc gettimeofday.
>
> > For the sake of this discussion, I claim that optimizations made on
> > converting a continuous cycle based clock to an NTP adjusted time can be
> > made to all arches, and pushing the nanosecond conversion into the
> > driver is messy and needless. What are examples contrary to this claim?
>
> What kind of NTP adjustments are you talking about? A nsec_offset function
> could look like this:
>
> unsigned long nsec_offset(cs)
> {
> return ((cs->xtime_nsec + get_cycles() - cs->last_offset) * cs->mult) >> SHIFT;
> }
>
> This is fucking simple, what about this is "messy"? There is no NTP
> adjustment here, this is all happening somewhere else.
That's my point. if nsec_offset is opaque, then what is the interface
for making NTP adjustments to that function? Are all nsec_offset
functions required to use the xtime_nsec, last_offset, and mult values?
> Keeping it in the
> driver allows to make parameter constant, skip unnecessary steps and
> allows to do it within 32bit. This is something you can _never_ do in a
> generic centralized way without making it truly messy. I'd be happy to be
> proven otherwise, but I simply don't see it.
Well, my issue w/ you desire to have a 32bit continuous clock is that I
don't know how useful it would be.
For a 1Mhz clock,
You've got 1,000 ns per cycle and the algorithm looks something like
say:
get_nsec_offset: cycles * 1,000 >> 0
which gives you ~4 seconds of leeway, which is pretty good.
However, the short term jitter is 1000ppm.
So lets bump up the SHIFT value,
get_nsec_offset: cycles * 1,024,000 >> 10
The short term jitter: <1ppm, so that's good.
But the max cycles is then ~4,000 (4ms), which is too short.
You can wiggle around here and maybe come up with something that works,
but it only gets worse for clocks that are faster.
For robust timekeeping using continuous cycles, I think the 64bit mult
in gettimeofday is going to be necessary in the majority of cases (we
can wrap it in some sort of arch optimized macro for a mul_lxl_ll or
something if possible).
> > > The first step would be to keep it separate from the current
> > > update_wall_time() code. I just got rid of clock read in the hrtimer
> > > interrupt code you are about to introduce it again here. Many clocks don't
> > > need that much precision, and especially if it's an expensive operation
> > > it's a complete waste of time.
> >
> > With continuous cycle based counters, the clock read is *necessary* when
> > updating xtime for robust timekeeping. We can move update_wall_time so
> > we don't run it every timer interrupt, but we cannot keep correct time
> > by just guessing how much time has passed and adding it in.
>
> It has almost nothing to do with continuous cycles. On an UP system only
> anything running with a higher priority than the timer interrupt or if the
> cycle adjustment happens asynchron to the timer interrupt (e.g. TSC) can
> see the adjustment. Again it depends on the clock whether the common
> adjustment is significant bigger than the time needed to read the clock,
> otherwise it's just a waste of time.
Eh? I didn't understand that. Mind clarifying/expanding here?
thanks
-john
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/5] clocksource patches
2006-05-09 0:29 ` john stultz
@ 2006-05-09 22:48 ` Roman Zippel
0 siblings, 0 replies; 16+ messages in thread
From: Roman Zippel @ 2006-05-09 22:48 UTC (permalink / raw)
To: john stultz; +Cc: linux-kernel, Andrew Morton
Hi,
On Mon, 8 May 2006, john stultz wrote:
> On Mon, 2006-05-08 at 23:15 +0200, Roman Zippel wrote:
> > The point is to give the _clock_ control over this kind of stuff, only the
> > clock driver knows how to deal with this efficiently, so as long as you
> > try to create a "dumb" clock driver you're going to make things only
> > worse. Now the archs have most control over it, but creating a single
> > bloated and slow blop instead will not be an improvement.
> > It's not about moving everything into the clock driver here, it's about
> > creating a _powerful_ API, which leaves control in the hands of the clock
> > driver, but at the same time keeps them as _simple_ (and not as dumb) as
> > possible.
>
> Part of my concern here is keeping the code manageable and hackable.
> What you're suggesting sounds very similar to what we have for the i386
> timer_opts code, which I don't want to duplicate.
What are you talking about???
Let's take a simple example:
static cycle_t read_tsc(void)
{
cycle_t ret;
rdtscll(ret);
return ret;
}
which could become:
static unsigned long tsc_nsec_offset(struct clocksource *cs)
{
cycle_t cyc;
rdtscll(cyc);
return generic_cont_cycle2nsec_offset(cs, cyc, 22, (cycle_t)-1);
}
Please tell me what kind of problem you have with this? Even in this
simple case it will already be faster due to the constant parameters.
What is wrong with a little extra performance?
> Maybe it would help here if you would better define the API for this
> abstraction. As it stands, it appears incomplete. Define the state
> values stored, and list what interfaces modify which state values, etc.
>
> ie: clock->get_nsec_offset():
> What exactly does this measure? Is this strictly defined by the state
> stored in the clocksource? If not, how will this interact w/ dynamic
> ticks? What is the maximum time we can delay interrupts before the clock
> wraps? How do we know if its tick based?
I explained this already at the start of this thread and please read the
patch. I'm truly baffled, that you actually have to ask these questions.
> Another issue: if get_nsec_offset() is clock specific in its
> implementation, but the state values it uses in at least the common case
> are modified by generic code, how can we implement something like the
> ppc lock free read? That will affect both the generic code and the clock
> specific code.
You basically have two copies of the time parameters, for
get_nsec_offset() this only means it gets a different structure argument,
the rest is the same. The pointer switch between these two copies can be
done generically.
> > What kind of NTP adjustments are you talking about? A nsec_offset function
> > could look like this:
> >
> > unsigned long nsec_offset(cs)
> > {
> > return ((cs->xtime_nsec + get_cycles() - cs->last_offset) * cs->mult) >> SHIFT;
> > }
> >
> > This is fucking simple, what about this is "messy"? There is no NTP
> > adjustment here, this is all happening somewhere else.
>
> That's my point. if nsec_offset is opaque, then what is the interface
> for making NTP adjustments to that function? Are all nsec_offset
> functions required to use the xtime_nsec, last_offset, and mult values?
These values are not opaque, from an average kernel hacker I would at
least expect to understand what these values mean, but he doesn't has to
know how they are adjusted (or even calculated) and for this function it's
also not really important.
> > Keeping it in the
> > driver allows to make parameter constant, skip unnecessary steps and
> > allows to do it within 32bit. This is something you can _never_ do in a
> > generic centralized way without making it truly messy. I'd be happy to be
> > proven otherwise, but I simply don't see it.
>
> Well, my issue w/ you desire to have a 32bit continuous clock is that I
> don't know how useful it would be.
>
> For a 1Mhz clock,
> You've got 1,000 ns per cycle and the algorithm looks something like
> say:
> get_nsec_offset: cycles * 1,000 >> 0
> which gives you ~4 seconds of leeway, which is pretty good.
> However, the short term jitter is 1000ppm.
I think you mean 1000ppb or 1ppm.
Anyway, it's still not entirely correct. The short term jitter (for a
continuous clock) is defined by two parameters. First you have the base
jitter defined by the clock frequency of 1/freq seconds (which is also
independent of the used shift), so even with a perfectly synchronized
signal there is a jitter of +-0.5ppm. The second parameter is defined by
the size of the adjustment steps, which depends on the shift and HZ:
freq/2^shift/HZ nsec. This means in this case with HZ=1000 adjustment adds
a jitter of +-0.5ppm or with HZ=100 it's +-5ppm.
> So lets bump up the SHIFT value,
> get_nsec_offset: cycles * 1,024,000 >> 10
>
> The short term jitter: <1ppm, so that's good.
> But the max cycles is then ~4,000 (4ms), which is too short.
>
> You can wiggle around here and maybe come up with something that works,
> but it only gets worse for clocks that are faster.
You don't have to "wiggle" around anything. Using log2(freq^2/10^9/HZ) you
can calculate a shift value with an adjustment step which matches the
clock resolution, so with HZ=100 and a shift of 4 the adjustment step is
+-0.3125ppm and with a shift of 5 it's +-0.15625ppm, which is good enough
and wraps around after 134msec (If you lose that many update ticks you
have other problems already and with a tick based clock you wouldn't
notice it anyway). So if the clock resolution is only around 1usec anyway,
a 32bit calculation of the offset is perfectly usable.
I don't really expect to know these details from many people, but if you
want to maintain the clock system, you have to know this, you have to know
what is possible and what isn't and why. I'm really scared if you create
your code by "wiggling" around with it until it somehow fits.
> For robust timekeeping using continuous cycles, I think the 64bit mult
> in gettimeofday is going to be necessary in the majority of cases (we
> can wrap it in some sort of arch optimized macro for a mul_lxl_ll or
> something if possible).
Actually currently you use a mul_llxl_ll, which is considerably more
expensive on many archs. With current GHz clocks and the possible delays
of the timer interrupt in the rt kernel we are currently pushing the
limits and a mul_llxl_ll may be needed, which is perfectly fine. What is
not ok, is forcing it onto everyone by design. If something is not
generally true, you cannot make it generic!
What makes this worse that you don't optimize for the majority of cases,
but that you have to do it for the worst case, this is the reason it's a
mul_llxl_ll not mul_lxl_ll. Giving the clock control over this you could
register two different clock and have a choice whether you want the slow,
low priority clock, which can go a few seconds without updates, or the
fast clock, which needs updates a few times a second. With your cycle
based design you'll never have this kind of flexibility, are you really
sure nobody ever needs that?
> > > With continuous cycle based counters, the clock read is *necessary* when
> > > updating xtime for robust timekeeping. We can move update_wall_time so
> > > we don't run it every timer interrupt, but we cannot keep correct time
> > > by just guessing how much time has passed and adding it in.
> >
> > It has almost nothing to do with continuous cycles. On an UP system only
> > anything running with a higher priority than the timer interrupt or if the
> > cycle adjustment happens asynchron to the timer interrupt (e.g. TSC) can
> > see the adjustment. Again it depends on the clock whether the common
> > adjustment is significant bigger than the time needed to read the clock,
> > otherwise it's just a waste of time.
>
> Eh? I didn't understand that. Mind clarifying/expanding here?
If the clock is updated at exactly every freq/HZ cycles, you won't see a
jump due to the clock adjustment. This means only if you delay the timer
interrupt can you cause a time jump and this delay has to be large enough
to produce a large enough jump to be noticable (without correcting for
it).
The nsec offset is adjusted by (offset >> (shift - mult_adj)) nsec, this
means IOW the correction is adjustment_offset*delay, e.g. if the clock is
adjusted by 1msec/sec and the delay is 1msec (one tick!), the correction
is 1usec. IOW you already need quite large adjustments and delay to
produce a significant adjustment for the delay, so for slow clocks it's
pretty much guaranteed to be a complete waste of time.
bye, Roman
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2006-05-09 22:48 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-03 19:54 [PATCH 0/5] clocksource patches Roman Zippel
2006-04-03 20:08 ` Roman Zippel
2006-04-04 4:53 ` Thomas Gleixner
2006-04-04 19:06 ` Roman Zippel
2006-04-05 11:22 ` Thomas Gleixner
2006-04-05 13:40 ` Ingo Molnar
2006-04-05 20:44 ` Roman Zippel
2006-04-05 22:18 ` Thomas Gleixner
2006-04-07 17:57 ` john stultz
2006-04-27 20:33 ` Roman Zippel
2006-05-06 2:04 ` john stultz
2006-05-06 16:25 ` Roman Zippel
2006-05-08 18:33 ` john stultz
2006-05-08 21:15 ` Roman Zippel
2006-05-09 0:29 ` john stultz
2006-05-09 22:48 ` Roman Zippel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox