[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4A1C04A2.80404@parrot.com>
Date: Tue, 26 May 2009 17:02:58 +0200
From: Matthieu CASTET <matthieu.castet@...rot.com>
To: Linus Walleij <linus.ml.walleij@...il.com>
CC: Paul Mundt <lethal@...ux-sh.org>, Ingo Molnar <mingo@...e.hu>,
Andrew Victor <linux@...im.org.za>,
Haavard Skinnemoen <hskinnemoen@...el.com>,
Andrew Morton <akpm@...ux-foundation.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"linux-sh@...r.kernel.org" <linux-sh@...r.kernel.org>,
"peterz@...radead.org" <peterz@...radead.org>,
"linux-arm-kernel@...ts.arm.linux.org.uk"
<linux-arm-kernel@...ts.arm.linux.org.uk>
Subject: Re: [PATCH] sched: Support current clocksource handling in fallback
sched_clock().
Linus Walleij a écrit :
> 2009/5/26 Paul Mundt <lethal@...ux-sh.org>:
>
>> */
>> unsigned long long __attribute__((weak)) sched_clock(void)
>> {
>> + /*
>> + * Use the current clocksource when it becomes available later in
>> + * the boot process, and ensure that it has a high enough rating
>> + * to make it suitable for general use.
>> + */
>> + if (clock && clock->rating >= 100)
>> + return cyc2ns(clock, clocksource_read(clock));
>> +
>> + /* Otherwise just fall back on jiffies */
>> return (unsigned long long)(jiffies - INITIAL_JIFFIES)
>> * (NSEC_PER_SEC / HZ);
>> }
This is buggy for fast clocksource that wrap often, because sched_clock
is not supposed to wrap.
That why custom implementation use cnt32_to_63 and a smaller shift
(around 8 -10) for conversion for timer unit to ns.
Look for example to arch/arm/mach-pxa/time.c implementation [1]
But we can image you make it generic.
Matthieu
[1]
/*
* This is PXA's sched_clock implementation. This has a resolution
* of at least 308 ns and a maximum value of 208 days.
*
* The return value is guaranteed to be monotonic in that range as
* long as there is always less than 582 seconds between successive
* calls to sched_clock() which should always be the case in practice.
*/
#define OSCR2NS_SCALE_FACTOR 10
static unsigned long oscr2ns_scale;
static void __init set_oscr2ns_scale(unsigned long oscr_rate)
{
unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR;
do_div(v, oscr_rate);
oscr2ns_scale = v;
/*
* We want an even value to automatically clear the top bit
* returned by cnt32_to_63() without an additional run time
* instruction. So if the LSB is 1 then round it up.
*/
if (oscr2ns_scale & 1)
oscr2ns_scale++;
}
unsigned long long sched_clock(void)
{
unsigned long long v = cnt32_to_63(OSCR);
return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists