Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-drm-fsl-dcu.git] / net / sched / sch_api.c
index a19eff12cf78b9013d66f070153c869f8242b151..60b92fcdc8bbd5df0782769049d3671670eb3052 100644 (file)
@@ -191,21 +191,27 @@ int unregister_qdisc(struct Qdisc_ops *qops)
    (root qdisc, all its children, children of children etc.)
  */
 
-struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
+static struct Qdisc *__qdisc_lookup(struct net_device *dev, u32 handle)
 {
        struct Qdisc *q;
 
-       read_lock_bh(&qdisc_tree_lock);
        list_for_each_entry(q, &dev->qdisc_list, list) {
-               if (q->handle == handle) {
-                       read_unlock_bh(&qdisc_tree_lock);
+               if (q->handle == handle)
                        return q;
-               }
        }
-       read_unlock_bh(&qdisc_tree_lock);
        return NULL;
 }
 
+struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
+{
+       struct Qdisc *q;
+
+       read_lock(&qdisc_tree_lock);
+       q = __qdisc_lookup(dev, handle);
+       read_unlock(&qdisc_tree_lock);
+       return q;
+}
+
 static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
 {
        unsigned long cl;
@@ -348,6 +354,26 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc)
        return oqdisc;
 }
 
+void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
+{
+       struct Qdisc_class_ops *cops;
+       unsigned long cl;
+       u32 parentid;
+
+       if (n == 0)
+               return;
+       while ((parentid = sch->parent)) {
+               sch = __qdisc_lookup(sch->dev, TC_H_MAJ(parentid));
+               cops = sch->ops->cl_ops;
+               if (cops->qlen_notify) {
+                       cl = cops->get(sch, parentid);
+                       cops->qlen_notify(sch, cl);
+                       cops->put(sch, cl);
+               }
+               sch->q.qlen -= n;
+       }
+}
+EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
 
 /* Graft qdisc "new" to class "classid" of qdisc "parent" or
    to device "dev".
@@ -363,7 +389,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
        struct Qdisc *q = *old;
 
 
-       if (parent == NULL) { 
+       if (parent == NULL) {
                if (q && q->flags&TCQ_F_INGRESS) {
                        *old = dev_graft_qdisc(dev, q);
                } else {
@@ -570,7 +596,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                                q = qdisc_leaf(p, clid);
                        } else { /* ingress */
                                q = dev->qdisc_ingress;
-                        }
+                       }
                } else {
                        q = dev->qdisc_sleeping;
                }
@@ -717,7 +743,7 @@ create_n_graft:
                return -ENOENT;
        if (clid == TC_H_INGRESS)
                q = qdisc_create(dev, tcm->tcm_parent, tca, &err);
-        else
+       else
                q = qdisc_create(dev, tcm->tcm_handle, tca, &err);
        if (q == NULL) {
                if (err == -EAGAIN)
@@ -782,10 +808,10 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
 #endif
            gnet_stats_copy_queue(&d, &q->qstats) < 0)
                goto rtattr_failure;
-       
+
        if (gnet_stats_finish_copy(&d) < 0)
                goto rtattr_failure;
-       
+
        nlh->nlmsg_len = skb->tail - b;
        return skb->len;
 
@@ -837,7 +863,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
                if (idx > s_idx)
                        s_q_idx = 0;
-               read_lock_bh(&qdisc_tree_lock);
+               read_lock(&qdisc_tree_lock);
                q_idx = 0;
                list_for_each_entry(q, &dev->qdisc_list, list) {
                        if (q_idx < s_q_idx) {
@@ -846,12 +872,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
                        }
                        if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
                                          cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
-                               read_unlock_bh(&qdisc_tree_lock);
+                               read_unlock(&qdisc_tree_lock);
                                goto done;
                        }
                        q_idx++;
                }
-               read_unlock_bh(&qdisc_tree_lock);
+               read_unlock(&qdisc_tree_lock);
        }
 
 done:
@@ -928,7 +954,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        }
 
        /* OK. Locate qdisc */
-       if ((q = qdisc_lookup(dev, qid)) == NULL) 
+       if ((q = qdisc_lookup(dev, qid)) == NULL)
                return -ENOENT;
 
        /* An check that it supports classes */
@@ -952,7 +978,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                        goto out;
        } else {
                switch (n->nlmsg_type) {
-               case RTM_NEWTCLASS:     
+               case RTM_NEWTCLASS:
                        err = -EEXIST;
                        if (n->nlmsg_flags&NLM_F_EXCL)
                                goto out;
@@ -1074,7 +1100,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
        s_t = cb->args[0];
        t = 0;
 
-       read_lock_bh(&qdisc_tree_lock);
+       read_lock(&qdisc_tree_lock);
        list_for_each_entry(q, &dev->qdisc_list, list) {
                if (t < s_t || !q->ops->cl_ops ||
                    (tcm->tcm_parent &&
@@ -1096,7 +1122,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
                        break;
                t++;
        }
-       read_unlock_bh(&qdisc_tree_lock);
+       read_unlock(&qdisc_tree_lock);
 
        cb->args[0] = t;
 
@@ -1112,7 +1138,7 @@ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
        struct tcf_result *res)
 {
        int err = 0;
-       u32 protocol = skb->protocol;
+       __be16 protocol = skb->protocol;
 #ifdef CONFIG_NET_CLS_ACT
        struct tcf_proto *otp = tp;
 reclassify:
@@ -1136,7 +1162,7 @@ reclassify:
                                skb->tc_verd = SET_TC_VERD(skb->tc_verd,verd);
                                goto reclassify;
                        } else {
-                               if (skb->tc_verd) 
+                               if (skb->tc_verd)
                                        skb->tc_verd = SET_TC_VERD(skb->tc_verd,0);
                                return err;
                        }
@@ -1174,7 +1200,7 @@ static struct file_operations psched_fops = {
        .read  = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
-};     
+};
 #endif
 
 #ifdef CONFIG_NET_SCH_CLK_CPU
@@ -1277,7 +1303,6 @@ static int __init pktsched_init(void)
 
 subsys_initcall(pktsched_init);
 
-EXPORT_SYMBOL(qdisc_lookup);
 EXPORT_SYMBOL(qdisc_get_rtab);
 EXPORT_SYMBOL(qdisc_put_rtab);
 EXPORT_SYMBOL(register_qdisc);