~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/net/pkt_sched.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef __NET_PKT_SCHED_H
  2 #define __NET_PKT_SCHED_H
  3 
  4 #define PSCHED_GETTIMEOFDAY     1
  5 #define PSCHED_JIFFIES          2
  6 #define PSCHED_CPU              3
  7 
  8 #define PSCHED_CLOCK_SOURCE     PSCHED_JIFFIES
  9 
 10 #include <linux/config.h>
 11 #include <linux/pkt_sched.h>
 12 #include <net/pkt_cls.h>
 13 
 14 #ifdef CONFIG_X86_TSC
 15 #include <asm/msr.h>
 16 #endif
 17 
 18 struct rtattr;
 19 struct Qdisc;
 20 
 21 struct qdisc_walker
 22 {
 23         int     stop;
 24         int     skip;
 25         int     count;
 26         int     (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *);
 27 };
 28 
 29 struct Qdisc_class_ops
 30 {
 31         /* Child qdisc manipulation */
 32         int                     (*graft)(struct Qdisc *, unsigned long cl, struct Qdisc *, struct Qdisc **);
 33         struct Qdisc *          (*leaf)(struct Qdisc *, unsigned long cl);
 34 
 35         /* Class manipulation routines */
 36         unsigned long           (*get)(struct Qdisc *, u32 classid);
 37         void                    (*put)(struct Qdisc *, unsigned long);
 38         int                     (*change)(struct Qdisc *, u32, u32, struct rtattr **, unsigned long *);
 39         int                     (*delete)(struct Qdisc *, unsigned long);
 40         void                    (*walk)(struct Qdisc *, struct qdisc_walker * arg);
 41 
 42         /* Filter manipulation */
 43         struct tcf_proto **     (*tcf_chain)(struct Qdisc *, unsigned long);
 44         unsigned long           (*bind_tcf)(struct Qdisc *, unsigned long, u32 classid);
 45         void                    (*unbind_tcf)(struct Qdisc *, unsigned long);
 46 
 47         /* rtnetlink specific */
 48         int                     (*dump)(struct Qdisc *, unsigned long, struct sk_buff *skb, struct tcmsg*);
 49 };
 50 
 51 struct Qdisc_ops
 52 {
 53         struct Qdisc_ops        *next;
 54         struct Qdisc_class_ops  *cl_ops;
 55         char                    id[IFNAMSIZ];
 56         int                     priv_size;
 57 
 58         int                     (*enqueue)(struct sk_buff *, struct Qdisc *);
 59         struct sk_buff *        (*dequeue)(struct Qdisc *);
 60         int                     (*requeue)(struct sk_buff *, struct Qdisc *);
 61         int                     (*drop)(struct Qdisc *);
 62 
 63         int                     (*init)(struct Qdisc *, struct rtattr *arg);
 64         void                    (*reset)(struct Qdisc *);
 65         void                    (*destroy)(struct Qdisc *);
 66         int                     (*change)(struct Qdisc *, struct rtattr *arg);
 67 
 68         int                     (*dump)(struct Qdisc *, struct sk_buff *);
 69 };
 70 
 71 extern rwlock_t qdisc_tree_lock;
 72 
 73 struct Qdisc
 74 {
 75         int                     (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
 76         struct sk_buff *        (*dequeue)(struct Qdisc *dev);
 77         unsigned                flags;
 78 #define TCQ_F_BUILTIN   1
 79 #define TCQ_F_THROTTLED 2
 80 #define TCQ_F_INGRES    4
 81         struct Qdisc_ops        *ops;
 82         struct Qdisc            *next;
 83         u32                     handle;
 84         atomic_t                refcnt;
 85         struct sk_buff_head     q;
 86         struct net_device       *dev;
 87 
 88         struct tc_stats         stats;
 89         int                     (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);
 90 
 91         /* This field is deprecated, but it is still used by CBQ
 92          * and it will live until better solution will be invented.
 93          */
 94         struct Qdisc            *__parent;
 95 
 96         char                    data[0];
 97 };
 98 
 99 struct qdisc_rate_table
100 {
101         struct tc_ratespec rate;
102         u32             data[256];
103         struct qdisc_rate_table *next;
104         int             refcnt;
105 };
106 
107 static inline void sch_tree_lock(struct Qdisc *q)
108 {
109         write_lock(&qdisc_tree_lock);
110         spin_lock_bh(&q->dev->queue_lock);
111 }
112 
113 static inline void sch_tree_unlock(struct Qdisc *q)
114 {
115         spin_unlock_bh(&q->dev->queue_lock);
116         write_unlock(&qdisc_tree_lock);
117 }
118 
119 static inline void tcf_tree_lock(struct tcf_proto *tp)
120 {
121         write_lock(&qdisc_tree_lock);
122         spin_lock_bh(&tp->q->dev->queue_lock);
123 }
124 
125 static inline void tcf_tree_unlock(struct tcf_proto *tp)
126 {
127         spin_unlock_bh(&tp->q->dev->queue_lock);
128         write_unlock(&qdisc_tree_lock);
129 }
130 
131 
132 static inline unsigned long
133 cls_set_class(struct tcf_proto *tp, unsigned long *clp, unsigned long cl)
134 {
135         unsigned long old_cl;
136 
137         tcf_tree_lock(tp);
138         old_cl = *clp;
139         *clp = cl;
140         tcf_tree_unlock(tp);
141         return old_cl;
142 }
143 
144 static inline unsigned long
145 __cls_set_class(unsigned long *clp, unsigned long cl)
146 {
147         unsigned long old_cl;
148 
149         old_cl = *clp;
150         *clp = cl;
151         return old_cl;
152 }
153 
154 
155 /* 
156    Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth
157    
158    Normal IP packet size ~ 512byte, hence:
159 
160    0.5Kbyte/1Mbyte/sec = 0.5msec, so that we need 50usec timer for
161    10Mbit ethernet.
162 
163    10msec resolution -> <50Kbit/sec.
164    
165    The result: [34]86 is not good choice for QoS router :-(
166 
167    The things are not so bad, because we may use artifical
168    clock evaluated by integration of network data flow
169    in the most critical places.
170 
171    Note: we do not use fastgettimeofday.
172    The reason is that, when it is not the same thing as
173    gettimeofday, it returns invalid timestamp, which is
174    not updated, when net_bh is active.
175 
176    So, use PSCHED_CLOCK_SOURCE = PSCHED_CPU on alpha and pentiums
177    with rtdsc. And PSCHED_JIFFIES on all other architectures, including [34]86
178    and pentiums without rtdsc.
179    You can use PSCHED_GETTIMEOFDAY on another architectures,
180    which have fast and precise clock source, but it is too expensive.
181  */
182 
183 /* General note about internal clock.
184 
185    Any clock source returns time intervals, measured in units
186    close to 1usec. With source PSCHED_GETTIMEOFDAY it is precisely
187    microseconds, otherwise something close but different chosen to minimize
188    arithmetic cost. Ratio usec/internal untis in form nominator/denominator
189    may be read from /proc/net/psched.
190  */
191 
192 
193 #if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
194 
195 typedef struct timeval  psched_time_t;
196 typedef long            psched_tdiff_t;
197 
198 #define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
199 #define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ))
200 
201 #define PSCHED_EXPORTLIST EXPORT_SYMBOL(psched_tod_diff);
202 
203 #else /* PSCHED_CLOCK_SOURCE != PSCHED_GETTIMEOFDAY */
204 
205 #define PSCHED_EXPORTLIST PSCHED_EXPORTLIST_1 PSCHED_EXPORTLIST_2
206 
207 typedef u64     psched_time_t;
208 typedef long    psched_tdiff_t;
209 
210 extern psched_time_t    psched_time_base;
211 
212 #if PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES
213 
214 #if HZ == 100
215 #define PSCHED_JSCALE 13
216 #elif HZ == 1024
217 #define PSCHED_JSCALE 10
218 #else
219 #define PSCHED_JSCALE 0
220 #endif
221 
222 #define PSCHED_EXPORTLIST_2
223 
224 #if ~0UL == 0xFFFFFFFF
225 
226 #define PSCHED_WATCHER unsigned long
227 
228 extern PSCHED_WATCHER psched_time_mark;
229 
230 #define PSCHED_GET_TIME(stamp) ((stamp) = psched_time_base + (((unsigned long)(jiffies-psched_time_mark))<<PSCHED_JSCALE))
231 
232 #define PSCHED_EXPORTLIST_1 EXPORT_SYMBOL(psched_time_base); \
233                             EXPORT_SYMBOL(psched_time_mark);
234 
235 #else
236 
237 #define PSCHED_GET_TIME(stamp) ((stamp) = (jiffies<<PSCHED_JSCALE))
238 
239 #define PSCHED_EXPORTLIST_1 
240 
241 #endif
242 
243 #define PSCHED_US2JIFFIE(delay) (((delay)+(1<<PSCHED_JSCALE)-1)>>PSCHED_JSCALE)
244 
245 #elif PSCHED_CLOCK_SOURCE == PSCHED_CPU
246 
247 extern psched_tdiff_t psched_clock_per_hz;
248 extern int psched_clock_scale;
249 
250 #define PSCHED_EXPORTLIST_2 EXPORT_SYMBOL(psched_clock_per_hz); \
251                             EXPORT_SYMBOL(psched_clock_scale);
252 
253 #define PSCHED_US2JIFFIE(delay) (((delay)+psched_clock_per_hz-1)/psched_clock_per_hz)
254 
255 #ifdef CONFIG_X86_TSC
256 
257 #define PSCHED_GET_TIME(stamp) \
258 ({ u64 __cur; \
259    rdtscll(__cur); \
260    (stamp) = __cur>>psched_clock_scale; \
261 })
262 
263 #define PSCHED_EXPORTLIST_1
264 
265 #elif defined (__alpha__)
266 
267 #define PSCHED_WATCHER u32
268 
269 extern PSCHED_WATCHER psched_time_mark;
270 
271 #define PSCHED_GET_TIME(stamp) \
272 ({ u32 __res; \
273    __asm__ __volatile__ ("rpcc %0" : "r="(__res)); \
274    if (__res <= psched_time_mark) psched_time_base += 0x100000000UL; \
275    psched_time_mark = __res; \
276    (stamp) = (psched_time_base + __res)>>psched_clock_scale; \
277 })
278 
279 #define PSCHED_EXPORTLIST_1 EXPORT_SYMBOL(psched_time_base); \
280                             EXPORT_SYMBOL(psched_time_mark);
281 
282 #else
283 
284 #error PSCHED_CLOCK_SOURCE=PSCHED_CPU is not supported on this arch.
285 
286 #endif /* ARCH */
287 
288 #endif /* PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES */
289 
290 #endif /* PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY */
291 
292 #if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
293 #define PSCHED_TDIFF(tv1, tv2) \
294 ({ \
295            int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
296            int __delta = (tv1).tv_usec - (tv2).tv_usec; \
297            if (__delta_sec) { \
298                    switch (__delta_sec) { \
299                    default: \
300                            __delta = 0; \
301                    case 2: \
302                            __delta += 1000000; \
303                    case 1: \
304                            __delta += 1000000; \
305                    } \
306            } \
307            __delta; \
308 })
309 
310 extern int psched_tod_diff(int delta_sec, int bound);
311 
312 #define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \
313 ({ \
314            int __delta_sec = (tv1).tv_sec - (tv2).tv_sec; \
315            int __delta = (tv1).tv_usec - (tv2).tv_usec; \
316            switch (__delta_sec) { \
317            default: \
318                    __delta = psched_tod_diff(__delta_sec, bound); guard; break; \
319            case 2: \
320                    __delta += 1000000; \
321            case 1: \
322                    __delta += 1000000; \
323            case 0: ; \
324            } \
325            __delta; \
326 })
327 
328 #define PSCHED_TLESS(tv1, tv2) (((tv1).tv_usec < (tv2).tv_usec && \
329                                 (tv1).tv_sec <= (tv2).tv_sec) || \
330                                  (tv1).tv_sec < (tv2).tv_sec)
331 
332 #define PSCHED_TADD2(tv, delta, tv_res) \
333 ({ \
334            int __delta = (tv).tv_usec + (delta); \
335            (tv_res).tv_sec = (tv).tv_sec; \
336            if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \
337            (tv_res).tv_usec = __delta; \
338 })
339 
340 #define PSCHED_TADD(tv, delta) \
341 ({ \
342            (tv).tv_usec += (delta); \
343            if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \
344                  (tv).tv_usec -= 1000000; } \
345 })
346 
347 /* Set/check that time is in the "past perfect";
348    it depends on concrete representation of system time
349  */
350 
351 #define PSCHED_SET_PASTPERFECT(t)       ((t).tv_sec = 0)
352 #define PSCHED_IS_PASTPERFECT(t)        ((t).tv_sec == 0)
353 
354 #define PSCHED_AUDIT_TDIFF(t) ({ if ((t) > 2000000) (t) = 2000000; })
355 
356 #else
357 
358 #define PSCHED_TDIFF(tv1, tv2) (long)((tv1) - (tv2))
359 #define PSCHED_TDIFF_SAFE(tv1, tv2, bound, guard) \
360 ({ \
361            long __delta = (tv1) - (tv2); \
362            if ( __delta > (bound)) {  __delta = (bound); guard; } \
363            __delta; \
364 })
365 
366 
367 #define PSCHED_TLESS(tv1, tv2) ((tv1) < (tv2))
368 #define PSCHED_TADD2(tv, delta, tv_res) ((tv_res) = (tv) + (delta))
369 #define PSCHED_TADD(tv, delta) ((tv) += (delta))
370 #define PSCHED_SET_PASTPERFECT(t)       ((t) = 0)
371 #define PSCHED_IS_PASTPERFECT(t)        ((t) == 0)
372 #define PSCHED_AUDIT_TDIFF(t)
373 
374 #endif
375 
376 struct tcf_police
377 {
378         struct tcf_police *next;
379         int             refcnt;
380         u32             index;
381 
382         int             action;
383         int             result;
384         u32             ewma_rate;
385         u32             burst;
386         u32             mtu;
387 
388         u32             toks;
389         u32             ptoks;
390         psched_time_t   t_c;
391         spinlock_t      lock;
392         struct qdisc_rate_table *R_tab;
393         struct qdisc_rate_table *P_tab;
394 
395         struct tc_stats stats;
396 };
397 
398 extern int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st);
399 extern void tcf_police_destroy(struct tcf_police *p);
400 extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est);
401 extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p);
402 extern int tcf_police(struct sk_buff *skb, struct tcf_police *p);
403 
404 static inline void tcf_police_release(struct tcf_police *p)
405 {
406         if (p && --p->refcnt == 0)
407                 tcf_police_destroy(p);
408 }
409 
410 extern struct Qdisc noop_qdisc;
411 extern struct Qdisc_ops noop_qdisc_ops;
412 extern struct Qdisc_ops pfifo_qdisc_ops;
413 extern struct Qdisc_ops bfifo_qdisc_ops;
414 
415 int register_qdisc(struct Qdisc_ops *qops);
416 int unregister_qdisc(struct Qdisc_ops *qops);
417 struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
418 struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
419 void dev_init_scheduler(struct net_device *dev);
420 void dev_shutdown(struct net_device *dev);
421 void dev_activate(struct net_device *dev);
422 void dev_deactivate(struct net_device *dev);
423 void qdisc_reset(struct Qdisc *qdisc);
424 void qdisc_destroy(struct Qdisc *qdisc);
425 struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops);
426 int qdisc_new_estimator(struct tc_stats *stats, struct rtattr *opt);
427 void qdisc_kill_estimator(struct tc_stats *stats);
428 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab);
429 void qdisc_put_rtab(struct qdisc_rate_table *tab);
430 int teql_init(void);
431 int tc_filter_init(void);
432 int pktsched_init(void);
433 
434 extern int qdisc_restart(struct net_device *dev);
435 
436 static inline void qdisc_run(struct net_device *dev)
437 {
438         while (!netif_queue_stopped(dev) &&
439                qdisc_restart(dev)<0)
440                 /* NOTHING */;
441 }
442 
443 /* Calculate maximal size of packet seen by hard_start_xmit
444    routine of this device.
445  */
446 static inline unsigned psched_mtu(struct net_device *dev)
447 {
448         unsigned mtu = dev->mtu;
449         return dev->hard_header ? mtu + dev->hard_header_len : mtu;
450 }
451 
452 #endif
453 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.