Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab932c97 authored by John Stultz's avatar John Stultz Committed by Mark Salyzyn
Browse files

BACKPORT: time: Clean up CLOCK_MONOTONIC_RAW time handling



(cherry pick from commit fc6eead7c1e2e5376c25d2795d4539fdacbc0648)

Now that we fixed the sub-ns handling for CLOCK_MONOTONIC_RAW,
remove the duplicitive tk->raw_time.tv_nsec, which can be
stored in tk->tkr_raw.xtime_nsec (similarly to how its handled
for monotonic time).

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Daniel Mentz <danielmentz@google.com>
Tested-by: default avatarDaniel Mentz <danielmentz@google.com>
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Bug: 20045882
Bug: 63737556
Change-Id: I243827d21b08703a09d2d2fe738a9258be224582
parent c8c539ce
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -215,8 +215,8 @@ void update_vsyscall(struct timekeeper *tk)
	if (!use_syscall) {
		/* tkr_mono.cycle_last == tkr_raw.cycle_last */
		vdso_data->cs_cycle_last	= tk->tkr_mono.cycle_last;
		vdso_data->raw_time_sec		= tk->raw_time.tv_sec;
		vdso_data->raw_time_nsec	= tk->raw_time.tv_nsec;
		vdso_data->raw_time_sec		= tk->raw_sec;
		vdso_data->raw_time_nsec	= tk->tkr_raw.xtime_nsec;
		vdso_data->xtime_clock_sec	= tk->xtime_sec;
		vdso_data->xtime_clock_nsec	= tk->tkr_mono.xtime_nsec;
		/* tkr_raw.xtime_nsec == 0 */
+2 −2
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ 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
 * @raw_time:		Monotonic raw base time in timespec64 format
 * @raw_sec:		CLOCK_MONOTONIC_RAW  time in seconds
 * @cycle_interval:	Number of clock cycles in one NTP interval
 * @xtime_interval:	Number of clock shifted nano seconds in one NTP
 *			interval.
@@ -83,7 +83,7 @@ struct timekeeper {
	ktime_t			offs_boot;
	ktime_t			offs_tai;
	s32			tai_offset;
	struct timespec64	raw_time;
	u64			raw_sec;

	/* The following members are for timekeeping internal use */
	cycle_t			cycle_interval;
+23 −15
Original line number Diff line number Diff line
@@ -72,6 +72,10 @@ static inline void tk_normalize_xtime(struct timekeeper *tk)
		tk->tkr_mono.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_mono.shift;
		tk->xtime_sec++;
	}
	while (tk->tkr_raw.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_raw.shift)) {
		tk->tkr_raw.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
		tk->raw_sec++;
	}
}

static inline struct timespec64 tk_xtime(struct timekeeper *tk)
@@ -166,12 +170,14 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
	 /* if changing clocks, convert xtime_nsec shift units */
	if (old_clock) {
		int shift_change = clock->shift - old_clock->shift;
		if (shift_change < 0)
		if (shift_change < 0) {
			tk->tkr_mono.xtime_nsec >>= -shift_change;
		else
			tk->tkr_raw.xtime_nsec >>= -shift_change;
		} else {
			tk->tkr_mono.xtime_nsec <<= shift_change;
			tk->tkr_raw.xtime_nsec <<= shift_change;
		}
	}
	tk->tkr_raw.xtime_nsec = 0;

	tk->tkr_mono.shift = clock->shift;
	tk->tkr_raw.shift = clock->shift;
@@ -405,6 +411,7 @@ EXPORT_SYMBOL_GPL(pvclock_gtod_unregister_notifier);
 */
static inline void tk_update_ktime_data(struct timekeeper *tk)
{
	u64 seconds;
	s64 nsec;

	/*
@@ -420,7 +427,9 @@ static inline void tk_update_ktime_data(struct timekeeper *tk)
	tk->tkr_mono.base = ns_to_ktime(nsec);

	/* Update the monotonic raw base */
	tk->tkr_raw.base = timespec64_to_ktime(tk->raw_time);
	seconds = tk->raw_sec;
	nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift);
	tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);
}

/* must hold timekeeper_lock */
@@ -454,7 +463,6 @@ static void timekeeping_forward_now(struct timekeeper *tk)
{
	struct clocksource *clock = tk->tkr_mono.clock;
	cycle_t cycle_now, delta;
	s64 nsec;

	cycle_now = tk->tkr_mono.read(clock);
	delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
@@ -466,10 +474,13 @@ static void timekeeping_forward_now(struct timekeeper *tk)
	/* If arch requires, add in get_arch_timeoffset() */
	tk->tkr_mono.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_mono.shift;

	tk_normalize_xtime(tk);

	nsec = clocksource_cyc2ns(delta, tk->tkr_raw.mult, tk->tkr_raw.shift);
	timespec64_add_ns(&tk->raw_time, nsec);
	tk->tkr_raw.xtime_nsec += delta * tk->tkr_raw.mult;

	/* If arch requires, add in get_arch_timeoffset() */
	tk->tkr_raw.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_raw.shift;

	tk_normalize_xtime(tk);
}

/**
@@ -898,11 +909,12 @@ void getrawmonotonic(struct timespec *ts)

	do {
		seq = read_seqcount_begin(&tk_core.seq);
		ts64.tv_sec = tk->raw_sec;
		nsecs = timekeeping_get_ns(&tk->tkr_raw);
		ts64 = tk->raw_time;

	} while (read_seqcount_retry(&tk_core.seq, seq));

	ts64.tv_nsec = 0;
	timespec64_add_ns(&ts64, nsecs);
	*ts = timespec64_to_timespec(ts64);
}
@@ -1016,8 +1028,7 @@ void __init timekeeping_init(void)
	tk_setup_internals(tk, clock);

	tk_set_xtime(tk, &now);
	tk->raw_time.tv_sec = 0;
	tk->raw_time.tv_nsec = 0;
	tk->raw_sec = 0;
	if (boot.tv_sec == 0 && boot.tv_nsec == 0)
		boot = tk_xtime(tk);

@@ -1484,15 +1495,12 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset,
	*clock_set |= accumulate_nsecs_to_secs(tk);

	/* Accumulate raw time */
	tk->tkr_raw.xtime_nsec += (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
	tk->tkr_raw.xtime_nsec += tk->raw_interval << shift;
	snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
	while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) {
		tk->tkr_raw.xtime_nsec -= snsec_per_sec;
		tk->raw_time.tv_sec++;
		tk->raw_sec++;
	}
	tk->raw_time.tv_nsec = tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift;
	tk->tkr_raw.xtime_nsec -= (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;

	/* Accumulate error between NTP and clock interval */
	tk->ntp_error += tk->ntp_tick << shift;