Loading include/linux/jiffies.h +19 −3 Original line number Diff line number Diff line Loading @@ -416,9 +416,25 @@ static inline unsigned long usecs_to_jiffies(const unsigned int u) } } extern unsigned long timespec_to_jiffies(const struct timespec *value); extern void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value); extern unsigned long timespec64_to_jiffies(const struct timespec64 *value); extern void jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value); static inline unsigned long timespec_to_jiffies(const struct timespec *value) { struct timespec64 ts = timespec_to_timespec64(*value); return timespec64_to_jiffies(&ts); } static inline void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) { struct timespec64 ts; jiffies_to_timespec64(jiffies, &ts); *value = timespec64_to_timespec(ts); } extern unsigned long timeval_to_jiffies(const struct timeval *value); extern void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value); Loading include/linux/time64.h +35 −0 Original line number Diff line number Diff line Loading @@ -12,11 +12,18 @@ typedef __s64 time64_t; */ #if __BITS_PER_LONG == 64 # define timespec64 timespec #define itimerspec64 itimerspec #else struct timespec64 { time64_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; struct itimerspec64 { struct timespec64 it_interval; struct timespec64 it_value; }; #endif /* Parameters used to convert the timespec values: */ Loading Loading @@ -45,6 +52,16 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ts; } static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64) { return *its64; } static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its) { return *its; } # define timespec64_equal timespec_equal # define timespec64_compare timespec_compare # define set_normalized_timespec64 set_normalized_timespec Loading Loading @@ -77,6 +94,24 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ret; } static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64) { struct itimerspec ret; ret.it_interval = timespec64_to_timespec(its64->it_interval); ret.it_value = timespec64_to_timespec(its64->it_value); return ret; } static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its) { struct itimerspec64 ret; ret.it_interval = timespec_to_timespec64(its->it_interval); ret.it_value = timespec_to_timespec64(its->it_value); return ret; } static inline int timespec64_equal(const struct timespec64 *a, const struct timespec64 *b) { Loading include/linux/timekeeping.h +8 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,17 @@ extern int do_sys_settimeofday(const struct timespec *tv, * Kernel time accessors */ unsigned long get_seconds(void); struct timespec current_kernel_time(void); struct timespec64 current_kernel_time64(void); /* does not take xtime_lock */ struct timespec __current_kernel_time(void); static inline struct timespec current_kernel_time(void) { struct timespec64 now = current_kernel_time64(); return timespec64_to_timespec(now); } /* * timespec based interfaces */ Loading kernel/time/ntp.c +5 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,11 @@ int second_overflow(unsigned long secs) } #ifdef CONFIG_GENERIC_CMOS_UPDATE int __weak update_persistent_clock(struct timespec now) { return -ENODEV; } int __weak update_persistent_clock64(struct timespec64 now64) { struct timespec now; Loading kernel/time/time.c +21 −22 Original line number Diff line number Diff line Loading @@ -287,26 +287,20 @@ EXPORT_SYMBOL(jiffies_to_usecs); * @t: Timespec * @gran: Granularity in ns. * * Truncate a timespec to a granularity. gran must be smaller than a second. * Always rounds down. * * This function should be only used for timestamps returned by * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because * it doesn't handle the better resolution of the latter. * Truncate a timespec to a granularity. Always rounds down. gran must * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns). */ struct timespec timespec_trunc(struct timespec t, unsigned gran) { /* * Division is pretty slow so avoid it for common cases. * Currently current_kernel_time() never returns better than * jiffies resolution. Exploit that. */ if (gran <= jiffies_to_usecs(1) * 1000) { /* Avoid division in the common cases 1 ns and 1 s. */ if (gran == 1) { /* nothing */ } else if (gran == 1000000000) { } else if (gran == NSEC_PER_SEC) { t.tv_nsec = 0; } else { } else if (gran > 1 && gran < NSEC_PER_SEC) { t.tv_nsec -= t.tv_nsec % gran; } else { WARN(1, "illegal file time granularity: %u", gran); } return t; } Loading Loading @@ -546,7 +540,7 @@ EXPORT_SYMBOL(__usecs_to_jiffies); * value to a scaled second value. */ static unsigned long __timespec_to_jiffies(unsigned long sec, long nsec) __timespec64_to_jiffies(u64 sec, long nsec) { nsec = nsec + TICK_NSEC - 1; Loading @@ -554,22 +548,27 @@ __timespec_to_jiffies(unsigned long sec, long nsec) sec = MAX_SEC_IN_JIFFIES; nsec = 0; } return (((u64)sec * SEC_CONVERSION) + return ((sec * SEC_CONVERSION) + (((u64)nsec * NSEC_CONVERSION) >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; } unsigned long timespec_to_jiffies(const struct timespec *value) static unsigned long __timespec_to_jiffies(unsigned long sec, long nsec) { return __timespec_to_jiffies(value->tv_sec, value->tv_nsec); return __timespec64_to_jiffies((u64)sec, nsec); } EXPORT_SYMBOL(timespec_to_jiffies); unsigned long timespec64_to_jiffies(const struct timespec64 *value) { return __timespec64_to_jiffies(value->tv_sec, value->tv_nsec); } EXPORT_SYMBOL(timespec64_to_jiffies); void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) { /* * Convert jiffies to nanoseconds and separate with Loading @@ -580,7 +579,7 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) NSEC_PER_SEC, &rem); value->tv_nsec = rem; } EXPORT_SYMBOL(jiffies_to_timespec); EXPORT_SYMBOL(jiffies_to_timespec64); /* * We could use a similar algorithm to timespec_to_jiffies (with a Loading Loading
include/linux/jiffies.h +19 −3 Original line number Diff line number Diff line Loading @@ -416,9 +416,25 @@ static inline unsigned long usecs_to_jiffies(const unsigned int u) } } extern unsigned long timespec_to_jiffies(const struct timespec *value); extern void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value); extern unsigned long timespec64_to_jiffies(const struct timespec64 *value); extern void jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value); static inline unsigned long timespec_to_jiffies(const struct timespec *value) { struct timespec64 ts = timespec_to_timespec64(*value); return timespec64_to_jiffies(&ts); } static inline void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) { struct timespec64 ts; jiffies_to_timespec64(jiffies, &ts); *value = timespec64_to_timespec(ts); } extern unsigned long timeval_to_jiffies(const struct timeval *value); extern void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value); Loading
include/linux/time64.h +35 −0 Original line number Diff line number Diff line Loading @@ -12,11 +12,18 @@ typedef __s64 time64_t; */ #if __BITS_PER_LONG == 64 # define timespec64 timespec #define itimerspec64 itimerspec #else struct timespec64 { time64_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; struct itimerspec64 { struct timespec64 it_interval; struct timespec64 it_value; }; #endif /* Parameters used to convert the timespec values: */ Loading Loading @@ -45,6 +52,16 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ts; } static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64) { return *its64; } static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its) { return *its; } # define timespec64_equal timespec_equal # define timespec64_compare timespec_compare # define set_normalized_timespec64 set_normalized_timespec Loading Loading @@ -77,6 +94,24 @@ static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) return ret; } static inline struct itimerspec itimerspec64_to_itimerspec(struct itimerspec64 *its64) { struct itimerspec ret; ret.it_interval = timespec64_to_timespec(its64->it_interval); ret.it_value = timespec64_to_timespec(its64->it_value); return ret; } static inline struct itimerspec64 itimerspec_to_itimerspec64(struct itimerspec *its) { struct itimerspec64 ret; ret.it_interval = timespec_to_timespec64(its->it_interval); ret.it_value = timespec_to_timespec64(its->it_value); return ret; } static inline int timespec64_equal(const struct timespec64 *a, const struct timespec64 *b) { Loading
include/linux/timekeeping.h +8 −1 Original line number Diff line number Diff line Loading @@ -18,10 +18,17 @@ extern int do_sys_settimeofday(const struct timespec *tv, * Kernel time accessors */ unsigned long get_seconds(void); struct timespec current_kernel_time(void); struct timespec64 current_kernel_time64(void); /* does not take xtime_lock */ struct timespec __current_kernel_time(void); static inline struct timespec current_kernel_time(void) { struct timespec64 now = current_kernel_time64(); return timespec64_to_timespec(now); } /* * timespec based interfaces */ Loading
kernel/time/ntp.c +5 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,11 @@ int second_overflow(unsigned long secs) } #ifdef CONFIG_GENERIC_CMOS_UPDATE int __weak update_persistent_clock(struct timespec now) { return -ENODEV; } int __weak update_persistent_clock64(struct timespec64 now64) { struct timespec now; Loading
kernel/time/time.c +21 −22 Original line number Diff line number Diff line Loading @@ -287,26 +287,20 @@ EXPORT_SYMBOL(jiffies_to_usecs); * @t: Timespec * @gran: Granularity in ns. * * Truncate a timespec to a granularity. gran must be smaller than a second. * Always rounds down. * * This function should be only used for timestamps returned by * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because * it doesn't handle the better resolution of the latter. * Truncate a timespec to a granularity. Always rounds down. gran must * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns). */ struct timespec timespec_trunc(struct timespec t, unsigned gran) { /* * Division is pretty slow so avoid it for common cases. * Currently current_kernel_time() never returns better than * jiffies resolution. Exploit that. */ if (gran <= jiffies_to_usecs(1) * 1000) { /* Avoid division in the common cases 1 ns and 1 s. */ if (gran == 1) { /* nothing */ } else if (gran == 1000000000) { } else if (gran == NSEC_PER_SEC) { t.tv_nsec = 0; } else { } else if (gran > 1 && gran < NSEC_PER_SEC) { t.tv_nsec -= t.tv_nsec % gran; } else { WARN(1, "illegal file time granularity: %u", gran); } return t; } Loading Loading @@ -546,7 +540,7 @@ EXPORT_SYMBOL(__usecs_to_jiffies); * value to a scaled second value. */ static unsigned long __timespec_to_jiffies(unsigned long sec, long nsec) __timespec64_to_jiffies(u64 sec, long nsec) { nsec = nsec + TICK_NSEC - 1; Loading @@ -554,22 +548,27 @@ __timespec_to_jiffies(unsigned long sec, long nsec) sec = MAX_SEC_IN_JIFFIES; nsec = 0; } return (((u64)sec * SEC_CONVERSION) + return ((sec * SEC_CONVERSION) + (((u64)nsec * NSEC_CONVERSION) >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; } unsigned long timespec_to_jiffies(const struct timespec *value) static unsigned long __timespec_to_jiffies(unsigned long sec, long nsec) { return __timespec_to_jiffies(value->tv_sec, value->tv_nsec); return __timespec64_to_jiffies((u64)sec, nsec); } EXPORT_SYMBOL(timespec_to_jiffies); unsigned long timespec64_to_jiffies(const struct timespec64 *value) { return __timespec64_to_jiffies(value->tv_sec, value->tv_nsec); } EXPORT_SYMBOL(timespec64_to_jiffies); void jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) { /* * Convert jiffies to nanoseconds and separate with Loading @@ -580,7 +579,7 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) NSEC_PER_SEC, &rem); value->tv_nsec = rem; } EXPORT_SYMBOL(jiffies_to_timespec); EXPORT_SYMBOL(jiffies_to_timespec64); /* * We could use a similar algorithm to timespec_to_jiffies (with a Loading