netdev
[Top] [All Lists]

Re: [PATCH 2.6]: Make packet scheduler clock source configurable

To: "David S. Miller" <davem@xxxxxxxxxx>
Subject: Re: [PATCH 2.6]: Make packet scheduler clock source configurable
From: Patrick McHardy <kaber@xxxxxxxxx>
Date: Wed, 14 Jul 2004 05:46:19 +0200
Cc: shemminger@xxxxxxxx, netdev@xxxxxxxxxxx, devik@xxxxxx
In-reply-to: <40F4862D.3070802@xxxxxxxxx>
References: <40F34740.5040100@xxxxxxxxx> <1107.63.170.215.71.1089689716.squirrel@xxxxxxxxxxxx> <20040712205037.573411c0.davem@xxxxxxxxxx> <40F4862D.3070802@xxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5
Patrick McHardy wrote:
David S. Miller wrote:


I also want to add sparc64 %tick register support here too.
This is an area with a lot of potential cleanup.  We should
made an asm/pkt_sched.h to abstract out the clock source
implementation instead of loading net/pkt_sched.h up with
a pile of ifdefs.


Couldn't we just use get_cycles() ? Something like this:

#include <asm/timex.h>

#if sizeof(cycles_t) == sizeof(u64)

This one actually compiles ;). The assembler of PSCHED_GET_TIME is
exactly the same on x86. There are 10 architectures that return
something non-zero for get_cycles(), but I have no idea if it is
suitable on all of them. Patch applies on top of the dead-code
removal patch.

Regards
Patrick
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/07/14 05:22:57+02:00 kaber@xxxxxxxxx 
#   [PKT_SCHED]: Use get_cycles() for PSCHED_CPU clock source
#   
#   Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
# 
# net/sched/sch_api.c
#   2004/07/14 05:22:48+02:00 kaber@xxxxxxxxx +12 -13
#   [PKT_SCHED]: Use get_cycles() for PSCHED_CPU clock source
# 
# include/net/pkt_sched.h
#   2004/07/14 05:22:48+02:00 kaber@xxxxxxxxx +15 -34
#   [PKT_SCHED]: Use get_cycles() for PSCHED_CPU clock source
# 
diff -Nru a/include/net/pkt_sched.h b/include/net/pkt_sched.h
--- a/include/net/pkt_sched.h   2004-07-14 05:23:48 +02:00
+++ b/include/net/pkt_sched.h   2004-07-14 05:23:48 +02:00
@@ -16,11 +16,6 @@
 #include <linux/module.h>
 #include <linux/rtnetlink.h>
 
-#ifdef CONFIG_X86_TSC
-#include <asm/msr.h>
-#endif
-
-
 struct rtattr;
 struct Qdisc;
 
@@ -235,41 +230,27 @@
 #define PSCHED_JIFFIE2US(delay) ((delay)<<PSCHED_JSCALE)
 
 #elif PSCHED_CLOCK_SOURCE == PSCHED_CPU
+#include <asm/timex.h>
 
 extern psched_tdiff_t psched_clock_per_hz;
 extern int psched_clock_scale;
+extern psched_time_t psched_time_base;
+extern cycles_t psched_time_mark;
 
+#define PSCHED_GET_TIME(stamp)                                         \
+do {                                                                   \
+       cycles_t cur = get_cycles();                                    \
+       if (sizeof(cycles_t) == sizeof(u32)) {                          \
+               if (cur <= psched_time_mark)                            \
+                       psched_time_base += 0x100000000ULL;             \
+               psched_time_mark = cur;                                 \
+               (stamp) = (psched_time_base + cur)>>psched_clock_scale; \
+       } else {                                                        \
+               (stamp) = cur>>psched_clock_scale;                      \
+       }                                                               \
+} while (0)
 #define PSCHED_US2JIFFIE(delay) 
(((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
 #define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz)
-
-#ifdef CONFIG_X86_TSC
-
-#define PSCHED_GET_TIME(stamp) \
-({ u64 __cur; \
-   rdtscll(__cur); \
-   (stamp) = __cur>>psched_clock_scale; \
-})
-
-#elif defined (__alpha__)
-
-#define PSCHED_WATCHER u32
-
-extern psched_time_t psched_time_base;
-extern PSCHED_WATCHER psched_time_mark;
-
-#define PSCHED_GET_TIME(stamp) \
-({ u32 __res; \
-   __asm__ __volatile__ ("rpcc %0" : "r="(__res)); \
-   if (__res <= psched_time_mark) psched_time_base += 0x100000000UL; \
-   psched_time_mark = __res; \
-   (stamp) = (psched_time_base + __res)>>psched_clock_scale; \
-})
-
-#else
-
-#error PSCHED_CLOCK_SOURCE=PSCHED_CPU is not supported on this arch.
-
-#endif /* ARCH */
 
 #endif /* PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES */
 
diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c
--- a/net/sched/sch_api.c       2004-07-14 05:23:48 +02:00
+++ b/net/sched/sch_api.c       2004-07-14 05:23:48 +02:00
@@ -1109,25 +1109,26 @@
 EXPORT_SYMBOL(psched_clock_per_hz);
 EXPORT_SYMBOL(psched_clock_scale);
 
-#ifdef PSCHED_WATCHER
 psched_time_t psched_time_base;
-PSCHED_WATCHER psched_time_mark;
+cycles_t psched_time_mark;
 EXPORT_SYMBOL(psched_time_mark);
 EXPORT_SYMBOL(psched_time_base);
 
-static void psched_tick(unsigned long);
-
-static struct timer_list psched_timer = TIMER_INITIALIZER(psched_tick, 0, 0);
-
+/*
+ * Periodically adjust psched_time_base to avoid overflow
+ * with 32-bit get_cycles(). Safe up to 4GHz CPU.
+ */
 static void psched_tick(unsigned long dummy)
 {
+       static struct timer_list psched_timer = { .function = psched_tick };
        psched_time_t dummy_stamp;
-       PSCHED_GET_TIME(dummy_stamp);
-       /* It is OK up to 4GHz cpu */
-       psched_timer.expires = jiffies + 1*HZ;
-       add_timer(&psched_timer);
+
+       if (sizeof(cycles_t) == sizeof(u32)) {
+               PSCHED_GET_TIME(dummy_stamp);
+               psched_timer.expires = jiffies + 1*HZ;
+               add_timer(&psched_timer);
+       }
 }
-#endif
 
 int __init psched_calibrate_clock(void)
 {
@@ -1137,9 +1138,7 @@
        long rdelay;
        unsigned long stop;
 
-#ifdef PSCHED_WATCHER
        psched_tick(0);
-#endif
        stop = jiffies + HZ/10;
        PSCHED_GET_TIME(stamp);
        do_gettimeofday(&tv);
<Prev in Thread] Current Thread [Next in Thread>