I commented in this post that just because DAHDI thinks it has a High Resolution timer from the kernel, this might not actually be the case.
When you compile the DAHDI dummy driver it checks your kernel headers to see if you compiled your kernel with CONFIG_HIGH_RES_TIMERS, in which case the specific functions in the dummy driver call out to the hrtimer kernel functions.
So what if you compiled your kernel with CONFIG_HIGH_RES_TIMERS but you don’t have HPET support on your hardware?
Simple. The kernel emulates the hrtimer by passing a low-resolution timer via the same interface. This sounds crazy, but it doesn’t really have much choice.
To be sure that you’re using a hardware high-res timer, run dmesg | grep hpet like this:
hpet-test:/usr/src# dmesg | grep hpet [ 0.004000] hpet clockevent registered [ 0.256427] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0 [ 0.256435] hpet0: 3 64-bit timers, 14318180 Hz [ 1.150057] hpet_resources: 0xfed00000 is busy
Here you can see the HPET being initialised by the kernel. If you don’t have an HPET, then you can expect some really strange results when you run the DAHDI tests. I had some of these results a few months back, and I might dig them out for a future post at some point.
For those who are interested in bits of the kernel, it’s the following statement in the hrtimer_forward() method of hrtimer.c that overrides timer intervals that are lower than the resolution of the hardware timer in use:
[linux-2.6.29/kernel/hrtimer.c]
if (interval.tv64 < timer->base->resolution.tv64)
interval.tv64 = timer->base->resolution.tv64;
So when dahdi_dummy.c calls this method from dahdi_dummy_hr_int (the interrupt method) with an interval value defined in DAHDI_TIME_NS as 1 000 000 nanoseconds (1/T = 1kHz), it can be reset to a larger value by the kernel code if the current hardware doesn’t support it.
Finally, if you want to be sure that your hrtimer has switched into high resolution mode, you can use this:
hpet-test:/usr/src# dmesg | grep "high resolution" [ 0.318555] checking if image is initramfs...<7>Switched to high resolution mode on CPU 1 [ 0.505710] Switched to high resolution mode on CPU 0
If it didn’t work on your hardware, you should see the message Could not switch to high resolution mode on CPU X.
One Trackback
[...] ? */ if (!hpet && !pm1 && !pm2) { To unsubscribe from this list: send the line …Why the kernel hrtimer might not be a high-resolution timerhpet-test:/usr/src# dmesg | grep hpet [ 0.004000] hpet clockevent registered [ 0.256427] … Here [...]