netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephen Hemminger <shemminger@linux-foundation.org>
To: netdev@vger.kernel.org
Subject: [RFC] use ktime for packet scheduling
Date: Thu, 22 Feb 2007 14:30:47 -0800	[thread overview]
Message-ID: <20070222143047.1631b93e@freekitty> (raw)

Here is an experimental patch that changes the packet scheduler to use
ktime instead of gettimeofday. This should be faster on 64 bit and avoid some of
the math overhead issues with previous code.

Also since it uses monotonic clock, it won't cause timing glitches when NTP
adjusts the clock.

---
 include/net/pkt_sched.h |  123 ++++++++++++++----------------------------------
 kernel/hrtimer.c        |    1 
 2 files changed, 37 insertions(+), 87 deletions(-)

--- netem.orig/include/net/pkt_sched.h	2007-02-22 12:08:53.000000000 -0800
+++ netem/include/net/pkt_sched.h	2007-02-22 14:21:57.000000000 -0800
@@ -56,19 +56,48 @@
 
 #ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
 
-typedef struct timeval	psched_time_t;
-typedef long		psched_tdiff_t;
+typedef ktime_t psched_time_t;
+typedef long	psched_tdiff_t;
+
+/* Avoid doing 64 bit divide by 1000 */
+#define PSCHED_US2NS(x)	((s64)(x) << 10)
+#define PSCHED_NS2US(x)	((x) >> 10)
 
-#define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
+#define PSCHED_GET_TIME(stamp)  ((stamp) = ktime_get())
 #define PSCHED_US2JIFFIE(usecs) usecs_to_jiffies(usecs)
 #define PSCHED_JIFFIE2US(delay) jiffies_to_usecs(delay)
+static inline psched_tdiff_t psched_diff(const psched_time_t tv1,
+					 const psched_time_t tv2)
+{
+	return PSCHED_NS2US(ktime_to_ns(ktime_sub(tv1, tv2)));
+}
+
+#define PSCHED_TDIFF(tv1, tv2) psched_diff(tv1, tv2)
+#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
+	min_t(long, psched_diff((tv1),(tv2)), bound)
+
+static inline psched_time_t psched_add(const psched_time_t tv1, u32 usec)
+{
+	u64 ns = PSCHED_US2NS(usec);
+	return ktime_add_ns(tv1, ns);
+}
+
+#define PSCHED_TLESS(tv1, tv2) ((tv1).tv64 < (tv2).tv64)
+#define PSCHED_TADD(tv, delta) psched_add((tv), (delta))
+#define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = psched_add((tv), (delta)))
+
+/* Set/check that time is in the "past perfect" */
+
+#define PSCHED_SET_PASTPERFECT(t)	((t).tv64 = 0)
+#define PSCHED_IS_PASTPERFECT(t)	((t).tv64 == 0)
+#define	PSCHED_AUDIT_TDIFF(t)
 
 #else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
 
 typedef u64	psched_time_t;
 typedef long	psched_tdiff_t;
 
-#ifdef CONFIG_NET_SCH_CLK_JIFFIES
+#  ifdef CONFIG_NET_SCH_CLK_JIFFIES
 
 #if HZ < 96
 #define PSCHED_JSCALE 14
@@ -86,8 +115,7 @@
 #define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE)
 #define PSCHED_JIFFIE2US(delay) ((delay)<<PSCHED_JSCALE)
 
-#endif /* CONFIG_NET_SCH_CLK_JIFFIES */
-#ifdef CONFIG_NET_SCH_CLK_CPU
+#  elif defined(CONFIG_NET_SCH_CLK_CPU)
 #include <asm/timex.h>
 
 extern psched_tdiff_t psched_clock_per_hz;
@@ -110,89 +138,10 @@
 #define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
 #define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz)
 
-#endif /* CONFIG_NET_SCH_CLK_CPU */
-
+#else
+#error CONFIG_NET_SCH_CLK not set correctly!
 #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
 
-#ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
-#define PSCHED_TDIFF(tv1, tv2) \
-({ \
-	   int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
-	   int __delta = (tv1).tv_usec - (tv2).tv_usec; \
-	   if (__delta_sec) { \
-	           switch (__delta_sec) { \
-		   default: \
-			   __delta = 0; \
-		   case 2: \
-			   __delta += USEC_PER_SEC; \
-		   case 1: \
-			   __delta += USEC_PER_SEC; \
-	           } \
-	   } \
-	   __delta; \
-})
-
-static inline int
-psched_tod_diff(int delta_sec, int bound)
-{
-	int delta;
-
-	if (bound <= USEC_PER_SEC || delta_sec > (0x7FFFFFFF/USEC_PER_SEC)-1)
-		return bound;
-	delta = delta_sec * USEC_PER_SEC;
-	if (delta > bound || delta < 0)
-		delta = bound;
-	return delta;
-}
-
-#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
-({ \
-	   int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
-	   int __delta = (tv1).tv_usec - (tv2).tv_usec; \
-	   switch (__delta_sec) { \
-	   default: \
-		   __delta = psched_tod_diff(__delta_sec, bound);  break; \
-	   case 2: \
-		   __delta += USEC_PER_SEC; \
-	   case 1: \
-		   __delta += USEC_PER_SEC; \
-	   case 0: \
- 		   if (__delta > bound || __delta < 0) \
- 			__delta = bound; \
-	   } \
-	   __delta; \
-})
-
-#define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \
-				(tv1).tv_sec <= (tv2).tv_sec) || \
-				 (tv1).tv_sec < (tv2).tv_sec)
-
-#define PSCHED_TADD2(tv, delta, tv_res) \
-({ \
-	   int __delta = (tv).tv_usec + (delta); \
-	   (tv_res).tv_sec = (tv).tv_sec; \
-	   while (__delta >= USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
-	   (tv_res).tv_usec = __delta; \
-})
-
-#define PSCHED_TADD(tv, delta) \
-({ \
-	   (tv).tv_usec += (delta); \
-	   while ((tv).tv_usec >= USEC_PER_SEC) { (tv).tv_sec++; \
-		 (tv).tv_usec -= USEC_PER_SEC; } \
-})
-
-/* Set/check that time is in the "past perfect";
-   it depends on concrete representation of system time
- */
-
-#define PSCHED_SET_PASTPERFECT(t)	((t).tv_sec = 0)
-#define PSCHED_IS_PASTPERFECT(t)	((t).tv_sec == 0)
-
-#define	PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; })
-
-#else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
-
 #define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2))
 #define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
 	min_t(long long, (tv1) - (tv2), bound)
--- netem.orig/kernel/hrtimer.c	2007-02-22 14:03:11.000000000 -0800
+++ netem/kernel/hrtimer.c	2007-02-22 14:11:02.000000000 -0800
@@ -59,6 +59,7 @@
 
 	return timespec_to_ktime(now);
 }
+EXPORT_SYMBOL_GPL(ktime_get);
 
 /**
  * ktime_get_real - get the real (wall-) time in ktime_t format

             reply	other threads:[~2007-02-22 22:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-22 22:30 Stephen Hemminger [this message]
2007-02-24 14:17 ` [RFC] use ktime for packet scheduling Patrick McHardy
2007-03-07 23:59   ` Stephen Hemminger
2007-03-08 17:48     ` Patrick McHardy

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=20070222143047.1631b93e@freekitty \
    --to=shemminger@linux-foundation.org \
    --cc=netdev@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).