aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_fq_codel.c
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2014-09-12 23:05:27 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-13 12:30:25 -0400
commit25d8c0d55f241ce2d360df1bea48e23a55836ee6 (patch)
treec0aca67607e7ce560a4a2cebef5fb6d55adf4112 /net/sched/sch_fq_codel.c
parent46e5da40aec256155cfedee96dd21a75da941f2c (diff)
net: rcu-ify tcf_proto
rcu'ify tcf_proto this allows calling tc_classify() without holding any locks. Updaters are protected by RTNL. This patch prepares the core net_sched infrastracture for running the classifier/action chains without holding the qdisc lock however it does nothing to ensure cls_xxx and act_xxx types also work without locking. Additional patches are required to address the fall out. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_fq_codel.c')
-rw-r--r--net/sched/sch_fq_codel.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index cc56c8bb9bed..105cf5557630 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -52,7 +52,7 @@ struct fq_codel_flow {
52}; /* please try to keep this structure <= 64 bytes */ 52}; /* please try to keep this structure <= 64 bytes */
53 53
54struct fq_codel_sched_data { 54struct fq_codel_sched_data {
55 struct tcf_proto *filter_list; /* optional external classifier */ 55 struct tcf_proto __rcu *filter_list; /* optional external classifier */
56 struct fq_codel_flow *flows; /* Flows table [flows_cnt] */ 56 struct fq_codel_flow *flows; /* Flows table [flows_cnt] */
57 u32 *backlogs; /* backlog table [flows_cnt] */ 57 u32 *backlogs; /* backlog table [flows_cnt] */
58 u32 flows_cnt; /* number of flows */ 58 u32 flows_cnt; /* number of flows */
@@ -85,6 +85,7 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch,
85 int *qerr) 85 int *qerr)
86{ 86{
87 struct fq_codel_sched_data *q = qdisc_priv(sch); 87 struct fq_codel_sched_data *q = qdisc_priv(sch);
88 struct tcf_proto *filter;
88 struct tcf_result res; 89 struct tcf_result res;
89 int result; 90 int result;
90 91
@@ -93,11 +94,12 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch,
93 TC_H_MIN(skb->priority) <= q->flows_cnt) 94 TC_H_MIN(skb->priority) <= q->flows_cnt)
94 return TC_H_MIN(skb->priority); 95 return TC_H_MIN(skb->priority);
95 96
96 if (!q->filter_list) 97 filter = rcu_dereference(q->filter_list);
98 if (!filter)
97 return fq_codel_hash(q, skb) + 1; 99 return fq_codel_hash(q, skb) + 1;
98 100
99 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; 101 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
100 result = tc_classify(skb, q->filter_list, &res); 102 result = tc_classify(skb, filter, &res);
101 if (result >= 0) { 103 if (result >= 0) {
102#ifdef CONFIG_NET_CLS_ACT 104#ifdef CONFIG_NET_CLS_ACT
103 switch (result) { 105 switch (result) {
@@ -496,7 +498,8 @@ static void fq_codel_put(struct Qdisc *q, unsigned long cl)
496{ 498{
497} 499}
498 500
499static struct tcf_proto **fq_codel_find_tcf(struct Qdisc *sch, unsigned long cl) 501static struct tcf_proto __rcu **fq_codel_find_tcf(struct Qdisc *sch,
502 unsigned long cl)
500{ 503{
501 struct fq_codel_sched_data *q = qdisc_priv(sch); 504 struct fq_codel_sched_data *q = qdisc_priv(sch);
502 505