[MIPS] malta_int.c: make 4 variables static
[safe/jmp/linux-2.6] / net / sched / sch_htb.c
index 512df9a..66148cc 100644 (file)
@@ -609,14 +609,14 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 /* TODO: requeuing packet charges it to policers again !! */
 static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
+       int ret;
        struct htb_sched *q = qdisc_priv(sch);
-       int ret = NET_XMIT_SUCCESS;
        struct htb_class *cl = htb_classify(skb, sch, &ret);
        struct sk_buff *tskb;
 
-       if (cl == HTB_DIRECT || !cl) {
+       if (cl == HTB_DIRECT) {
                /* enqueue to helper queue */
-               if (q->direct_queue.qlen < q->direct_qlen && cl) {
+               if (q->direct_queue.qlen < q->direct_qlen) {
                        __skb_queue_head(&q->direct_queue, skb);
                } else {
                        __skb_queue_head(&q->direct_queue, skb);
@@ -625,6 +625,13 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
                        sch->qstats.drops++;
                        return NET_XMIT_CN;
                }
+#ifdef CONFIG_NET_CLS_ACT
+       } else if (!cl) {
+               if (ret == NET_XMIT_BYPASS)
+                       sch->qstats.drops++;
+               kfree_skb(skb);
+               return ret;
+#endif
        } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) !=
                   NET_XMIT_SUCCESS) {
                sch->qstats.drops++;
@@ -704,9 +711,11 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
  */
 static psched_time_t htb_do_events(struct htb_sched *q, int level)
 {
-       int i;
-
-       for (i = 0; i < 500; i++) {
+       /* don't run for longer than 2 jiffies; 2 is used instead of
+          1 to simplify things when jiffy is going to be incremented
+          too soon */
+       unsigned long stop_at = jiffies + 2;
+       while (time_before(jiffies, stop_at)) {
                struct htb_class *cl;
                long diff;
                struct rb_node *p = rb_first(&q->wait_pq[level]);
@@ -724,9 +733,8 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level)
                if (cl->cmode != HTB_CAN_SEND)
                        htb_add_to_wait_tree(q, cl, diff);
        }
-       if (net_ratelimit())
-               printk(KERN_WARNING "htb: too many events !\n");
-       return q->now + PSCHED_TICKS_PER_SEC / 10;
+       /* too much load - let's continue on next jiffie */
+       return q->now + PSCHED_TICKS_PER_SEC / HZ;
 }
 
 /* Returns class->node+prio from id-tree where classe's id is >= id. NULL
@@ -992,6 +1000,13 @@ static void htb_reset(struct Qdisc *sch)
                INIT_LIST_HEAD(q->drops + i);
 }
 
+static const struct nla_policy htb_policy[TCA_HTB_MAX + 1] = {
+       [TCA_HTB_PARMS] = { .len = sizeof(struct tc_htb_opt) },
+       [TCA_HTB_INIT]  = { .len = sizeof(struct tc_htb_glob) },
+       [TCA_HTB_CTAB]  = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+       [TCA_HTB_RTAB]  = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+};
+
 static int htb_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct htb_sched *q = qdisc_priv(sch);
@@ -1003,12 +1018,11 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
        if (!opt)
                return -EINVAL;
 
-       err = nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL);
+       err = nla_parse_nested(tb, TCA_HTB_INIT, opt, htb_policy);
        if (err < 0)
                return err;
 
-       if (tb[TCA_HTB_INIT] == NULL ||
-           nla_len(tb[TCA_HTB_INIT]) < sizeof(*gopt)) {
+       if (tb[TCA_HTB_INIT] == NULL) {
                printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
                return -EINVAL;
        }
@@ -1043,25 +1057,29 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
 static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct htb_sched *q = qdisc_priv(sch);
-       unsigned char *b = skb_tail_pointer(skb);
-       struct nlattr *nla;
+       struct nlattr *nest;
        struct tc_htb_glob gopt;
+
        spin_lock_bh(&sch->dev->queue_lock);
-       gopt.direct_pkts = q->direct_pkts;
 
+       gopt.direct_pkts = q->direct_pkts;
        gopt.version = HTB_VER;
        gopt.rate2quantum = q->rate2quantum;
        gopt.defcls = q->defcls;
        gopt.debug = 0;
-       nla = (struct nlattr *)b;
-       NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
        NLA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
-       nla->nla_len = skb_tail_pointer(skb) - b;
+       nla_nest_end(skb, nest);
+
        spin_unlock_bh(&sch->dev->queue_lock);
        return skb->len;
+
 nla_put_failure:
        spin_unlock_bh(&sch->dev->queue_lock);
-       nlmsg_trim(skb, skb_tail_pointer(skb));
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1069,8 +1087,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
                          struct sk_buff *skb, struct tcmsg *tcm)
 {
        struct htb_class *cl = (struct htb_class *)arg;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct nlattr *nla;
+       struct nlattr *nest;
        struct tc_htb_opt opt;
 
        spin_lock_bh(&sch->dev->queue_lock);
@@ -1079,8 +1096,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
        if (!cl->level && cl->un.leaf.q)
                tcm->tcm_info = cl->un.leaf.q->handle;
 
-       nla = (struct nlattr *)b;
-       NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        memset(&opt, 0, sizeof(opt));
 
@@ -1092,12 +1110,14 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
        opt.prio = cl->un.leaf.prio;
        opt.level = cl->level;
        NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
-       nla->nla_len = skb_tail_pointer(skb) - b;
+
+       nla_nest_end(skb, nest);
        spin_unlock_bh(&sch->dev->queue_lock);
        return skb->len;
+
 nla_put_failure:
        spin_unlock_bh(&sch->dev->queue_lock);
-       nlmsg_trim(skb, b);
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1313,13 +1333,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
        if (!opt)
                goto failure;
 
-       err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL);
+       err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy);
        if (err < 0)
                goto failure;
 
        err = -EINVAL;
-       if (tb[TCA_HTB_PARMS] == NULL ||
-           nla_len(tb[TCA_HTB_PARMS]) < sizeof(*hopt))
+       if (tb[TCA_HTB_PARMS] == NULL)
                goto failure;
 
        parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch);