This seems like a neat idea, but I'm a little worried about the
implementation. Surely someone with 4k+ cpus will complain when the
percpu vvar data exceeds a page and crashes. I have no personal
objection to a dynamically-sized vvar area, but it might need more
careful handling.
I also wonder if there a problem with information leaking. If there
was an entire per-cpu vvar page (perhaps mapped differently on each
cpu) then nothing interesting would leak. But that could add
overhead.
diff --git a/arch/x86/include/asm/vvar.h b/arch/x86/include/asm/vvar.h
index 0fd7a4a..e36e1c1 100644
--- a/arch/x86/include/asm/vvar.h
+++ b/arch/x86/include/asm/vvar.h
@@ -47,5 +47,6 @@
DECLARE_VVAR(0, volatile unsigned long, jiffies)
DECLARE_VVAR(16, int, vgetcpu_mode)
DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data)
+DECLARE_VVAR(2048, struct vcpu_data, vcpu_data)
Any reason this isn't page-aligned? Offset 2048 seems like an odd place.
notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
{
long ret;
- asm("syscall" : "=a" (ret) :
- "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
+ asm volatile("syscall" : "=a" (ret) :
+ "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
return ret;
}
Huh? This should probably be a separate patch (and probably not a
-stable candidate, since it would take amazing compiler stupidity to
generate anything other than the obvious code). The memory clobber
may also be enough to make this officially safe.
+ if (vp->tsc_unstable) {
+ struct timespec ts;
+ vdso_fallback_gettime(CLOCK_THREAD_CPUTIME_ID,&ts);
+ return timespec_to_ns(&ts);
+ }
Yuck -- another flag indicating whether we're using the tsc.
+
+ do {
+ native_read_tscp(&p);
Do all 64-bit cpus have rdtscp? ISTR older Intel machines don't have it.
--- a/arch/x86/vdso/vdso.lds.S
+++ b/arch/x86/vdso/vdso.lds.S
@@ -25,6 +25,8 @@ VERSION {
__vdso_getcpu;
time;
__vdso_time;
+ thread_cpu_time;
+ __vdso_thread_cpu_time;
local: *;
};
}
Why do we have the non-__vdso versions? IMO anything that actually
uses them is likely to be confused. They have the same names as the
glibc wrappers, but the glibc wrappers have different return value and
errno semantics. I'd say just use __vdso.
Also, what's wrong with just adding the functionality to __vdso_clock_gettime?
+struct vcpu_data {
+ struct vpercpu_data vpercpu[NR_CPUS];
+ unsigned int tsc_khz;
I think this also duplicates some of the gtod_data stuff, at least in
the case that TSC works for gtod.