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);
|