diff options
author | Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> | 2009-11-26 00:49:27 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-26 06:59:20 -0500 |
commit | b7b20df91d43d5e59578b8fc16e895c0c8cbd9b5 (patch) | |
tree | 9ad1a2347264db548a161575080ed3bdc32f6d51 /kernel | |
parent | d5b7c78e975302a1bab28263266c39ecb71acad4 (diff) |
sched, time: Define nsecs_to_jiffies()
Use of msecs_to_jiffies() for nsecs_to_cputime() have some
problems:
- The type of msecs_to_jiffies()'s argument is unsigned int, so
it cannot convert msecs greater than UINT_MAX = about 49.7 days.
- msecs_to_jiffies() returns MAX_JIFFY_OFFSET if MSB of argument
is set, assuming that input was negative value. So it cannot
convert msecs greater than INT_MAX = about 24.8 days too.
This patch defines a new function nsecs_to_jiffies() that can
deal greater values, and that can deal all incoming values as
unsigned.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Spencer Candland <spencer@bluehost.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Amrico Wang <xiyou.wangcong@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <johnstul@linux.vnet.ibm.com>
LKML-Reference: <4B0E16E7.5070307@jp.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched.c | 3 | ||||
-rw-r--r-- | kernel/time.c | 30 |
2 files changed, 31 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 82251c21f785..b3d4e2be95aa 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -5192,8 +5192,7 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
5192 | #else | 5192 | #else |
5193 | 5193 | ||
5194 | #ifndef nsecs_to_cputime | 5194 | #ifndef nsecs_to_cputime |
5195 | # define nsecs_to_cputime(__nsecs) \ | 5195 | # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) |
5196 | msecs_to_cputime(div_u64((__nsecs), NSEC_PER_MSEC)) | ||
5197 | #endif | 5196 | #endif |
5198 | 5197 | ||
5199 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | 5198 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) |
diff --git a/kernel/time.c b/kernel/time.c index 2e2e469a7fec..804798005d19 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -662,6 +662,36 @@ u64 nsec_to_clock_t(u64 x) | |||
662 | #endif | 662 | #endif |
663 | } | 663 | } |
664 | 664 | ||
665 | /** | ||
666 | * nsecs_to_jiffies - Convert nsecs in u64 to jiffies | ||
667 | * | ||
668 | * @n: nsecs in u64 | ||
669 | * | ||
670 | * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64. | ||
671 | * And this doesn't return MAX_JIFFY_OFFSET since this function is designed | ||
672 | * for scheduler, not for use in device drivers to calculate timeout value. | ||
673 | * | ||
674 | * note: | ||
675 | * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512) | ||
676 | * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years | ||
677 | */ | ||
678 | unsigned long nsecs_to_jiffies(u64 n) | ||
679 | { | ||
680 | #if (NSEC_PER_SEC % HZ) == 0 | ||
681 | /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */ | ||
682 | return div_u64(n, NSEC_PER_SEC / HZ); | ||
683 | #elif (HZ % 512) == 0 | ||
684 | /* overflow after 292 years if HZ = 1024 */ | ||
685 | return div_u64(n * HZ / 512, NSEC_PER_SEC / 512); | ||
686 | #else | ||
687 | /* | ||
688 | * Generic case - optimized for cases where HZ is a multiple of 3. | ||
689 | * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc. | ||
690 | */ | ||
691 | return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ); | ||
692 | #endif | ||
693 | } | ||
694 | |||
665 | #if (BITS_PER_LONG < 64) | 695 | #if (BITS_PER_LONG < 64) |
666 | u64 get_jiffies_64(void) | 696 | u64 get_jiffies_64(void) |
667 | { | 697 | { |