aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/pkt_sched.h
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-03-16 04:18:42 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:26:04 -0400
commit641b9e0e8b7f96425da6ce98f3361e3af0baee29 (patch)
tree2315fed3b4fd9df52a52464b9b1ce1561d403a87 /include/net/pkt_sched.h
parentddc7b8e32b22fe8b45d306b7d99472d4b560add6 (diff)
[NET_SCHED]: Use ktime as clocksource
Get rid of the manual clock source selection mess and use ktime. Also use a scalar representation, which allows to clean up pkt_sched.h a bit more and results in less ktime_to_ns() calls in most cases. The PSCHED_US2JIFFIE/PSCHED_JIFFIE2US macros are implemented quite inefficient by this patch, following patches will convert all qdiscs to hrtimers and get rid of them entirely. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/pkt_sched.h')
-rw-r--r--include/net/pkt_sched.h169
1 files changed, 13 insertions, 156 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index f6afee73235d..1c12afd113d6 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -2,6 +2,7 @@
2#define __NET_PKT_SCHED_H 2#define __NET_PKT_SCHED_H
3 3
4#include <linux/jiffies.h> 4#include <linux/jiffies.h>
5#include <linux/ktime.h>
5#include <net/sch_generic.h> 6#include <net/sch_generic.h>
6 7
7struct qdisc_walker 8struct qdisc_walker
@@ -37,176 +38,32 @@ static inline void *qdisc_priv(struct Qdisc *q)
37 The things are not so bad, because we may use artifical 38 The things are not so bad, because we may use artifical
38 clock evaluated by integration of network data flow 39 clock evaluated by integration of network data flow
39 in the most critical places. 40 in the most critical places.
40
41 Note: we do not use fastgettimeofday.
42 The reason is that, when it is not the same thing as
43 gettimeofday, it returns invalid timestamp, which is
44 not updated, when net_bh is active.
45 */ 41 */
46 42
47/* General note about internal clock.
48
49 Any clock source returns time intervals, measured in units
50 close to 1usec. With source CONFIG_NET_SCH_CLK_GETTIMEOFDAY it is precisely
51 microseconds, otherwise something close but different chosen to minimize
52 arithmetic cost. Ratio usec/internal untis in form nominator/denominator
53 may be read from /proc/net/psched.
54 */
55
56
57#ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
58
59typedef struct timeval psched_time_t;
60typedef long psched_tdiff_t;
61
62#define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
63#define PSCHED_US2JIFFIE(usecs) usecs_to_jiffies(usecs)
64#define PSCHED_JIFFIE2US(delay) jiffies_to_usecs(delay)
65
66#else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
67
68typedef u64 psched_time_t; 43typedef u64 psched_time_t;
69typedef long psched_tdiff_t; 44typedef long psched_tdiff_t;
70 45
71#ifdef CONFIG_NET_SCH_CLK_JIFFIES 46/* Avoid doing 64 bit divide by 1000 */
72 47#define PSCHED_US2NS(x) ((s64)(x) << 10)
73#if HZ < 96 48#define PSCHED_NS2US(x) ((x) >> 10)
74#define PSCHED_JSCALE 14
75#elif HZ >= 96 && HZ < 192
76#define PSCHED_JSCALE 13
77#elif HZ >= 192 && HZ < 384
78#define PSCHED_JSCALE 12
79#elif HZ >= 384 && HZ < 768
80#define PSCHED_JSCALE 11
81#elif HZ >= 768
82#define PSCHED_JSCALE 10
83#endif
84
85#define PSCHED_GET_TIME(stamp) ((stamp) = (get_jiffies_64()<<PSCHED_JSCALE))
86#define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE)
87#define PSCHED_JIFFIE2US(delay) ((delay)<<PSCHED_JSCALE)
88
89#endif /* CONFIG_NET_SCH_CLK_JIFFIES */
90#ifdef CONFIG_NET_SCH_CLK_CPU
91#include <asm/timex.h>
92
93extern psched_tdiff_t psched_clock_per_hz;
94extern int psched_clock_scale;
95extern psched_time_t psched_time_base;
96extern cycles_t psched_time_mark;
97
98#define PSCHED_GET_TIME(stamp) \
99do { \
100 cycles_t cur = get_cycles(); \
101 if (sizeof(cycles_t) == sizeof(u32)) { \
102 if (cur <= psched_time_mark) \
103 psched_time_base += 0x100000000ULL; \
104 psched_time_mark = cur; \
105 (stamp) = (psched_time_base + cur)>>psched_clock_scale; \
106 } else { \
107 (stamp) = cur>>psched_clock_scale; \
108 } \
109} while (0)
110#define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
111#define PSCHED_JIFFIE2US(delay) ((delay)*psched_clock_per_hz)
112
113#endif /* CONFIG_NET_SCH_CLK_CPU */
114
115#endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
116
117#ifdef CONFIG_NET_SCH_CLK_GETTIMEOFDAY
118#define PSCHED_TDIFF(tv1, tv2) \
119({ \
120 int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
121 int __delta = (tv1).tv_usec - (tv2).tv_usec; \
122 if (__delta_sec) { \
123 switch (__delta_sec) { \
124 default: \
125 __delta = 0; \
126 case 2: \
127 __delta += USEC_PER_SEC; \
128 case 1: \
129 __delta += USEC_PER_SEC; \
130 } \
131 } \
132 __delta; \
133})
134
135static inline int
136psched_tod_diff(int delta_sec, int bound)
137{
138 int delta;
139
140 if (bound <= USEC_PER_SEC || delta_sec > (0x7FFFFFFF/USEC_PER_SEC)-1)
141 return bound;
142 delta = delta_sec * USEC_PER_SEC;
143 if (delta > bound || delta < 0)
144 delta = bound;
145 return delta;
146}
147
148#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
149({ \
150 int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
151 int __delta = (tv1).tv_usec - (tv2).tv_usec; \
152 switch (__delta_sec) { \
153 default: \
154 __delta = psched_tod_diff(__delta_sec, bound); break; \
155 case 2: \
156 __delta += USEC_PER_SEC; \
157 case 1: \
158 __delta += USEC_PER_SEC; \
159 case 0: \
160 if (__delta > bound || __delta < 0) \
161 __delta = bound; \
162 } \
163 __delta; \
164})
165
166#define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \
167 (tv1).tv_sec <= (tv2).tv_sec) || \
168 (tv1).tv_sec < (tv2).tv_sec)
169
170#define PSCHED_TADD2(tv, delta, tv_res) \
171({ \
172 int __delta = (tv).tv_usec + (delta); \
173 (tv_res).tv_sec = (tv).tv_sec; \
174 while (__delta >= USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
175 (tv_res).tv_usec = __delta; \
176})
177
178#define PSCHED_TADD(tv, delta) \
179({ \
180 (tv).tv_usec += (delta); \
181 while ((tv).tv_usec >= USEC_PER_SEC) { (tv).tv_sec++; \
182 (tv).tv_usec -= USEC_PER_SEC; } \
183})
184
185/* Set/check that time is in the "past perfect";
186 it depends on concrete representation of system time
187 */
188
189#define PSCHED_SET_PASTPERFECT(t) ((t).tv_sec = 0)
190#define PSCHED_IS_PASTPERFECT(t) ((t).tv_sec == 0)
191 49
192#define PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; }) 50#define PSCHED_TICKS_PER_SEC PSCHED_NS2US(NSEC_PER_SEC)
51#define PSCHED_GET_TIME(stamp) \
52 ((stamp) = PSCHED_NS2US(ktime_to_ns(ktime_get())))
193 53
194#else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ 54#define PSCHED_US2JIFFIE(usecs) usecs_to_jiffies(PSCHED_US2NS((usecs)) / NSEC_PER_USEC)
55#define PSCHED_JIFFIE2US(delay) PSCHED_NS2US(jiffies_to_usecs((delay)) * NSEC_PER_USEC)
195 56
196#define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2)) 57#define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2))
197#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \ 58#define PSCHED_TDIFF_SAFE(tv1, tv2, bound) \
198 min_t(long long, (tv1) - (tv2), bound) 59 min_t(long long, (tv1) - (tv2), bound)
199 60#define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2))
200
201#define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2))
202#define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta)) 61#define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta))
203#define PSCHED_TADD(tv, delta) ((tv) += (delta)) 62#define PSCHED_TADD(tv, delta) ((tv) += (delta))
204#define PSCHED_SET_PASTPERFECT(t) ((t) = 0) 63#define PSCHED_SET_PASTPERFECT(t) ((t) = 0)
205#define PSCHED_IS_PASTPERFECT(t) ((t) == 0) 64#define PSCHED_IS_PASTPERFECT(t) ((t) == 0)
206#define PSCHED_AUDIT_TDIFF(t) 65#define PSCHED_AUDIT_TDIFF(t)
207 66
208#endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
209
210extern struct Qdisc_ops pfifo_qdisc_ops; 67extern struct Qdisc_ops pfifo_qdisc_ops;
211extern struct Qdisc_ops bfifo_qdisc_ops; 68extern struct Qdisc_ops bfifo_qdisc_ops;
212 69