All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
To: linux-kernel@vger.kernel.org
Cc: "Stanislaw Gruszka" <sgruszka@redhat.com>,
	"Ingo Molnar" <mingo@elte.hu>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Spencer Candland" <spencer@bluehost.com>,
	"Oleg Nesterov" <oleg@redhat.com>,
	"Balbir Singh" <balbir@in.ibm.com>,
	"Américo Wang" <xiyou.wangcong@gmail.com>
Subject: [PATCH -tip 3/3] define nsecs_to_jiffies()
Date: Thu, 26 Nov 2009 14:49:27 +0900	[thread overview]
Message-ID: <4B0E16E7.5070307@jp.fujitsu.com> (raw)
In-Reply-To: <4B0B8683.6020104@jp.fujitsu.com>

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>
---
 include/linux/jiffies.h |    1 +
 kernel/sched.c          |    3 +--
 kernel/time.c           |   30 ++++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 1a9cf78..6811f4b 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -307,6 +307,7 @@ extern clock_t jiffies_to_clock_t(long x);
 extern unsigned long clock_t_to_jiffies(unsigned long x);
 extern u64 jiffies_64_to_clock_t(u64 x);
 extern u64 nsec_to_clock_t(u64 x);
+extern unsigned long nsecs_to_jiffies(u64 n);
 
 #define TIMESTAMP_SIZE	30
 
diff --git a/kernel/sched.c b/kernel/sched.c
index a7093c1..792b25e 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5156,8 +5156,7 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
 #else
 
 #ifndef nsecs_to_cputime
-# define nsecs_to_cputime(__nsecs) \
-	msecs_to_cputime(div_u64((__nsecs), NSEC_PER_MSEC))
+# define nsecs_to_cputime(__nsecs)	nsecs_to_jiffies(__nsecs)
 #endif
 
 void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
diff --git a/kernel/time.c b/kernel/time.c
index 2e2e469..b30016c 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -662,6 +662,36 @@ u64 nsec_to_clock_t(u64 x)
 #endif
 }
 
+/**
+ * nsecs_to_jiffies - Convert nsecs in u64 to jiffies
+ *
+ * @n:	nsecs in u64
+ *
+ * Unlike {m,u}secs_to_jiffies, type of input is not unsigned int but u64.
+ * And this doesn't return MAX_JIFFY_OFFSET since this function is designed
+ * for scheduler, not for use in device drivers to calculate timeout value.
+ *
+ * note:
+ *   NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ *   ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
+ */
+unsigned long nsecs_to_jiffies(u64 n)
+{
+#if (NSEC_PER_SEC % HZ) == 0
+	/* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */
+	return div_u64(n, NSEC_PER_SEC / HZ);
+#elif (HZ % 512) == 0
+	/* overflow after 292 years if HZ = 1024 */
+	return div_u64(n * HZ / 512, NSEC_PER_SEC / 512);
+#else
+	/*
+	 * Generic case - optimized for cases where HZ is a multiple of 3.
+	 * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc.
+	 */
+	return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ);
+#endif
+}
+
 #if (BITS_PER_LONG < 64)
 u64 get_jiffies_64(void)
 {
-- 
1.6.5.3


  parent reply	other threads:[~2009-11-26  5:49 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-20  4:44 [PATCH tip/sched/core] introduce task_times() to replace task_[us]time() pair Hidetoshi Seto
2009-11-23 10:28 ` Stanislaw Gruszka
2009-11-24  5:38   ` Hidetoshi Seto
2009-11-24  7:08     ` Hidetoshi Seto
2009-11-26  5:48       ` [PATCH -tip 1/3] introduce task_times() to replace task_{u,s}time() pair Hidetoshi Seto
2009-11-26 10:25         ` Peter Zijlstra
2009-11-27  0:37           ` Hidetoshi Seto
2009-11-26 12:33         ` [tip:sched/core] sched: Introduce " tip-bot for Hidetoshi Seto
2009-11-26  5:49       ` [PATCH -tip 2/3] remove task_{u,s,g}time() Hidetoshi Seto
2009-11-26 10:26         ` Peter Zijlstra
2009-11-26 12:33         ` [tip:sched/core] sched: Remove task_{u,s,g}time() tip-bot for Hidetoshi Seto
2009-11-26  5:49       ` Hidetoshi Seto [this message]
2009-11-26 10:27         ` [PATCH -tip 3/3] define nsecs_to_jiffies() Peter Zijlstra
2009-11-26 12:34         ` [tip:sched/core] sched, time: Define nsecs_to_jiffies() tip-bot for Hidetoshi Seto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B0E16E7.5070307@jp.fujitsu.com \
    --to=seto.hidetoshi@jp.fujitsu.com \
    --cc=balbir@in.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=sgruszka@redhat.com \
    --cc=spencer@bluehost.com \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.