diff options
Diffstat (limited to 'kernel/time.c')
-rw-r--r-- | kernel/time.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/kernel/time.c b/kernel/time.c index 86729042e4cd..343e2515375a 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/security.h> | 36 | #include <linux/security.h> |
37 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/math64.h> | ||
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | #include <asm/unistd.h> | 42 | #include <asm/unistd.h> |
@@ -587,9 +588,7 @@ clock_t jiffies_to_clock_t(long x) | |||
587 | return x / (HZ / USER_HZ); | 588 | return x / (HZ / USER_HZ); |
588 | # endif | 589 | # endif |
589 | #else | 590 | #else |
590 | u64 tmp = (u64)x * TICK_NSEC; | 591 | return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ); |
591 | do_div(tmp, (NSEC_PER_SEC / USER_HZ)); | ||
592 | return (long)tmp; | ||
593 | #endif | 592 | #endif |
594 | } | 593 | } |
595 | EXPORT_SYMBOL(jiffies_to_clock_t); | 594 | EXPORT_SYMBOL(jiffies_to_clock_t); |
@@ -601,16 +600,12 @@ unsigned long clock_t_to_jiffies(unsigned long x) | |||
601 | return ~0UL; | 600 | return ~0UL; |
602 | return x * (HZ / USER_HZ); | 601 | return x * (HZ / USER_HZ); |
603 | #else | 602 | #else |
604 | u64 jif; | ||
605 | |||
606 | /* Don't worry about loss of precision here .. */ | 603 | /* Don't worry about loss of precision here .. */ |
607 | if (x >= ~0UL / HZ * USER_HZ) | 604 | if (x >= ~0UL / HZ * USER_HZ) |
608 | return ~0UL; | 605 | return ~0UL; |
609 | 606 | ||
610 | /* .. but do try to contain it here */ | 607 | /* .. but do try to contain it here */ |
611 | jif = x * (u64) HZ; | 608 | return div_u64((u64)x * HZ, USER_HZ); |
612 | do_div(jif, USER_HZ); | ||
613 | return jif; | ||
614 | #endif | 609 | #endif |
615 | } | 610 | } |
616 | EXPORT_SYMBOL(clock_t_to_jiffies); | 611 | EXPORT_SYMBOL(clock_t_to_jiffies); |
@@ -619,10 +614,9 @@ u64 jiffies_64_to_clock_t(u64 x) | |||
619 | { | 614 | { |
620 | #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 | 615 | #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 |
621 | # if HZ < USER_HZ | 616 | # if HZ < USER_HZ |
622 | x *= USER_HZ; | 617 | x = div_u64(x * USER_HZ, HZ); |
623 | do_div(x, HZ); | ||
624 | # elif HZ > USER_HZ | 618 | # elif HZ > USER_HZ |
625 | do_div(x, HZ / USER_HZ); | 619 | x = div_u64(x, HZ / USER_HZ); |
626 | # else | 620 | # else |
627 | /* Nothing to do */ | 621 | /* Nothing to do */ |
628 | # endif | 622 | # endif |
@@ -632,8 +626,7 @@ u64 jiffies_64_to_clock_t(u64 x) | |||
632 | * but even this doesn't overflow in hundreds of years | 626 | * but even this doesn't overflow in hundreds of years |
633 | * in 64 bits, so.. | 627 | * in 64 bits, so.. |
634 | */ | 628 | */ |
635 | x *= TICK_NSEC; | 629 | x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ)); |
636 | do_div(x, (NSEC_PER_SEC / USER_HZ)); | ||
637 | #endif | 630 | #endif |
638 | return x; | 631 | return x; |
639 | } | 632 | } |
@@ -642,21 +635,17 @@ EXPORT_SYMBOL(jiffies_64_to_clock_t); | |||
642 | u64 nsec_to_clock_t(u64 x) | 635 | u64 nsec_to_clock_t(u64 x) |
643 | { | 636 | { |
644 | #if (NSEC_PER_SEC % USER_HZ) == 0 | 637 | #if (NSEC_PER_SEC % USER_HZ) == 0 |
645 | do_div(x, (NSEC_PER_SEC / USER_HZ)); | 638 | return div_u64(x, NSEC_PER_SEC / USER_HZ); |
646 | #elif (USER_HZ % 512) == 0 | 639 | #elif (USER_HZ % 512) == 0 |
647 | x *= USER_HZ/512; | 640 | return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512); |
648 | do_div(x, (NSEC_PER_SEC / 512)); | ||
649 | #else | 641 | #else |
650 | /* | 642 | /* |
651 | * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024, | 643 | * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024, |
652 | * overflow after 64.99 years. | 644 | * overflow after 64.99 years. |
653 | * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ... | 645 | * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ... |
654 | */ | 646 | */ |
655 | x *= 9; | 647 | return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ); |
656 | do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2)) / | ||
657 | USER_HZ)); | ||
658 | #endif | 648 | #endif |
659 | return x; | ||
660 | } | 649 | } |
661 | 650 | ||
662 | #if (BITS_PER_LONG < 64) | 651 | #if (BITS_PER_LONG < 64) |