Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: timers, init: Limit the number of per cpu calibration bootup messages posix-cpu-timers: optimize and document timer_create callback clockevents: Add missing include to pacify sparse x86: vmiclock: Fix printk format x86: Fix printk format due to variable type change sparc: fix printk for change of variable type clocksource/events: Fix fallout of generic code changes nohz: Allow 32-bit machines to sleep for more than 2.15 seconds nohz: Track last do_timer() cpu nohz: Prevent clocksource wrapping during idle nohz: Type cast printk argument mips: Use generic mult/shift factor calculation for clocks clocksource: Provide a generic mult/shift factor calculation clockevents: Use u32 for mult and shift factors nohz: Introduce arch_needs_cpu nohz: Reuse ktime in sub-functions of tick_check_idle. time: Remove xtime_cache time: Implement logarithmic time accumulation
This commit is contained in:
@@ -107,6 +107,59 @@ u64 timecounter_cyc2time(struct timecounter *tc,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timecounter_cyc2time);
|
||||
|
||||
/**
|
||||
* clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
|
||||
* @mult: pointer to mult variable
|
||||
* @shift: pointer to shift variable
|
||||
* @from: frequency to convert from
|
||||
* @to: frequency to convert to
|
||||
* @minsec: guaranteed runtime conversion range in seconds
|
||||
*
|
||||
* The function evaluates the shift/mult pair for the scaled math
|
||||
* operations of clocksources and clockevents.
|
||||
*
|
||||
* @to and @from are frequency values in HZ. For clock sources @to is
|
||||
* NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock
|
||||
* event @to is the counter frequency and @from is NSEC_PER_SEC.
|
||||
*
|
||||
* The @minsec conversion range argument controls the time frame in
|
||||
* seconds which must be covered by the runtime conversion with the
|
||||
* calculated mult and shift factors. This guarantees that no 64bit
|
||||
* overflow happens when the input value of the conversion is
|
||||
* multiplied with the calculated mult factor. Larger ranges may
|
||||
* reduce the conversion accuracy by chosing smaller mult and shift
|
||||
* factors.
|
||||
*/
|
||||
void
|
||||
clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec)
|
||||
{
|
||||
u64 tmp;
|
||||
u32 sft, sftacc= 32;
|
||||
|
||||
/*
|
||||
* Calculate the shift factor which is limiting the conversion
|
||||
* range:
|
||||
*/
|
||||
tmp = ((u64)minsec * from) >> 32;
|
||||
while (tmp) {
|
||||
tmp >>=1;
|
||||
sftacc--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the conversion shift/mult pair which has the best
|
||||
* accuracy and fits the maxsec conversion range:
|
||||
*/
|
||||
for (sft = 32; sft > 0; sft--) {
|
||||
tmp = (u64) to << sft;
|
||||
do_div(tmp, from);
|
||||
if ((tmp >> sftacc) == 0)
|
||||
break;
|
||||
}
|
||||
*mult = tmp;
|
||||
*shift = sft;
|
||||
}
|
||||
|
||||
/*[Clocksource internal variables]---------
|
||||
* curr_clocksource:
|
||||
* currently selected clocksource.
|
||||
@@ -413,6 +466,47 @@ void clocksource_touch_watchdog(void)
|
||||
clocksource_resume_watchdog();
|
||||
}
|
||||
|
||||
/**
|
||||
* clocksource_max_deferment - Returns max time the clocksource can be deferred
|
||||
* @cs: Pointer to clocksource
|
||||
*
|
||||
*/
|
||||
static u64 clocksource_max_deferment(struct clocksource *cs)
|
||||
{
|
||||
u64 max_nsecs, max_cycles;
|
||||
|
||||
/*
|
||||
* Calculate the maximum number of cycles that we can pass to the
|
||||
* cyc2ns function without overflowing a 64-bit signed result. The
|
||||
* maximum number of cycles is equal to ULLONG_MAX/cs->mult which
|
||||
* is equivalent to the below.
|
||||
* max_cycles < (2^63)/cs->mult
|
||||
* max_cycles < 2^(log2((2^63)/cs->mult))
|
||||
* max_cycles < 2^(log2(2^63) - log2(cs->mult))
|
||||
* max_cycles < 2^(63 - log2(cs->mult))
|
||||
* max_cycles < 1 << (63 - log2(cs->mult))
|
||||
* Please note that we add 1 to the result of the log2 to account for
|
||||
* any rounding errors, ensure the above inequality is satisfied and
|
||||
* no overflow will occur.
|
||||
*/
|
||||
max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1));
|
||||
|
||||
/*
|
||||
* The actual maximum number of cycles we can defer the clocksource is
|
||||
* determined by the minimum of max_cycles and cs->mask.
|
||||
*/
|
||||
max_cycles = min_t(u64, max_cycles, (u64) cs->mask);
|
||||
max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift);
|
||||
|
||||
/*
|
||||
* To ensure that the clocksource does not wrap whilst we are idle,
|
||||
* limit the time the clocksource can be deferred by 12.5%. Please
|
||||
* note a margin of 12.5% is used because this can be computed with
|
||||
* a shift, versus say 10% which would require division.
|
||||
*/
|
||||
return max_nsecs - (max_nsecs >> 5);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_TIME
|
||||
|
||||
/**
|
||||
@@ -511,6 +605,9 @@ static void clocksource_enqueue(struct clocksource *cs)
|
||||
*/
|
||||
int clocksource_register(struct clocksource *cs)
|
||||
{
|
||||
/* calculate max idle time permitted for this clocksource */
|
||||
cs->max_idle_ns = clocksource_max_deferment(cs);
|
||||
|
||||
mutex_lock(&clocksource_mutex);
|
||||
clocksource_enqueue(cs);
|
||||
clocksource_select();
|
||||
|
Reference in New Issue
Block a user