On 2020-07-27 18:24, Mark Kettenis wrote:
Date: Mon, 27 Jul 2020 17:14:21 +0200
From: Christian Weisgerber <[email protected]>
Scott Cheloha:
--- lib/libc/arch/amd64/gen/usertc.c 8 Jul 2020 09:17:48 -0000 1.2
+++ lib/libc/arch/amd64/gen/usertc.c 25 Jul 2020 17:50:38 -0000
@@ -21,9 +21,12 @@
static inline u_int
rdtsc(void)
{
- uint32_t hi, lo;
- asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
- return ((uint64_t)lo)|(((uint64_t)hi)<<32);
+ uint32_t lo;
+
+ asm volatile("lfence");
+ asm volatile("rdtsc" : "=a"(lo) : : "rdx");
Is there a guarantee that two separate asm()s will not be reordered?
I believe that is true for "volatile" asm statements. But this is all
not very well documented and I believe that the compiler may hoist
bits of C code in between, which is probably not what you want.
Note that since "asm" is non-standard C, we favour spelling it as
"__asm" since that makes the compiler shut up about it even if you
request stricter C standard compliance.
And given the kernel bit nelow...
+
+ return lo;
}
static int
--- sys/arch/amd64/amd64/tsc.c 6 Jul 2020 13:33:06 -0000 1.19
+++ sys/arch/amd64/amd64/tsc.c 25 Jul 2020 17:50:38 -0000
@@ -211,7 +211,12 @@ cpu_recalibrate_tsc(struct timecounter *
u_int
tsc_get_timecount(struct timecounter *tc)
{
- return rdtsc() + curcpu()->ci_tsc_skew;
+ uint32_t lo;
+
+ asm volatile("lfence");
+ asm volatile("rdtsc" : "=a"(lo) : : "rdx");
+
+ return lo + curcpu()->ci_tsc_skew;
}
void
I'd just do s/rdtsc/rdtsc_lfence/, which would agree well with the
rest of the file.
Agreed. And I would really prefer that the libc code stays as close
to the kernel code as possible.
Is the issue with LFENCE slowing down the network stack settled? That
was the argument against it last time.