On Mon, Jul 31, 2017 at 07:19:36AM +0800, Adam Steen wrote: > Sorry, i sent that before i had finished. > > I am trying to find an equivalent of the following code for FreeBSD > > size_t outsz = sizeof bi->cpu.tsc_freq; > int ret = sysctlbyname("machdep.tsc_freq", &bi->cpu.tsc_freq, &outsz, > NULL, > 0); > if (ret == -1) > err(1, "sysctl(machdep.tsc_freq)"); > int invariant_tsc = 0; > outsz = sizeof invariant_tsc; > ret = sysctlbyname("kern.timecounter.invariant_tsc", &invariant_tsc, > &outsz, > NULL, 0); > if (ret == -1) > err(1, "sysctl(kern.timecounter.invariant_tsc"); > if (invariant_tsc != 1) > errx(1, "Host TSC is not invariant, cannot continue"); > > > line 122-134 of > https://github.com/adamsteen/solo5/blob/master/ukvm/ukvm_hv_freebsd_x86_64.c > > Currently the port fails with "vmx_handle_exit: unhandled exit > 2147483681 (unknown)" (0x80000021 in hex), I am setting up the > registers to incorrect values, but need to read more to understand > what OpenBSD vmm and ukvm are expecting from each other. >
If you point me to a bootable image that causes this failure, I might be able to figure out what vmm(4) doesn't like. Nothing in lines 122-134 of the file indicated above should cause this. -ml > Cheers > Adam > > > Hi Mike > > > > In short i don't want to calculate the TSC frequency, i would like to > > get it from the kernel if possible? (also checking if it was > > invariant.) I knew my code was inaccurate, but didn't know another > > way. > > > > I did check the output of dmesg: "cpu0: TSC frequency 2492310500 Hz', > > but couldn't find a away to get this programmatically, eg via sysctl > > > > Long story, i am in the process of porting Solo5 to OpenBSD (see > > https://github.com/adamsteen/solo5) and need the tsc frequency to > > support the ukvm tsc clock. > > > > Is there currently a way to get the TSC frequency programmatically? > > and is CPUID the best way to check if the tsc is invariant? > > (CPUID.80000007H:EDX[8], Intel's Designer's vol3b, section 16.11.1 > > Invariant TSC) > > > > On Mon, Jul 31, 2017 at 1:57 AM, Mike Belopuhov <m...@belopuhov.com> wrote: > >> On Wed, Jul 26, 2017 at 19:24 +0800, Adam Steen wrote: > >>> Hi > >>> > >>> Is there an easy/accurate way to calculate the tsc timecounter frequency? > >>> like Time Stamp Counters <http://blog.tinola.com/?e=54> on Linux. (on a > >>> Sandy Bridge cpu) > >>> > >>> Another reference Converting Sandy Bridge TSC to wall clock time > >>> <https://software.intel.com/en-us/forums/intel-isa-extensions/topic/284137>. > >>> > >>> The code below works but i don't really know how accurate it is, at best > >>> 10,000 Hz. > >>> > >>> Cheers > >>> Adam > >>> > >> > >> Hi, > >> > >> First of all it's not clear why do you want to calculate TSC > >> frequency in the userland program? The kernel does it and > >> prints the result to the system message buffer (viewed with > >> the dmesg command). > >> > >> The second thing worth pointing out is that gettimeofday is a > >> syscall that queries the timestamp from the timecounter code > >> (updated every 10ms) with a current delta read directly from > >> the hardware so that you get an accurate reading, but then > >> it's adjusted according to the system time adjustment rules > >> imposed by things like NTP and settimeofday, so essentially > >> it's not monotonic (unless you can ensure there is no actor > >> present that is adjusting the time while you're performing > >> your measurement). There's also a way for userland to query > >> a precise monotonically increasing timestamp: clock_gettime > >> with CLOCK_MONOTONIC as the clock_id. In this case the > >> returned timestamp is relative to the moment the system was > >> brought up but this doesn't matter if all you need is > >> difference. > >> > >> The third thing to know is where does this hardware reading > >> comes from and what's its precision. Running "sysctl -n > >> kern.timecounter.hardware" will tell you what is currently > >> selected as the source and then you can locate that device > >> your dmesg (with exception of i8254 -- that 1.19Mhz PIT). > >> For instance on my laptop it's ACPI HPET that is proving a > >> running counter with the frequency of 14 MHz. This is what's > >> going to limit the precision of your measurement. > >> > >> To get a better reading you may try to take a series of say > >> 10 measurements and calculate the average. > >> > >> The difference between RDTSC and RDTSCP is that the latter > >> tells you on which CPU the instruction was executed. This > >> poses a valid question: is TSC frequency the same on a multi- > >> socket system. And I don't have an answer for that one. > >> AFAIU, this boils down to the motherboard design and if the > >> manufacturer has selected to use different quartz crystals > >> for different sockets, then as we know for a fact that no two > >> quartz crystals are created the same and thus frequency > >> sourced from them and multiplied by clock generator PLLs to > >> produce bus and then core clock signals will be slightly > >> different between sockets. I believe there's a way to > >> compensate for that but OpenBSD doesn't do this currently. > >> > >> However, your code doesn't check on which CPU the RDTSC has > >> been executed so you can just use RDTSC and hope that TSC > >> frequencies are the same and all counters on all cores have > >> been started at the same time by the firmware (which is > >> another question whether or not this is actually true). > >> > >> The CPUID call that you can see used there is there to > >> provide serialization. I believe there's no need to do it in > >> this case. In fact we haven't observed adverse effects w/o > >> an additional serialization instruction on Skylake where TSC > >> is used as the default timecounter (e.g. instead of an HPET). > >> > >> The other issue with your program is that you don't account > >> for how long does it take to perform a syscall operation. You > >> could time it before running the loop and then subtract the > >> reading. > >> > >> And finally, a userland program will not run a 1 second loop > >> uninterrupted since the scheduler will always attempt to > >> select a different process every 10ms. Which means that > >> a potential context switch and a 10ms timeslice of another > >> process might make its way into your measurement. > >> > >> This all begs the same question I asked in the beginning: why > >> do you want to calculate the TSC frequency in the userland > >> program? > >> > >> >