Another go at ktime_get_raw_fast_ns()
cover Another go at ktime_get_raw_fast_ns()
Hi John,
So yeah, I just didn't try hard enough it seems; how about this?
Also, I think we should double check that everything passed to tk_setup_internals(.clock) is either static storage or RCU-sched freed, because with the whole latch thing one CPUs (fast) access might still be in progress while the other is freeing the clock struct.
Not sure what the lifetime rules of struct clocksource are here.
RFC PATCH 1/4 time: Rename timekeeper::tkr to timekeeper::tkr_mono
In preparation of adding another tkr field, rename this one to tkr_mono. Also rename tk_read_base::base_mono to tk_read_base::base, since the structure is not specific to CLOCK_MONOTONIC and the mono name got added to the tk_read_base instance.
Lots of trivial churn.
--- arch/arm64/kernel/vdso.c | 10 +- arch/s390/kernel/time.c | 18 ++-- arch/tile/kernel/time.c | 24 ++--- arch/x86/kernel/vsyscall_gtod.c | 24 ++--- arch/x86/kvm/x86.c | 14 +-- include/linux/timekeeper_internal.h | 12 +- kernel/time/timekeeping.c | 150 ++++++++++++++++++------------------ 7 files changed, 126 insertions(+), 126 deletions(-)
arch/arm64/kernel/vdso.c +5 -5
@@ -200,7 +200,7 @@ int arch_setup_additional_pages(struct lvoid update_vsyscall (struct timekeeper *tk) {struct timespec xtime_coarse; -u32 use_syscall =strcmp (tk->tkr.clock->name,"arch_sys_counter" ); +u32 use_syscall =strcmp (tk->tkr_mono.clock->name,"arch_sys_counter" ); ++vdso_data->tb_seq_count;smp_wmb ();
@@ -213,11 +213,11 @@ void update_vsyscall(struct timekeeper * vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;if (!use_syscall) { - vdso_data->cs_cycle_last = tk->tkr.cycle_last; + vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec; - vdso_data->cs_mult = tk->tkr.mult; - vdso_data->cs_shift = tk->tkr.shift; + vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; + vdso_data->cs_mult = tk->tkr_mono.mult; + vdso_data->cs_shift = tk->tkr_mono.shift; }smp_wmb ();
arch/s390/kernel/time.c +9 -9
@@ -215,20 +215,20 @@ void update_vsyscall(struct timekeeper * {u64 nsecps; -if (tk->tkr.clock != &clocksource_tod) +if (tk->tkr_mono.clock != &clocksource_tod)return ;/* Make userspace gettimeofday spin until we're done. */ ++vdso_data->tb_update_count;smp_wmb (); - vdso_data->xtime_tod_stamp = tk->tkr.cycle_last; + vdso_data->xtime_tod_stamp = tk->tkr_mono.cycle_last; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec; + vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; vdso_data->wtom_clock_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->wtom_clock_nsec = tk->tkr.xtime_nsec + - + ((u64 ) tk->wall_to_monotonic.tv_nsec << tk->tkr.shift); - nsecps = (u64 )NSEC_PER_SEC << tk->tkr.shift; + vdso_data->wtom_clock_nsec = tk->tkr_mono.xtime_nsec + + + ((u64 ) tk->wall_to_monotonic.tv_nsec << tk->tkr_mono.shift); + nsecps = (u64 )NSEC_PER_SEC << tk->tkr_mono.shift;while (vdso_data->wtom_clock_nsec >= nsecps) { vdso_data->wtom_clock_nsec -= nsecps; vdso_data->wtom_clock_sec++;
@@ -236,7 +236,7 @@ void update_vsyscall(struct timekeeper * vdso_data->xtime_coarse_sec = tk->xtime_sec; vdso_data->xtime_coarse_nsec = - (long )(tk->tkr.xtime_nsec >> tk->tkr.shift); + (long )(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); vdso_data->wtom_coarse_sec = vdso_data->xtime_coarse_sec + tk->wall_to_monotonic.tv_sec; vdso_data->wtom_coarse_nsec =
@@ -246,8 +246,8 @@ void update_vsyscall(struct timekeeper * vdso_data->wtom_coarse_sec++; } - vdso_data->tk_mult = tk->tkr.mult; - vdso_data->tk_shift = tk->tkr.shift; + vdso_data->tk_mult = tk->tkr_mono.mult; + vdso_data->tk_shift = tk->tkr_mono.shift;smp_wmb (); ++vdso_data->tb_update_count; }
arch/tile/kernel/time.c +12 -12
@@ -257,34 +257,34 @@ void update_vsyscall_tz(void)void update_vsyscall (struct timekeeper *tk) { -if (tk->tkr.clock != &cycle_counter_cs) +if (tk->tkr_mono.clock != &cycle_counter_cs)return ;write_seqcount_begin (&vdso_data->tb_seq); - vdso_data->cycle_last = tk->tkr.cycle_last; - vdso_data->mask = tk->tkr.mask; - vdso_data->mult = tk->tkr.mult; - vdso_data->shift = tk->tkr.shift; + vdso_data->cycle_last = tk->tkr_mono.cycle_last; + vdso_data->mask = tk->tkr_mono.mask; + vdso_data->mult = tk->tkr_mono.mult; + vdso_data->shift = tk->tkr_mono.shift; vdso_data->wall_time_sec = tk->xtime_sec; - vdso_data->wall_time_snsec = tk->tkr.xtime_nsec; + vdso_data->wall_time_snsec = tk->tkr_mono.xtime_nsec; vdso_data->monotonic_time_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->monotonic_time_snsec = tk->tkr.xtime_nsec + vdso_data->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + ((u64 )tk->wall_to_monotonic.tv_nsec - << tk->tkr.shift); + << tk->tkr_mono.shift);while (vdso_data->monotonic_time_snsec >= - (((u64 )NSEC_PER_SEC ) << tk->tkr.shift)) { + (((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift)) { vdso_data->monotonic_time_snsec -= - ((u64 )NSEC_PER_SEC ) << tk->tkr.shift; + ((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift; vdso_data->monotonic_time_sec++; } vdso_data->wall_time_coarse_sec = tk->xtime_sec; - vdso_data->wall_time_coarse_nsec = (long )(tk->tkr.xtime_nsec >> - tk->tkr.shift); + vdso_data->wall_time_coarse_nsec = (long )(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdso_data->monotonic_time_coarse_sec = vdso_data->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
arch/x86/kernel/vsyscall_gtod.c +12 -12
@@ -31,30 +31,30 @@ void update_vsyscall(struct timekeeper *gtod_write_begin (vdata);/* copy vsyscall data */ - vdata->vclock_mode = tk->tkr.clock->archdata.vclock_mode; - vdata->cycle_last = tk->tkr.cycle_last; - vdata->mask = tk->tkr.mask; - vdata->mult = tk->tkr.mult; - vdata->shift = tk->tkr.shift; + vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->cycle_last = tk->tkr_mono.cycle_last; + vdata->mask = tk->tkr_mono.mask; + vdata->mult = tk->tkr_mono.mult; + vdata->shift = tk->tkr_mono.shift; vdata->wall_time_sec = tk->xtime_sec; - vdata->wall_time_snsec = tk->tkr.xtime_nsec; + vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; vdata->monotonic_time_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdata->monotonic_time_snsec = tk->tkr.xtime_nsec + vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + ((u64 )tk->wall_to_monotonic.tv_nsec - << tk->tkr.shift); + << tk->tkr_mono.shift);while (vdata->monotonic_time_snsec >= - (((u64 )NSEC_PER_SEC ) << tk->tkr.shift)) { + (((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift)) { vdata->monotonic_time_snsec -= - ((u64 )NSEC_PER_SEC ) << tk->tkr.shift; + ((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift; vdata->monotonic_time_sec++; } vdata->wall_time_coarse_sec = tk->xtime_sec; - vdata->wall_time_coarse_nsec = (long )(tk->tkr.xtime_nsec >> - tk->tkr.shift); + vdata->wall_time_coarse_nsec = (long )(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdata->monotonic_time_coarse_sec = vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
arch/x86/kvm/x86.c +7 -7
@@ -1070,19 +1070,19 @@ static void update_pvclock_gtod(struct tstruct pvclock_gtod_data *vdata = &pvclock_gtod_data;u64 boot_ns; - boot_ns =ktime_to_ns (ktime_add (tk->tkr.base_mono, tk->offs_boot)); + boot_ns =ktime_to_ns (ktime_add (tk->tkr_mono.base, tk->offs_boot));write_seqcount_begin (&vdata->seq);/* copy pvclock gtod data */ - vdata->clock.vclock_mode = tk->tkr.clock->archdata.vclock_mode; - vdata->clock.cycle_last = tk->tkr.cycle_last; - vdata->clock.mask = tk->tkr.mask; - vdata->clock.mult = tk->tkr.mult; - vdata->clock.shift = tk->tkr.shift; + vdata->clock.vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->clock.cycle_last = tk->tkr_mono.cycle_last; + vdata->clock.mask = tk->tkr_mono.mask; + vdata->clock.mult = tk->tkr_mono.mult; + vdata->clock.shift = tk->tkr_mono.shift; vdata->boot_ns = boot_ns; - vdata->nsec_base = tk->tkr.xtime_nsec; + vdata->nsec_base = tk->tkr_mono.xtime_nsec;write_seqcount_end (&vdata->seq); }
include/linux/timekeeper_internal.h +6 -6
@@ -16,16 +16,16 @@* @read: Read function of @clock * @mask: Bitmask for two's complement subtraction of non 64bit clocks * @cycle_last: @clock cycle value at last update -* @mult: NTP adjusted multiplier for scaled math conversion +* @mult: (NTP adjusted) multiplier for scaled math conversion * @shift: Shift value for scaled math conversion * @xtime_nsec: Shifted (fractional) nano seconds offset for readout -* @base_mono: ktime_t (nanoseconds) base time for readout +* @base: ktime_t (nanoseconds) base time for readout * * This struct has size 56 byte on 64 bit. Together with a seqcount it * occupies a single 64byte cache line. * * The struct is separate from struct timekeeper as it is also used -* for a fast NMI safe accessor to clock monotonic. +* for a fast NMI safe accessors. */ struct tk_read_base {struct clocksource *clock;
@@ -35,12 +35,12 @@ struct tk_read_base {u32 mult;u32 shift;u64 xtime_nsec; -ktime_t base_mono; +ktime_t base; };/** * struct timekeeper - Structure holding internal timekeeping values. -* @tkr: The readout base structure +* @tkr_mono: The readout base structure for CLOCK_MONOTONIC * @xtime_sec: Current CLOCK_REALTIME time in seconds * @ktime_sec: Current CLOCK_MONOTONIC time in seconds * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
@@ -76,7 +76,7 @@ struct tk_read_base {* used instead. */ struct timekeeper { -struct tk_read_base tkr; +struct tk_read_base tkr_mono;u64 xtime_sec;unsigned long ktime_sec;struct timespec64 wall_to_monotonic;
kernel/time/timekeeping.c +75 -75
405 lines not on this page · raw message
tip-bot for Peter Zijlstra
merge bot[tip:perf/timer] time: Rename timekeeper::tkr to timekeeper:: tkr_mono
time: Rename timekeeper::tkr to timekeeper::tkr_mono
Commit-ID: 876e78818def2983be55878b21f7152fbaebbd36 Gitweb: http://git.kernel.org/tip/876e78818def2983be55878b21f7152fbaebbd36 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 19 Mar 2015 10:09:06 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 27 Mar 2015 09:45:06 +0100
time: Rename timekeeper::tkr to timekeeper::tkr_mono
In preparation of adding another tkr field, rename this one to tkr_mono. Also rename tk_read_base::base_mono to tk_read_base::base, since the structure is not specific to CLOCK_MONOTONIC and the mono name got added to the tk_read_base instance.
Lots of trivial churn.
--- arch/arm64/kernel/vdso.c | 10 +-- arch/s390/kernel/time.c | 18 ++--- arch/tile/kernel/time.c | 24 +++--- arch/x86/kernel/vsyscall_gtod.c | 24 +++--- arch/x86/kvm/x86.c | 14 ++-- include/linux/timekeeper_internal.h | 12 +-- kernel/time/timekeeping.c | 150 ++++++++++++++++++------------------ 7 files changed, 126 insertions(+), 126 deletions(-)
arch/arm64/kernel/vdso.c +5 -5
@@ -200,7 +200,7 @@ up_fail:void update_vsyscall (struct timekeeper *tk) {struct timespec xtime_coarse; -u32 use_syscall =strcmp (tk->tkr.clock->name,"arch_sys_counter" ); +u32 use_syscall =strcmp (tk->tkr_mono.clock->name,"arch_sys_counter" ); ++vdso_data->tb_seq_count;smp_wmb ();
@@ -213,11 +213,11 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;if (!use_syscall) { - vdso_data->cs_cycle_last = tk->tkr.cycle_last; + vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec; - vdso_data->cs_mult = tk->tkr.mult; - vdso_data->cs_shift = tk->tkr.shift; + vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; + vdso_data->cs_mult = tk->tkr_mono.mult; + vdso_data->cs_shift = tk->tkr_mono.shift; }smp_wmb ();
arch/s390/kernel/time.c +9 -9
@@ -215,20 +215,20 @@ void update_vsyscall(struct timekeeper *tk) {u64 nsecps; -if (tk->tkr.clock != &clocksource_tod) +if (tk->tkr_mono.clock != &clocksource_tod)return ;/* Make userspace gettimeofday spin until we're done. */ ++vdso_data->tb_update_count;smp_wmb (); - vdso_data->xtime_tod_stamp = tk->tkr.cycle_last; + vdso_data->xtime_tod_stamp = tk->tkr_mono.cycle_last; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec; + vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; vdso_data->wtom_clock_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->wtom_clock_nsec = tk->tkr.xtime_nsec + - + ((u64 ) tk->wall_to_monotonic.tv_nsec << tk->tkr.shift); - nsecps = (u64 )NSEC_PER_SEC << tk->tkr.shift; + vdso_data->wtom_clock_nsec = tk->tkr_mono.xtime_nsec + + + ((u64 ) tk->wall_to_monotonic.tv_nsec << tk->tkr_mono.shift); + nsecps = (u64 )NSEC_PER_SEC << tk->tkr_mono.shift;while (vdso_data->wtom_clock_nsec >= nsecps) { vdso_data->wtom_clock_nsec -= nsecps; vdso_data->wtom_clock_sec++;
@@ -236,7 +236,7 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->xtime_coarse_sec = tk->xtime_sec; vdso_data->xtime_coarse_nsec = - (long )(tk->tkr.xtime_nsec >> tk->tkr.shift); + (long )(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); vdso_data->wtom_coarse_sec = vdso_data->xtime_coarse_sec + tk->wall_to_monotonic.tv_sec; vdso_data->wtom_coarse_nsec =
@@ -246,8 +246,8 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtom_coarse_sec++; } - vdso_data->tk_mult = tk->tkr.mult; - vdso_data->tk_shift = tk->tkr.shift; + vdso_data->tk_mult = tk->tkr_mono.mult; + vdso_data->tk_shift = tk->tkr_mono.shift;smp_wmb (); ++vdso_data->tb_update_count; }
arch/tile/kernel/time.c +12 -12
@@ -257,34 +257,34 @@ void update_vsyscall_tz(void)void update_vsyscall (struct timekeeper *tk) { -if (tk->tkr.clock != &cycle_counter_cs) +if (tk->tkr_mono.clock != &cycle_counter_cs)return ;write_seqcount_begin (&vdso_data->tb_seq); - vdso_data->cycle_last = tk->tkr.cycle_last; - vdso_data->mask = tk->tkr.mask; - vdso_data->mult = tk->tkr.mult; - vdso_data->shift = tk->tkr.shift; + vdso_data->cycle_last = tk->tkr_mono.cycle_last; + vdso_data->mask = tk->tkr_mono.mask; + vdso_data->mult = tk->tkr_mono.mult; + vdso_data->shift = tk->tkr_mono.shift; vdso_data->wall_time_sec = tk->xtime_sec; - vdso_data->wall_time_snsec = tk->tkr.xtime_nsec; + vdso_data->wall_time_snsec = tk->tkr_mono.xtime_nsec; vdso_data->monotonic_time_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->monotonic_time_snsec = tk->tkr.xtime_nsec + vdso_data->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + ((u64 )tk->wall_to_monotonic.tv_nsec - << tk->tkr.shift); + << tk->tkr_mono.shift);while (vdso_data->monotonic_time_snsec >= - (((u64 )NSEC_PER_SEC ) << tk->tkr.shift)) { + (((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift)) { vdso_data->monotonic_time_snsec -= - ((u64 )NSEC_PER_SEC ) << tk->tkr.shift; + ((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift; vdso_data->monotonic_time_sec++; } vdso_data->wall_time_coarse_sec = tk->xtime_sec; - vdso_data->wall_time_coarse_nsec = (long )(tk->tkr.xtime_nsec >> - tk->tkr.shift); + vdso_data->wall_time_coarse_nsec = (long )(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdso_data->monotonic_time_coarse_sec = vdso_data->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
arch/x86/kernel/vsyscall_gtod.c +12 -12
@@ -31,30 +31,30 @@ void update_vsyscall(struct timekeeper *tk)gtod_write_begin (vdata);/* copy vsyscall data */ - vdata->vclock_mode = tk->tkr.clock->archdata.vclock_mode; - vdata->cycle_last = tk->tkr.cycle_last; - vdata->mask = tk->tkr.mask; - vdata->mult = tk->tkr.mult; - vdata->shift = tk->tkr.shift; + vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->cycle_last = tk->tkr_mono.cycle_last; + vdata->mask = tk->tkr_mono.mask; + vdata->mult = tk->tkr_mono.mult; + vdata->shift = tk->tkr_mono.shift; vdata->wall_time_sec = tk->xtime_sec; - vdata->wall_time_snsec = tk->tkr.xtime_nsec; + vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; vdata->monotonic_time_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdata->monotonic_time_snsec = tk->tkr.xtime_nsec + vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + ((u64 )tk->wall_to_monotonic.tv_nsec - << tk->tkr.shift); + << tk->tkr_mono.shift);while (vdata->monotonic_time_snsec >= - (((u64 )NSEC_PER_SEC ) << tk->tkr.shift)) { + (((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift)) { vdata->monotonic_time_snsec -= - ((u64 )NSEC_PER_SEC ) << tk->tkr.shift; + ((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift; vdata->monotonic_time_sec++; } vdata->wall_time_coarse_sec = tk->xtime_sec; - vdata->wall_time_coarse_nsec = (long )(tk->tkr.xtime_nsec >> - tk->tkr.shift); + vdata->wall_time_coarse_nsec = (long )(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdata->monotonic_time_coarse_sec = vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
arch/x86/kvm/x86.c +7 -7
@@ -1070,19 +1070,19 @@ static void update_pvclock_gtod(struct timekeeper *tk)struct pvclock_gtod_data *vdata = &pvclock_gtod_data;u64 boot_ns; - boot_ns =ktime_to_ns (ktime_add (tk->tkr.base_mono, tk->offs_boot)); + boot_ns =ktime_to_ns (ktime_add (tk->tkr_mono.base, tk->offs_boot));write_seqcount_begin (&vdata->seq);/* copy pvclock gtod data */ - vdata->clock.vclock_mode = tk->tkr.clock->archdata.vclock_mode; - vdata->clock.cycle_last = tk->tkr.cycle_last; - vdata->clock.mask = tk->tkr.mask; - vdata->clock.mult = tk->tkr.mult; - vdata->clock.shift = tk->tkr.shift; + vdata->clock.vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->clock.cycle_last = tk->tkr_mono.cycle_last; + vdata->clock.mask = tk->tkr_mono.mask; + vdata->clock.mult = tk->tkr_mono.mult; + vdata->clock.shift = tk->tkr_mono.shift; vdata->boot_ns = boot_ns; - vdata->nsec_base = tk->tkr.xtime_nsec; + vdata->nsec_base = tk->tkr_mono.xtime_nsec;write_seqcount_end (&vdata->seq); }
include/linux/timekeeper_internal.h +6 -6
@@ -16,16 +16,16 @@* @read: Read function of @clock * @mask: Bitmask for two's complement subtraction of non 64bit clocks * @cycle_last: @clock cycle value at last update -* @mult: NTP adjusted multiplier for scaled math conversion +* @mult: (NTP adjusted) multiplier for scaled math conversion * @shift: Shift value for scaled math conversion * @xtime_nsec: Shifted (fractional) nano seconds offset for readout -* @base_mono: ktime_t (nanoseconds) base time for readout +* @base: ktime_t (nanoseconds) base time for readout * * This struct has size 56 byte on 64 bit. Together with a seqcount it * occupies a single 64byte cache line. * * The struct is separate from struct timekeeper as it is also used -* for a fast NMI safe accessor to clock monotonic. +* for a fast NMI safe accessors. */ struct tk_read_base {struct clocksource *clock;
@@ -35,12 +35,12 @@ struct tk_read_base {u32 mult;u32 shift;u64 xtime_nsec; -ktime_t base_mono; +ktime_t base; };/** * struct timekeeper - Structure holding internal timekeeping values. -* @tkr: The readout base structure +* @tkr_mono: The readout base structure for CLOCK_MONOTONIC * @xtime_sec: Current CLOCK_REALTIME time in seconds * @ktime_sec: Current CLOCK_MONOTONIC time in seconds * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
@@ -76,7 +76,7 @@ struct tk_read_base {* used instead. */ struct timekeeper { -struct tk_read_base tkr; +struct tk_read_base tkr_mono;u64 xtime_sec;unsigned long ktime_sec;struct timespec64 wall_to_monotonic;
kernel/time/timekeeping.c +75 -75
405 lines not on this page · raw message
RFC PATCH 2/4 time: Add timerkeeper::tkr_raw
In reply to Peter ZijlstraIntroduce tkr_raw and make use of it.
base_raw -> tkr_raw.base
clock->{mult,shift} -> tkr_raw.{mult.shift}
Kill timekeeping_get_ns_raw() in favour of timekeeping_get_ns(&tkr_raw), this removes all mono_raw special casing.
Duplicate the updates to tkr_mono.cycle_last into tkr_raw.cycle_last, both need the same value.
--- include/linux/timekeeper_internal.h | 4 +-- kernel/time/timekeeping.c | 41 ++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 24 deletions(-)
include/linux/timekeeper_internal.h +2 -2
@@ -41,6 +41,7 @@ struct tk_read_base {/** * struct timekeeper - Structure holding internal timekeeping values. * @tkr_mono: The readout base structure for CLOCK_MONOTONIC +* @tkr_raw: The readout base structure for CLOCK_MONOTONIC_RAW * @xtime_sec: Current CLOCK_REALTIME time in seconds * @ktime_sec: Current CLOCK_MONOTONIC time in seconds * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
@@ -48,7 +49,6 @@ struct tk_read_base {* @offs_boot: Offset clock monotonic -> clock boottime * @offs_tai: Offset clock monotonic -> clock tai * @tai_offset: The current UTC to TAI offset in seconds -* @base_raw: Monotonic raw base time in ktime_t format * @raw_time: Monotonic raw base time in timespec64 format * @cycle_interval: Number of clock cycles in one NTP interval * @xtime_interval: Number of clock shifted nano seconds in one NTP
@@ -77,6 +77,7 @@ struct tk_read_base {*/ struct timekeeper {struct tk_read_base tkr_mono; +struct tk_read_base tkr_raw;u64 xtime_sec;unsigned long ktime_sec;struct timespec64 wall_to_monotonic;
@@ -84,7 +85,6 @@ struct timekeeper {ktime_t offs_boot;ktime_t offs_tai;s32 tai_offset; -ktime_t base_raw;struct timespec64 raw_time;/* The following members are for timekeeping internal use */
kernel/time/timekeeping.c +19 -22
120 lines not on this page · raw message
tip-bot for Peter Zijlstra
merge bot[tip:perf/timer] time: Add timerkeeper::tkr_raw
time: Add timerkeeper::tkr_raw
Commit-ID: 4a4ad80d32cea69ee93bd4589f24dc478804cd80 Gitweb: http://git.kernel.org/tip/4a4ad80d32cea69ee93bd4589f24dc478804cd80 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 19 Mar 2015 09:28:44 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 27 Mar 2015 09:45:07 +0100
time: Add timerkeeper::tkr_raw
Introduce tkr_raw and make use of it.
base_raw -> tkr_raw.base
clock->{mult,shift} -> tkr_raw.{mult.shift}
Kill timekeeping_get_ns_raw() in favour of timekeeping_get_ns(&tkr_raw), this removes all mono_raw special casing.
Duplicate the updates to tkr_mono.cycle_last into tkr_raw.cycle_last, both need the same value.
--- include/linux/timekeeper_internal.h | 4 ++-- kernel/time/timekeeping.c | 41 +++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 24 deletions(-)
include/linux/timekeeper_internal.h +2 -2
@@ -41,6 +41,7 @@ struct tk_read_base {/** * struct timekeeper - Structure holding internal timekeeping values. * @tkr_mono: The readout base structure for CLOCK_MONOTONIC +* @tkr_raw: The readout base structure for CLOCK_MONOTONIC_RAW * @xtime_sec: Current CLOCK_REALTIME time in seconds * @ktime_sec: Current CLOCK_MONOTONIC time in seconds * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
@@ -48,7 +49,6 @@ struct tk_read_base {* @offs_boot: Offset clock monotonic -> clock boottime * @offs_tai: Offset clock monotonic -> clock tai * @tai_offset: The current UTC to TAI offset in seconds -* @base_raw: Monotonic raw base time in ktime_t format * @raw_time: Monotonic raw base time in timespec64 format * @cycle_interval: Number of clock cycles in one NTP interval * @xtime_interval: Number of clock shifted nano seconds in one NTP
@@ -77,6 +77,7 @@ struct tk_read_base {*/ struct timekeeper {struct tk_read_base tkr_mono; +struct tk_read_base tkr_raw;u64 xtime_sec;unsigned long ktime_sec;struct timespec64 wall_to_monotonic;
@@ -84,7 +85,6 @@ struct timekeeper {ktime_t offs_boot;ktime_t offs_tai;s32 tai_offset; -ktime_t base_raw;struct timespec64 raw_time;/* The following members are for timekeeping internal use */
kernel/time/timekeeping.c +19 -22
120 lines not on this page · raw message
RFC PATCH 3/4 time: Parametrize all tk_fast_mono users
In reply to Peter ZijlstraIn preparation for more tk_fast instances, remove all hard-coded tk_fast_mono references.
--- kernel/time/timekeeping.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
kernel/time/timekeeping.c +15 -10
@@ -364,18 +364,18 @@ static inline s64 timekeeping_get_ns(str* slightly wrong timestamp (a few nanoseconds). See * @ktime_get_mono_fast_ns. */ -static void update_fast_timekeeper (struct tk_read_base *tkr) +static void update_fast_timekeeper (struct tk_read_base *tkr,struct tk_fast *tkf) { -struct tk_read_base *base = tk_fast_mono.base; +struct tk_read_base *base = tkf->base;/* Force readers off to base[1] */ -raw_write_seqcount_latch (&tk_fast_mono.seq); +raw_write_seqcount_latch (&tkf->seq);/* Update base[0] */ memcpy (base, tkr,sizeof (*base));/* Force readers back to base[0] */ -raw_write_seqcount_latch (&tk_fast_mono.seq); +raw_write_seqcount_latch (&tkf->seq);/* Update base[1] */ memcpy (base +1 , base,sizeof (*base));
@@ -413,20 +413,25 @@ static void update_fast_timekeeper(struc* of the following timestamps. Callers need to be aware of that and * deal with it. */ -u64 notrace ktime_get_mono_fast_ns(void) +static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) {struct tk_read_base *tkr;unsigned int seq;u64 now;do { - seq =raw_read_seqcount (&tk_fast_mono.seq); - tkr = tk_fast_mono.base + (seq &0x01 ); + seq =raw_read_seqcount (&tkf->seq); + tkr = tkf->base + (seq &0x01 ); now =ktime_to_ns (tkr->base) +timekeeping_get_ns (tkr); + }while (read_seqcount_retry (&tkf->seq, seq)); - }while (read_seqcount_retry (&tk_fast_mono.seq, seq));return now; } + +u64 ktime_get_mono_fast_ns (void ) +{ +return __ktime_get_fast_ns (&tk_fast_mono); +}EXPORT_SYMBOL_GPL (ktime_get_mono_fast_ns);/* Suspend-time cycles value for halted fast timekeeper. */
@@ -455,7 +460,7 @@ static void halt_fast_timekeeper(structmemcpy (&tkr_dummy, tkr,sizeof (tkr_dummy)); cycles_at_suspend = tkr->read (tkr->clock); tkr_dummy.read = dummy_clock_read; -update_fast_timekeeper (&tkr_dummy); +update_fast_timekeeper (&tkr_dummy, &tk_fast_mono); }#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
@@ -586,7 +591,7 @@ static void timekeeping_update(struct timemcpy (&shadow_timekeeper, &tk_core.timekeeper,sizeof (tk_core.timekeeper)); -update_fast_timekeeper (&tk->tkr_mono); +update_fast_timekeeper (&tk->tkr_mono, &tk_fast_mono); }/**
tip-bot for Peter Zijlstra
merge bot[tip:perf/timer] time: Parametrize all tk_fast_mono users
time: Parametrize all tk_fast_mono users
Commit-ID: 4498e7467e9e441c18ca12f1ca08460356e0508a Gitweb: http://git.kernel.org/tip/4498e7467e9e441c18ca12f1ca08460356e0508a Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 19 Mar 2015 09:36:19 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 27 Mar 2015 09:45:08 +0100
time: Parametrize all tk_fast_mono users
In preparation for more tk_fast instances, remove all hard-coded tk_fast_mono references.
--- kernel/time/timekeeping.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
kernel/time/timekeeping.c +15 -10
@@ -364,18 +364,18 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)* slightly wrong timestamp (a few nanoseconds). See * @ktime_get_mono_fast_ns. */ -static void update_fast_timekeeper (struct tk_read_base *tkr) +static void update_fast_timekeeper (struct tk_read_base *tkr,struct tk_fast *tkf) { -struct tk_read_base *base = tk_fast_mono.base; +struct tk_read_base *base = tkf->base;/* Force readers off to base[1] */ -raw_write_seqcount_latch (&tk_fast_mono.seq); +raw_write_seqcount_latch (&tkf->seq);/* Update base[0] */ memcpy (base, tkr,sizeof (*base));/* Force readers back to base[0] */ -raw_write_seqcount_latch (&tk_fast_mono.seq); +raw_write_seqcount_latch (&tkf->seq);/* Update base[1] */ memcpy (base +1 , base,sizeof (*base));
@@ -413,20 +413,25 @@ static void update_fast_timekeeper(struct tk_read_base *tkr)* of the following timestamps. Callers need to be aware of that and * deal with it. */ -u64 notrace ktime_get_mono_fast_ns(void) +static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) {struct tk_read_base *tkr;unsigned int seq;u64 now;do { - seq =raw_read_seqcount (&tk_fast_mono.seq); - tkr = tk_fast_mono.base + (seq &0x01 ); + seq =raw_read_seqcount (&tkf->seq); + tkr = tkf->base + (seq &0x01 ); now =ktime_to_ns (tkr->base) +timekeeping_get_ns (tkr); + }while (read_seqcount_retry (&tkf->seq, seq)); - }while (read_seqcount_retry (&tk_fast_mono.seq, seq));return now; } + +u64 ktime_get_mono_fast_ns (void ) +{ +return __ktime_get_fast_ns (&tk_fast_mono); +}EXPORT_SYMBOL_GPL (ktime_get_mono_fast_ns);/* Suspend-time cycles value for halted fast timekeeper. */
@@ -455,7 +460,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk)memcpy (&tkr_dummy, tkr,sizeof (tkr_dummy)); cycles_at_suspend = tkr->read (tkr->clock); tkr_dummy.read = dummy_clock_read; -update_fast_timekeeper (&tkr_dummy); +update_fast_timekeeper (&tkr_dummy, &tk_fast_mono); }#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
@@ -586,7 +591,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)memcpy (&shadow_timekeeper, &tk_core.timekeeper,sizeof (tk_core.timekeeper)); -update_fast_timekeeper (&tk->tkr_mono); +update_fast_timekeeper (&tk->tkr_mono, &tk_fast_mono); }/**
RFC PATCH 4/4 time: Introduce tk_fast_raw
In reply to Peter ZijlstraAdd the NMI safe CLOCK_MONOTONIC_RAW accessor..
--- kernel/time/timekeeping.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
kernel/time/timekeeping.c +13 -0
@@ -59,6 +59,7 @@ struct tk_fast { };static struct tk_fast tk_fast_mono____cacheline_aligned ; +static struct tk_fast tk_fast_raw____cacheline_aligned ;/* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended;
@@ -434,6 +435,12 @@ u64 ktime_get_mono_fast_ns(void) }EXPORT_SYMBOL_GPL (ktime_get_mono_fast_ns); +u64 ktime_get_raw_fast_ns (void ) +{ +return __ktime_get_fast_ns (&tk_fast_raw); +} +EXPORT_SYMBOL_GPL (ktime_get_raw_fast_ns); +/* Suspend-time cycles value for halted fast timekeeper. */ static cycle_t cycles_at_suspend;
@@ -461,6 +468,11 @@ static void halt_fast_timekeeper(struct cycles_at_suspend = tkr->read (tkr->clock); tkr_dummy.read = dummy_clock_read;update_fast_timekeeper (&tkr_dummy, &tk_fast_mono); + + tkr = &tk->tkr_raw; +memcpy (&tkr_dummy, tkr,sizeof (tkr_dummy)); + tkr_dummy.read = dummy_clock_read; +update_fast_timekeeper (&tkr_dummy, &tk_fast_raw); }#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
@@ -592,6 +604,7 @@ static void timekeeping_update(struct ti sizeof(tk_core.timekeeper));update_fast_timekeeper (&tk->tkr_mono, &tk_fast_mono); +update_fast_timekeeper (&tk->tkr_raw, &tk_fast_raw); }/**
tip-bot for Peter Zijlstra
merge bot[tip:perf/timer] time: Introduce tk_fast_raw
time: Introduce tk_fast_raw
Commit-ID: f09cb9a1808e35ad7502ea39b6bfb443c7fa0f19 Gitweb: http://git.kernel.org/tip/f09cb9a1808e35ad7502ea39b6bfb443c7fa0f19 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 19 Mar 2015 09:39:08 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 27 Mar 2015 09:45:09 +0100
time: Introduce tk_fast_raw
Add the NMI safe CLOCK_MONOTONIC_RAW accessor..
--- include/linux/timekeeping.h | 1 + kernel/time/timekeeping.c | 13 +++++++++++++ 2 files changed, 14 insertions(+)
include/linux/timekeeping.h +1 -0
@@ -220,6 +220,7 @@ static inline u64 ktime_get_raw_ns(void) }extern u64 ktime_get_mono_fast_ns (void ); +extern u64 ktime_get_raw_fast_ns (void );/* * Timespec interfaces utilizing the ktime based ones
kernel/time/timekeeping.c +13 -0
@@ -59,6 +59,7 @@ struct tk_fast { };static struct tk_fast tk_fast_mono____cacheline_aligned ; +static struct tk_fast tk_fast_raw____cacheline_aligned ;/* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended;
@@ -434,6 +435,12 @@ u64 ktime_get_mono_fast_ns(void) }EXPORT_SYMBOL_GPL (ktime_get_mono_fast_ns); +u64 ktime_get_raw_fast_ns (void ) +{ +return __ktime_get_fast_ns (&tk_fast_raw); +} +EXPORT_SYMBOL_GPL (ktime_get_raw_fast_ns); +/* Suspend-time cycles value for halted fast timekeeper. */ static cycle_t cycles_at_suspend;
@@ -461,6 +468,11 @@ static void halt_fast_timekeeper(struct timekeeper *tk) cycles_at_suspend = tkr->read (tkr->clock); tkr_dummy.read = dummy_clock_read;update_fast_timekeeper (&tkr_dummy, &tk_fast_mono); + + tkr = &tk->tkr_raw; +memcpy (&tkr_dummy, tkr,sizeof (tkr_dummy)); + tkr_dummy.read = dummy_clock_read; +update_fast_timekeeper (&tkr_dummy, &tk_fast_raw); }#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
@@ -592,6 +604,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) sizeof(tk_core.timekeeper));update_fast_timekeeper (&tk->tkr_mono, &tk_fast_mono); +update_fast_timekeeper (&tk->tkr_raw, &tk_fast_raw); }/**
Quoted 3 lines · Peter Zijlstra
Hi John,
So yeah, I just didn't try hard enough it seems; how about this?
Yea, this looks much better! I'll queue it up for testing and if that goes well include it for 4.1.
Quoted 6 lines
Also, I think we should double check that everything passed to
tk_setup_internals(.clock)is either static storage or RCU-sched freed, because with the whole latch thing one CPUs (fast) access might still be in progress while the other is freeing the clock struct.Not sure what the lifetime rules of struct clocksource are here.
At one point it was install and never remove, but I think Thomas changed that awhile back, so I think your concern here is a good one.
thanks
-john
Quoted 7 lines · John Stultz
Quoted 3 lines · Peter Zijlstra
Hi John,
So yeah, I just didn't try hard enough it seems; how about this?
Yea, this looks much better! I'll queue it up for testing and if that goes well include it for 4.1.
I have a few patches that depend on it, so if you're ok with it I'd like to carry the lot. But yes please test ;-)
Quoted 9 lines
Quoted 6 lines
Also, I think we should double check that everything passed to
tk_setup_internals(.clock)is either static storage or RCU-sched freed, because with the whole latch thing one CPUs (fast) access might still be in progress while the other is freeing the clock struct.Not sure what the lifetime rules of struct clocksource are here.
At one point it was install and never remove, but I think Thomas changed that awhile back, so I think your concern here is a good one.
OK, I'll try and dig around a bit on this.
Quoted 11 lines · Peter Zijlstra
Quoted 7 lines · John Stultz
Quoted 3 lines · Peter Zijlstra
Hi John,
So yeah, I just didn't try hard enough it seems; how about this?
Yea, this looks much better! I'll queue it up for testing and if that goes well include it for 4.1.
I have a few patches that depend on it, so if you're ok with it I'd like to carry the lot. But yes please test ;-)
Sure thing. It collides with some minor changes Ingo requested from me, but I'll rework my stuff ontop of yours (so if you can push this set to tip/timers/core, I'd appreciate it).
I'll let you know when the tests finish.
thanks
-john
Quoted 10 lines · John Stultz
Quoted 9 lines · Peter Zijlstra
Quoted 7 lines · John Stultz
Quoted 3 lines · Peter Zijlstra
Hi John,
So yeah, I just didn't try hard enough it seems; how about this?
Yea, this looks much better! I'll queue it up for testing and if that goes well include it for 4.1.
Quoted 8 lines
Quoted 2 lines
I have a few patches that depend on it, so if you're ok with it I'd like to carry the lot. But yes please test ;-)
Sure thing. It collides with some minor changes Ingo requested from me, but I'll rework my stuff ontop of yours (so if you can push this set to tip/timers/core, I'd appreciate it).
I'll let you know when the tests finish.
Just fyi, didn't see any issues w/ x86_64, i386 and arm. Looks good.
thanks
-john
Peter Zijlstra
Acked-by John StultzQuoted 5 lines · John Stultz
Quoted 2 lines · John Stultz
Quoted 2 lines
Quoted 2 lines
Yea, this looks much better! I'll queue it up for testing and if that goes well include it for 4.1.
Just fyi, didn't see any issues w/
x86_64, i386 and arm. Looks good.
I've taken these to mean:
If not, please holler.