Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

time: Introduce timespec64_to_jiffies()/jiffies_to_timespec64()

The conversion between struct timespec and jiffies is not year 2038
safe on 32bit systems. Introduce timespec64_to_jiffies() and
jiffies_to_timespec64() functions which use struct timespec64 to
make it ready for 2038 issue.

Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>

authored by

Baolin Wang and committed by
John Stultz
9ca30850 8758a240

+32 -11
+19 -3
include/linux/jiffies.h
··· 416 416 } 417 417 } 418 418 419 - extern unsigned long timespec_to_jiffies(const struct timespec *value); 420 - extern void jiffies_to_timespec(const unsigned long jiffies, 421 - struct timespec *value); 419 + extern unsigned long timespec64_to_jiffies(const struct timespec64 *value); 420 + extern void jiffies_to_timespec64(const unsigned long jiffies, 421 + struct timespec64 *value); 422 + static inline unsigned long timespec_to_jiffies(const struct timespec *value) 423 + { 424 + struct timespec64 ts = timespec_to_timespec64(*value); 425 + 426 + return timespec64_to_jiffies(&ts); 427 + } 428 + 429 + static inline void jiffies_to_timespec(const unsigned long jiffies, 430 + struct timespec *value) 431 + { 432 + struct timespec64 ts; 433 + 434 + jiffies_to_timespec64(jiffies, &ts); 435 + *value = timespec64_to_timespec(ts); 436 + } 437 + 422 438 extern unsigned long timeval_to_jiffies(const struct timeval *value); 423 439 extern void jiffies_to_timeval(const unsigned long jiffies, 424 440 struct timeval *value);
+13 -8
kernel/time/time.c
··· 540 540 * value to a scaled second value. 541 541 */ 542 542 static unsigned long 543 - __timespec_to_jiffies(unsigned long sec, long nsec) 543 + __timespec64_to_jiffies(u64 sec, long nsec) 544 544 { 545 545 nsec = nsec + TICK_NSEC - 1; 546 546 ··· 548 548 sec = MAX_SEC_IN_JIFFIES; 549 549 nsec = 0; 550 550 } 551 - return (((u64)sec * SEC_CONVERSION) + 551 + return ((sec * SEC_CONVERSION) + 552 552 (((u64)nsec * NSEC_CONVERSION) >> 553 553 (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC; 554 554 555 555 } 556 556 557 - unsigned long 558 - timespec_to_jiffies(const struct timespec *value) 557 + static unsigned long 558 + __timespec_to_jiffies(unsigned long sec, long nsec) 559 559 { 560 - return __timespec_to_jiffies(value->tv_sec, value->tv_nsec); 560 + return __timespec64_to_jiffies((u64)sec, nsec); 561 561 } 562 562 563 - EXPORT_SYMBOL(timespec_to_jiffies); 563 + unsigned long 564 + timespec64_to_jiffies(const struct timespec64 *value) 565 + { 566 + return __timespec64_to_jiffies(value->tv_sec, value->tv_nsec); 567 + } 568 + EXPORT_SYMBOL(timespec64_to_jiffies); 564 569 565 570 void 566 - jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) 571 + jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value) 567 572 { 568 573 /* 569 574 * Convert jiffies to nanoseconds and separate with ··· 579 574 NSEC_PER_SEC, &rem); 580 575 value->tv_nsec = rem; 581 576 } 582 - EXPORT_SYMBOL(jiffies_to_timespec); 577 + EXPORT_SYMBOL(jiffies_to_timespec64); 583 578 584 579 /* 585 580 * We could use a similar algorithm to timespec_to_jiffies (with a