Page MenuHomeFreeBSD

Make userspace gettimeofday(2) work for HPET timecounter hardware.
ClosedPublic

Authored by kib on Aug 11 2016, 10:02 AM.

Details

Summary

Right now, userspace (fast) gettimeofday(2) on x86 only works for RDTSC. For older machines, like Core2, where RDTSC is not C2/C3 invariant, and which fall to HPET hardware, this means that the call has both the penalty of the syscall and of the uncached hw behind the QPI or PCIe connection to the sought bridge. We cannot do anything against the access latency, but the syscall overhead can be removed. We have mappable /dev/hpetX devices, which can be used there.

Patch adds yet another algorithm to the x86 'vdso' timehands. Libc is updated to handle both RDTSC and HPET. For HPET, the index of the hpet device to mmap is passed, index might be changed and libc invalidates its mapping.

The cpu_fill_vdso_timehands() functions are removed, instead timecounters get the method to fill vdso timehands, which makes the new algorithms additions to the kernel side rather clean. Libc does have to switch() based on the algo variant still.

I changed the hpet device permissions from 0600 to 0644. There are additional knobs which disable mmapings, honored for libc fast_gettime knob, and there are devfs usual methods to control permissions. But in fact, I do not see anything wrong with providing userspace the read-only access to the HPET registers page unconditionally.

Test Plan

Patch was tested on SandyBridge, amd64 kernel, both with 64 and 32 bit libc. The syscall_timing tool measurements results are below. Note that RDTSC with syscall is faster than userspace HPET access. But still, userspace HPET is four times faster than syscall HPET.

TSC/fast_gettime
Clock resolution: 0.000000001
test    loop    time    iterations      periteration
gettimeofday    0       1.007928510     52591682        0.000000019
gettimeofday    1       1.043998478     54486193        0.000000019
gettimeofday    2       1.043989482     54433115        0.000000019
gettimeofday    3       1.043997933     54474925        0.000000019
gettimeofday    4       1.040992803     53948267        0.000000019
gettimeofday    5       1.043994609     54500053        0.000000019
gettimeofday    6       1.020053741     53194581        0.000000019
gettimeofday    7       1.043989787     54482331        0.000000019
gettimeofday    8       1.043994915     54525097        0.000000019
gettimeofday    9       1.031130020     53843960        0.000000019

HPET/fast_gettime
Clock resolution: 0.000000070
test    loop    time    iterations      periteration
gettimeofday    0       1.000992061     1723026 0.000000580
gettimeofday    1       1.000910519     1721538 0.000000581
gettimeofday    2       1.000068005     1720167 0.000000581
gettimeofday    3       1.001043273     1720474 0.000000581
gettimeofday    4       1.000974022     1723124 0.000000580
gettimeofday    5       1.000955265     1721566 0.000000581
gettimeofday    6       1.004998299     1728666 0.000000581
gettimeofday    7       1.043984721     1794984 0.000000581
gettimeofday    8       1.035997777     1783213 0.000000580
gettimeofday    9       1.047979740     1802630 0.000000581

syscall/TSC
Clock resolution: 0.000000001
test    loop    time    iterations      periteration
gettimeofday    0       1.004486363     3588937 0.000000279
gettimeofday    1       1.042046225     3721676 0.000000279
gettimeofday    2       1.025922097     3661175 0.000000280
gettimeofday    3       1.012252698     3615760 0.000000279
gettimeofday    4       1.021744804     3649573 0.000000279
gettimeofday    5       1.043990357     3702818 0.000000281
gettimeofday    6       1.043995558     3725780 0.000000280
gettimeofday    7       1.043994414     3727664 0.000000280
gettimeofday    8       1.022993828     3653711 0.000000279
gettimeofday    9       1.043989137     3729411 0.000000279

syscall/HPET
Clock resolution: 0.000000070
test    loop    time    iterations      periteration
gettimeofday    0       1.024957696     414023  0.000002475
gettimeofday    1       1.001028436     404051  0.000002477
gettimeofday    2       1.023964920     413640  0.000002475
gettimeofday    3       1.004981756     406646  0.000002471
gettimeofday    4       1.007988443     408052  0.000002470
gettimeofday    5       1.001993736     404759  0.000002475
gettimeofday    6       1.043990521     422299  0.000002472
gettimeofday    7       1.030991827     416968  0.000002472
gettimeofday    8       1.011988548     408502  0.000002477
gettimeofday    9       1.017240226     406376  0.000002503

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

kib updated this revision to Diff 19206.Aug 11 2016, 10:02 AM
kib retitled this revision from to Make userspace gettimeofday(2) work for HPET timecounter hardware..
kib updated this object.
kib edited the test plan for this revision. (Show Details)
kib added reviewers: jhb, mav.
kib set the repository for this revision to rS FreeBSD src repository.
kib added a subscriber: emaste.
This revision was automatically updated to reflect the committed changes.