net: rcu-ify tcf_proto
[linux-2.6-microblaze.git] / net / sched / sch_prio.c
index 79359b6..03ef99e 100644 (file)
@@ -24,7 +24,7 @@
 
 struct prio_sched_data {
        int bands;
-       struct tcf_proto *filter_list;
+       struct tcf_proto __rcu *filter_list;
        u8  prio2band[TC_PRIO_MAX+1];
        struct Qdisc *queues[TCQ_PRIO_BANDS];
 };
@@ -36,11 +36,13 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
        struct prio_sched_data *q = qdisc_priv(sch);
        u32 band = skb->priority;
        struct tcf_result res;
+       struct tcf_proto *fl;
        int err;
 
        *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
        if (TC_H_MAJ(skb->priority) != sch->handle) {
-               err = tc_classify(skb, q->filter_list, &res);
+               fl = rcu_dereference_bh(q->filter_list);
+               err = tc_classify(skb, fl, &res);
 #ifdef CONFIG_NET_CLS_ACT
                switch (err) {
                case TC_ACT_STOLEN:
@@ -50,7 +52,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
                        return NULL;
                }
 #endif
-               if (!q->filter_list || err < 0) {
+               if (!fl || err < 0) {
                        if (TC_H_MAJ(band))
                                band = 0;
                        return q->queues[q->prio2band[band & TC_PRIO_MAX]];
@@ -351,7 +353,8 @@ static void prio_walk(struct Qdisc *sch, struct qdisc_walker *arg)
        }
 }
 
-static struct tcf_proto **prio_find_tcf(struct Qdisc *sch, unsigned long cl)
+static struct tcf_proto __rcu **prio_find_tcf(struct Qdisc *sch,
+                                             unsigned long cl)
 {
        struct prio_sched_data *q = qdisc_priv(sch);