Re: Accurate timers in rumpkernels on Xen / minios

  • From: Antti Kantee <pooka@xxxxxx>
  • To: rumpkernel-users@xxxxxxxxxxxxx
  • Date: Fri, 27 May 2016 10:23:44 +0000

On 27/05/16 09:32, George Dunlap wrote:

The problem I'm having is that the "nsleep()" seems to be quantizing
on 10ms, which is a *lot* less fine-grained than I wanted; the
"max_delta" for each reporting period is almost always a bit over 10ms
(i.e., the maximum amount of time it "overslept").  Below are reports
that happen every 1s; "now" is the time of reporting, "mops" is the
*cumulative* number of operations done (in millions); and max_delta is
the max_delta *for this period* (i.e., it gets reset every second):

{ "now":2033655690, "mops":60, "max_delta":10014214 }
{ "now":3061713795, "mops":118, "max_delta":10015144 }
{ "now":4089251608, "mops":176, "max_delta":10036716 }
{ "now":5117213014, "mops":234, "max_delta":10056997 }
{ "now":6144605339, "mops":292, "max_delta":10041393 }
{ "now":7171986432, "mops":350, "max_delta":10042572 }
{ "now":8199335304, "mops":408, "max_delta":10017662 }
{ "now":9226821190, "mops":466, "max_delta":10060509 }

This may be due to the default timer being set to 10ms; from the
skrool of the rumprun kernel at start-up:

---
timecounter: Timecounters tick every 10.000 msec
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
cpu0 at thinair0: rump virtual cpu
root file system type: rumpfs
kern.module.path=/stand/amd64/7.99.21/modules
mainbus0 (root)
timecounter: Timecounter "bmktc" frequency 1000000000 Hz quality 100
---

I haven't yet traced the actual execution time to know whether it's
the nsleep() that's on a 10ms granularity, or the clock_gettime(), but
either way I need something more accurate.

So my question is, is there a good way to get a sleep timer that will
be more accurate -- sub-millisecond at least, but closer to a
microsecond -- either by using different parts of the POSIX interface,
or by changing the timer interrupt frequency?  (Or perhaps managing to
get it to default to that bmktc timecounter rather than the
clockinterrupt timecounter?)

The better clock should be used automatically since it's of higher quality. The fact that your max_delta is not a multiple of 10ms supports this suspicion. That clock directly uses platform/xen/xen/arch/x86/time.c::bmk_platform_cpu_clock_monotonic(). The domain is put to sleep with block_domain() in the same file.

Based on your email address, I'm sure you know Xen better than I do, but are you sure Xen itself can provide time and sleep with such an accuracy? I'd expect that sort of skew especially with the sleeps in a virtualized environment. If you can produce better accuracy with pure MiniOS, then there's a bug in Rumprun (or in the Rumprun copy of MiniOS in platform/xen).

Other related posts: