X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fnet%2Fpkt_sched.h;h=f6afee73235de8ca5e3ce395a2d53f1ee8c9b650;hb=refs%2Fheads%2Fvserver;hp=dab127cc2b1d85df24fa99b38c12e7c05d27489f;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index dab127cc2..f6afee732 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -1,17 +1,8 @@ #ifndef __NET_PKT_SCHED_H #define __NET_PKT_SCHED_H -#include -#include -#include -#include -#include -#include -#include -#include - -struct rtattr; -struct Qdisc; +#include +#include struct qdisc_walker { @@ -21,119 +12,16 @@ struct qdisc_walker int (*fn)(struct Qdisc *, unsigned long cl, struct qdisc_walker *); }; -struct Qdisc_class_ops -{ - /* Child qdisc manipulation */ - int (*graft)(struct Qdisc *, unsigned long cl, struct Qdisc *, struct Qdisc **); - struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); - - /* Class manipulation routines */ - unsigned long (*get)(struct Qdisc *, u32 classid); - void (*put)(struct Qdisc *, unsigned long); - int (*change)(struct Qdisc *, u32, u32, struct rtattr **, unsigned long *); - int (*delete)(struct Qdisc *, unsigned long); - void (*walk)(struct Qdisc *, struct qdisc_walker * arg); - - /* Filter manipulation */ - struct tcf_proto ** (*tcf_chain)(struct Qdisc *, unsigned long); - unsigned long (*bind_tcf)(struct Qdisc *, unsigned long, u32 classid); - void (*unbind_tcf)(struct Qdisc *, unsigned long); - - /* rtnetlink specific */ - int (*dump)(struct Qdisc *, unsigned long, struct sk_buff *skb, struct tcmsg*); -}; - -struct module; - -struct Qdisc_ops -{ - struct Qdisc_ops *next; - struct Qdisc_class_ops *cl_ops; - char id[IFNAMSIZ]; - int priv_size; - - int (*enqueue)(struct sk_buff *, struct Qdisc *); - struct sk_buff * (*dequeue)(struct Qdisc *); - int (*requeue)(struct sk_buff *, struct Qdisc *); - unsigned int (*drop)(struct Qdisc *); - - int (*init)(struct Qdisc *, struct rtattr *arg); - void (*reset)(struct Qdisc *); - void (*destroy)(struct Qdisc *); - int (*change)(struct Qdisc *, struct rtattr *arg); - - int (*dump)(struct Qdisc *, struct sk_buff *); - - struct module *owner; -}; - extern rwlock_t qdisc_tree_lock; -struct Qdisc -{ - int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); - struct sk_buff * (*dequeue)(struct Qdisc *dev); - unsigned flags; -#define TCQ_F_BUILTIN 1 -#define TCQ_F_THROTTLED 2 -#define TCQ_F_INGRES 4 - int padded; - struct Qdisc_ops *ops; - u32 handle; - u32 parent; - atomic_t refcnt; - struct sk_buff_head q; - struct net_device *dev; - struct list_head list; - - struct tc_stats stats; - spinlock_t *stats_lock; - struct rcu_head q_rcu; - int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q); - - /* This field is deprecated, but it is still used by CBQ - * and it will live until better solution will be invented. - */ - struct Qdisc *__parent; -}; - -#define QDISC_ALIGN 32 -#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) +#define QDISC_ALIGNTO 32 +#define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1)) static inline void *qdisc_priv(struct Qdisc *q) { - return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); -} - -struct qdisc_rate_table -{ - struct tc_ratespec rate; - u32 data[256]; - struct qdisc_rate_table *next; - int refcnt; -}; - -extern void qdisc_lock_tree(struct net_device *dev); -extern void qdisc_unlock_tree(struct net_device *dev); - -#define sch_tree_lock(q) qdisc_lock_tree((q)->dev) -#define sch_tree_unlock(q) qdisc_unlock_tree((q)->dev) -#define tcf_tree_lock(tp) qdisc_lock_tree((tp)->q->dev) -#define tcf_tree_unlock(tp) qdisc_unlock_tree((tp)->q->dev) - -#define cls_set_class(tp, clp, cl) tcf_set_class(tp, clp, cl) -static inline unsigned long -__cls_set_class(unsigned long *clp, unsigned long cl) -{ - unsigned long old_cl; - - old_cl = *clp; - *clp = cl; - return old_cl; + return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc)); } - /* Timer resolution MUST BE < 10% of min_schedulable_packet_size/bandwidth @@ -172,8 +60,8 @@ typedef struct timeval psched_time_t; typedef long psched_tdiff_t; #define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp)) -#define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ)) -#define PSCHED_JIFFIE2US(delay) ((delay)*(1000000/HZ)) +#define PSCHED_US2JIFFIE(usecs) usecs_to_jiffies(usecs) +#define PSCHED_JIFFIE2US(delay) jiffies_to_usecs(delay) #else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ @@ -236,15 +124,26 @@ do { \ default: \ __delta = 0; \ case 2: \ - __delta += 1000000; \ + __delta += USEC_PER_SEC; \ case 1: \ - __delta += 1000000; \ + __delta += USEC_PER_SEC; \ } \ } \ __delta; \ }) -extern int psched_tod_diff(int delta_sec, int bound); +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) \ ({ \ @@ -254,10 +153,12 @@ extern int psched_tod_diff(int delta_sec, int bound); default: \ __delta = psched_tod_diff(__delta_sec, bound); break; \ case 2: \ - __delta += 1000000; \ + __delta += USEC_PER_SEC; \ case 1: \ - __delta += 1000000; \ - case 0: ; \ + __delta += USEC_PER_SEC; \ + case 0: \ + if (__delta > bound || __delta < 0) \ + __delta = bound; \ } \ __delta; \ }) @@ -270,15 +171,15 @@ extern int psched_tod_diff(int delta_sec, int bound); ({ \ int __delta = (tv).tv_usec + (delta); \ (tv_res).tv_sec = (tv).tv_sec; \ - if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \ + 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); \ - if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \ - (tv).tv_usec -= 1000000; } \ + 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"; @@ -306,140 +207,28 @@ extern int psched_tod_diff(int delta_sec, int bound); #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ -struct tcf_police -{ - struct tcf_police *next; - int refcnt; -#ifdef CONFIG_NET_CLS_ACT - int bindcnt; -#endif - u32 index; - int action; - int result; - u32 ewma_rate; - u32 burst; - u32 mtu; - u32 toks; - u32 ptoks; - psched_time_t t_c; - spinlock_t lock; - struct qdisc_rate_table *R_tab; - struct qdisc_rate_table *P_tab; - - struct tc_stats stats; - spinlock_t *stats_lock; -}; - -#ifdef CONFIG_NET_CLS_ACT - -#define ACT_P_CREATED 1 -#define ACT_P_DELETED 1 -#define tca_gen(name) \ -struct tcf_##name *next; \ - u32 index; \ - int refcnt; \ - int bindcnt; \ - u32 capab; \ - int action; \ - struct tcf_t tm; \ - struct tc_stats stats; \ - spinlock_t *stats_lock; \ - spinlock_t lock - - -struct tc_action -{ - void *priv; - struct tc_action_ops *ops; - __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ - __u32 order; - struct tc_action *next; -}; - -#define TCA_CAP_NONE 0 -struct tc_action_ops -{ - struct tc_action_ops *next; - char kind[IFNAMSIZ]; - __u32 type; /* TBD to match kind */ - __u32 capab; /* capabilities includes 4 bit version */ - struct module *owner; - int (*act)(struct sk_buff **, struct tc_action *); - int (*get_stats)(struct sk_buff *, struct tc_action *); - int (*dump)(struct sk_buff *, struct tc_action *,int , int); - int (*cleanup)(struct tc_action *, int bind); - int (*lookup)(struct tc_action *, u32 ); - int (*init)(struct rtattr *,struct rtattr *,struct tc_action *, int , int ); - int (*walk)(struct sk_buff *, struct netlink_callback *, int , struct tc_action *); -}; +extern struct Qdisc_ops pfifo_qdisc_ops; +extern struct Qdisc_ops bfifo_qdisc_ops; -extern int tcf_register_action(struct tc_action_ops *a); -extern int tcf_unregister_action(struct tc_action_ops *a); -extern void tcf_action_destroy(struct tc_action *a, int bind); -extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res); -extern int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind); -extern int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind); -extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int); -extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); -extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); -extern int tcf_action_copy_stats (struct sk_buff *,struct tc_action *); -extern int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *,int , int ); -extern int tcf_act_police_dump(struct sk_buff *, struct tc_action *, int, int); -extern int tcf_act_police(struct sk_buff **skb, struct tc_action *a); -#endif +extern int register_qdisc(struct Qdisc_ops *qops); +extern int unregister_qdisc(struct Qdisc_ops *qops); +extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); +extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); +extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, + struct rtattr *tab); +extern void qdisc_put_rtab(struct qdisc_rate_table *tab); -extern unsigned long tcf_set_class(struct tcf_proto *tp, unsigned long *clp, - unsigned long cl); -extern int tcf_police(struct sk_buff *skb, struct tcf_police *p); -extern int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st, spinlock_t *lock); -extern void tcf_police_destroy(struct tcf_police *p); -extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est); -extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p); +extern void __qdisc_run(struct net_device *dev); -static inline int tcf_police_release(struct tcf_police *p, int bind) +static inline void qdisc_run(struct net_device *dev) { - int ret = 0; -#ifdef CONFIG_NET_CLS_ACT - if (p) { - if (bind) { - p->bindcnt--; - } - p->refcnt--; - if (p->refcnt <= 0 && !p->bindcnt) { - tcf_police_destroy(p); - ret = 1; - } - } -#else - if (p && --p->refcnt == 0) - tcf_police_destroy(p); - -#endif - return ret; + if (!netif_queue_stopped(dev) && + !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) + __qdisc_run(dev); } -extern struct Qdisc noop_qdisc; -extern struct Qdisc_ops noop_qdisc_ops; -extern struct Qdisc_ops pfifo_qdisc_ops; -extern struct Qdisc_ops bfifo_qdisc_ops; - -int register_qdisc(struct Qdisc_ops *qops); -int unregister_qdisc(struct Qdisc_ops *qops); -struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); -struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); -void dev_init_scheduler(struct net_device *dev); -void dev_shutdown(struct net_device *dev); -void dev_activate(struct net_device *dev); -void dev_deactivate(struct net_device *dev); -void qdisc_reset(struct Qdisc *qdisc); -void qdisc_destroy(struct Qdisc *qdisc); -struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops); -int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct rtattr *opt); -void qdisc_kill_estimator(struct tc_stats *stats); -struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); -void qdisc_put_rtab(struct qdisc_rate_table *tab); - -extern int qdisc_restart(struct net_device *dev); +extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, + struct tcf_result *res); /* Calculate maximal size of packet seen by hard_start_xmit routine of this device.