[PATCH v5] timekeeping: Added a function to return tv_sec portion of ktime_get_ts64()

Heena Sirwani
2014-10-25T20:00:38Z

The following patch adds a function to return tv_sec portion of
ktime_get_ts64() function in order to have a function that returns
seconds as 64-bit integers instead of 32-bit integers to address the
y2038 problem.

Since we are interested only in the seconds portion of ktime_get_ts64()
and require this to be as fast as possible, we take the implementation
of ktime_get_ts64() as it is and remove everything pertaining to the
nanoseconds portion. We only add to the seconds calculation if the
calculation of nanoseconds is more than one billion nanoseconds. We
replace timekeeping_get_ns() which returns the exact nanoseconds value
with tk_xtime() that returns nanosecond value of the last timer tick
since we do not require such fine resolution for nanoseconds portion but
want the seconds to be returned as fast as possible.

Signed-off-by: Heena Sirwani <heenasirwani@gmail.com>
---
Changes in v5:
- Made the commit message more clear.
- Changed the type of variable ts from timespec64 to time64_t as
we do not use the tv_nsec portion.
- Changed the type of nsec from s64 to s32.
- replaced the value 1000000000 with NSEC_PER_SEC.

include/linux/timekeeping.h | 1 +
kernel/time/timekeeping.c | 25 +++++++++++++++++++++++++
2 files changed, 26 insertions(+)

diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 1caa6b0..115d55e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -28,6 +28,7 @@ struct timespec __current_kernel_time(void);
struct timespec get_monotonic_coarse(void);
extern void getrawmonotonic(struct timespec *ts);
extern void ktime_get_ts64(struct timespec64 *ts);
+extern time64_t ktime_get_seconds(void);

extern int __getnstimeofday64(struct timespec64 *tv);
extern void getnstimeofday64(struct timespec64 *tv);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index ec1791f..93fc596 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -648,6 +648,31 @@ void ktime_get_ts64(struct timespec64 *ts)
}
EXPORT_SYMBOL_GPL(ktime_get_ts64);

+time64_t ktime_get_seconds(void)
+{
+ time64_t ts;
+ struct timekeeper *tk = &tk_core.timekeeper;
+ struct timespec64 tomono;
+ s32 nsec;
+ unsigned int seq;
+
+ WARN_ON(timekeeping_suspended);
+
+ do {
+ seq = read_seqcount_begin(&tk_core.seq);
+ ts = tk->xtime_sec;
+ nsec = (long)(tk->tkr.xtime_nsec >> tk->tkr.shift);
+ tomono = tk->wall_to_monotonic;
+
+ } while (read_seqcount_retry(&tk_core.seq, seq));
+
+ ts += tomono.tv_sec;
+ if (nsec + tomono.tv_nsec >= NSEC_PER_SEC)
+ ts += 1;
+ return ts;
+}
+EXPORT_SYMBOL_GPL(ktime_get_seconds);
+
#ifdef CONFIG_NTP_PPS

/**
--
1.7.9.5