* Julien Desfossez ([email protected]) wrote: > This option allows the user to fetch the current time in sec.nsec based > on the current TSC using the LTTng infrastructure. > If the TSC is not synchronized we return an error to the user. > > The main change from the previous version of this patch is the > conversion of the TSC in sec.nsec instead of encoding it in the timespec > struct. Also now we check if the TSC is synchronized and we export this > information along with the CPU frequency in the vDSO shared structure. > > The next step is to make this code work even if vDSOs are not available and > then to find a way to call {get,put}_trace_clock from inside the vDSO to > activate the archtitecture specific debug infrastructure if necessary, but > this > should probably come in a different patch.
Yes, you are right. Please keep this as a separate patch. > > Signed-off-by: Julien Desfossez <[email protected]> > --- > arch/x86/include/asm/trace-clock.h | 1 + > arch/x86/include/asm/vgtod.h | 2 ++ > arch/x86/kernel/vsyscall_64.c | 5 +++++ > arch/x86/vdso/vclock_gettime.c | 36 > ++++++++++++++++++++++++++++++++++++ > include/linux/time.h | 1 + > 5 files changed, 45 insertions(+), 0 deletions(-) > > diff --git a/arch/x86/include/asm/trace-clock.h > b/arch/x86/include/asm/trace-clock.h > index 01bc2f5..c1fd160 100644 > --- a/arch/x86/include/asm/trace-clock.h > +++ b/arch/x86/include/asm/trace-clock.h > @@ -14,6 +14,7 @@ > #include <asm/system.h> > #include <asm/processor.h> > #include <asm/atomic.h> > +#include <asm/vgtod.h> > > /* Minimum duration of a probe, in cycles */ > #define TRACE_CLOCK_MIN_PROBE_DURATION 200 > diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h > index 3d61e20..7b6f50b 100644 > --- a/arch/x86/include/asm/vgtod.h > +++ b/arch/x86/include/asm/vgtod.h > @@ -12,6 +12,8 @@ struct vsyscall_gtod_data { > u32 wall_time_nsec; > > int sysctl_enabled; > + int trace_clock_is_sync; > + u64 scaled_cpu_khz; > struct timezone sys_tz; > struct { /* extract of a clocksource struct */ > cycle_t (*vread)(void); > diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c > index dcbb28c..b5d52ab 100644 > --- a/arch/x86/kernel/vsyscall_64.c > +++ b/arch/x86/kernel/vsyscall_64.c > @@ -44,6 +44,8 @@ > #include <asm/desc.h> > #include <asm/topology.h> > #include <asm/vgtod.h> > +#include <asm/trace-clock.h> > +#include <asm/timer.h> > > #define __vsyscall(nr) \ > __attribute__ ((unused, __section__(".vsyscall_" #nr))) notrace > @@ -61,6 +63,7 @@ struct vsyscall_gtod_data __vsyscall_gtod_data > __section_vsyscall_gtod_data = > { > .lock = SEQLOCK_UNLOCKED, > .sysctl_enabled = 1, > + .trace_clock_is_sync = 0, > }; > > void update_vsyscall_tz(void) > @@ -89,6 +92,8 @@ void update_vsyscall(struct timespec *wall_time, struct > timespec *wtm, > vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; > vsyscall_gtod_data.wall_to_monotonic = *wtm; > vsyscall_gtod_data.wall_time_coarse = __current_kernel_time(); > + vsyscall_gtod_data.scaled_cpu_khz = (u64)cpu_khz >> CYC2NS_SCALE_FACTOR; > + vsyscall_gtod_data.trace_clock_is_sync = _trace_clock_is_sync; > write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); > } > > diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c > index ee55754..8574ba6 100644 > --- a/arch/x86/vdso/vclock_gettime.c > +++ b/arch/x86/vdso/vclock_gettime.c > @@ -22,6 +22,8 @@ > #include <asm/hpet.h> > #include <asm/unistd.h> > #include <asm/io.h> > +#include <asm/trace-clock.h> > +#include <asm/timer.h> > #include "vextern.h" > > #define gtod vdso_vsyscall_gtod_data > @@ -69,6 +71,7 @@ vset_normalized_timespec(struct timespec *ts, long sec, > long nsec) > --sec; > } > ts->tv_sec = sec; > + whitespace. > ts->tv_nsec = nsec; > } > > @@ -111,6 +114,33 @@ notrace static noinline int do_monotonic_coarse(struct > timespec *ts) > return 0; > } > > +#ifdef CONFIG_X86 > +notrace static noinline int do_trace_clock(struct timespec *ts) > +{ > + cycle_t cycles; > + unsigned long tmp; > + > + if (!gtod->trace_clock_is_sync) > + return -EPERM; > + > + /* Copy of the version in kernel/tsc.c which we cannot directly access > + * > + * Surround the RDTSC by barriers, to make sure it's not > + * speculated to outside the seqlock critical section and > + * does not cause time warps: > + */ > + rdtsc_barrier(); > + cycles = (cycle_t)vget_cycles(); > + rdtsc_barrier(); > + > + tmp = cycles*(USEC_PER_SEC / gtod->scaled_cpu_khz) >> > CYC2NS_SCALE_FACTOR; Is it me or the seqlock is missing ? Thanks, Mathieu > + ts->tv_nsec = do_div(tmp, NSEC_PER_SEC); > + ts->tv_sec = tmp; > + > + return 0; > +} > +#endif /* CONFIG_X86 */ > + > notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) > { > if (likely(gtod->sysctl_enabled)) > @@ -127,6 +157,12 @@ notrace int __vdso_clock_gettime(clockid_t clock, struct > timespec *ts) > return do_realtime_coarse(ts); > case CLOCK_MONOTONIC_COARSE: > return do_monotonic_coarse(ts); > +#ifdef CONFIG_X86 > + case CLOCK_TRACE: > + return do_trace_clock(ts); > +#endif > + default: > + return -EINVAL; > } > return vdso_fallback_gettime(clock, ts); > } > diff --git a/include/linux/time.h b/include/linux/time.h > index 9f15ac7..bf638ff 100644 > --- a/include/linux/time.h > +++ b/include/linux/time.h > @@ -290,6 +290,7 @@ struct itimerval { > #define CLOCK_MONOTONIC_RAW 4 > #define CLOCK_REALTIME_COARSE 5 > #define CLOCK_MONOTONIC_COARSE 6 > +#define CLOCK_TRACE 7 > > /* > * The IDs of various hardware clocks: > -- > 1.7.0.4 > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com _______________________________________________ ltt-dev mailing list [email protected] http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
