Why the kernel hrtimer might not be a high-resolution timer

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.

This entry was posted in Virtualisation, VoIP and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Trackback

  1. By hpet on April 6, 2010 at 7:11 am

    [...] ? */ 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 [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

What is 14 + 14 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple question (so we know that you are a human)