Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[cascardo/linux.git] / net / sched / sch_multiq.c
index afb050a..42dd218 100644 (file)
@@ -31,7 +31,7 @@ struct multiq_sched_data {
        u16 bands;
        u16 max_bands;
        u16 curband;
-       struct tcf_proto *filter_list;
+       struct tcf_proto __rcu *filter_list;
        struct Qdisc **queues;
 };
 
@@ -42,10 +42,11 @@ multiq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
        struct multiq_sched_data *q = qdisc_priv(sch);
        u32 band;
        struct tcf_result res;
+       struct tcf_proto *fl = rcu_dereference_bh(q->filter_list);
        int err;
 
        *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
-       err = tc_classify(skb, q->filter_list, &res);
+       err = tc_classify(skb, fl, &res);
 #ifdef CONFIG_NET_CLS_ACT
        switch (err) {
        case TC_ACT_STOLEN:
@@ -74,7 +75,7 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        if (qdisc == NULL) {
 
                if (ret & __NET_XMIT_BYPASS)
-                       sch->qstats.drops++;
+                       qdisc_qstats_drop(sch);
                kfree_skb(skb);
                return ret;
        }
@@ -86,7 +87,7 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                return NET_XMIT_SUCCESS;
        }
        if (net_xmit_drop_count(ret))
-               sch->qstats.drops++;
+               qdisc_qstats_drop(sch);
        return ret;
 }
 
@@ -359,9 +360,8 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
        struct Qdisc *cl_q;
 
        cl_q = q->queues[cl - 1];
-       cl_q->qstats.qlen = cl_q->q.qlen;
-       if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
-           gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
+       if (gnet_stats_copy_basic(d, NULL, &cl_q->bstats) < 0 ||
+           gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0)
                return -1;
 
        return 0;
@@ -388,7 +388,8 @@ static void multiq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
        }
 }
 
-static struct tcf_proto **multiq_find_tcf(struct Qdisc *sch, unsigned long cl)
+static struct tcf_proto __rcu **multiq_find_tcf(struct Qdisc *sch,
+                                               unsigned long cl)
 {
        struct multiq_sched_data *q = qdisc_priv(sch);