aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_choke.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_choke.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_choke.c')
-rw-r--r--net/sched/sch_choke.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index ed30e436128b..74813e6b6ff6 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -57,7 +57,7 @@ struct choke_sched_data {
57 57
58/* Variables */ 58/* Variables */
59 struct red_vars vars; 59 struct red_vars vars;
60 struct tcf_proto *filter_list; 60 struct tcf_proto __rcu *filter_list;
61 struct { 61 struct {
62 u32 prob_drop; /* Early probability drops */ 62 u32 prob_drop; /* Early probability drops */
63 u32 prob_mark; /* Early probability marks */ 63 u32 prob_mark; /* Early probability marks */
@@ -193,9 +193,11 @@ static bool choke_classify(struct sk_buff *skb,
193{ 193{
194 struct choke_sched_data *q = qdisc_priv(sch); 194 struct choke_sched_data *q = qdisc_priv(sch);
195 struct tcf_result res; 195 struct tcf_result res;
196 struct tcf_proto *fl;
196 int result; 197 int result;
197 198
198 result = tc_classify(skb, q->filter_list, &res); 199 fl = rcu_dereference_bh(q->filter_list);
200 result = tc_classify(skb, fl, &res);
199 if (result >= 0) { 201 if (result >= 0) {
200#ifdef CONFIG_NET_CLS_ACT 202#ifdef CONFIG_NET_CLS_ACT
201 switch (result) { 203 switch (result) {
@@ -249,7 +251,7 @@ static bool choke_match_random(const struct choke_sched_data *q,
249 return false; 251 return false;
250 252
251 oskb = choke_peek_random(q, pidx); 253 oskb = choke_peek_random(q, pidx);
252 if (q->filter_list) 254 if (rcu_access_pointer(q->filter_list))
253 return choke_get_classid(nskb) == choke_get_classid(oskb); 255 return choke_get_classid(nskb) == choke_get_classid(oskb);
254 256
255 return choke_match_flow(oskb, nskb); 257 return choke_match_flow(oskb, nskb);
@@ -257,11 +259,11 @@ static bool choke_match_random(const struct choke_sched_data *q,
257 259
258static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch) 260static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)
259{ 261{
262 int ret = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
260 struct choke_sched_data *q = qdisc_priv(sch); 263 struct choke_sched_data *q = qdisc_priv(sch);
261 const struct red_parms *p = &q->parms; 264 const struct red_parms *p = &q->parms;
262 int ret = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
263 265
264 if (q->filter_list) { 266 if (rcu_access_pointer(q->filter_list)) {
265 /* If using external classifiers, get result and record it. */ 267 /* If using external classifiers, get result and record it. */
266 if (!choke_classify(skb, sch, &ret)) 268 if (!choke_classify(skb, sch, &ret))
267 goto other_drop; /* Packet was eaten by filter */ 269 goto other_drop; /* Packet was eaten by filter */
@@ -554,7 +556,8 @@ static unsigned long choke_bind(struct Qdisc *sch, unsigned long parent,
554 return 0; 556 return 0;
555} 557}
556 558
557static struct tcf_proto **choke_find_tcf(struct Qdisc *sch, unsigned long cl) 559static struct tcf_proto __rcu **choke_find_tcf(struct Qdisc *sch,
560 unsigned long cl)
558{ 561{
559 struct choke_sched_data *q = qdisc_priv(sch); 562 struct choke_sched_data *q = qdisc_priv(sch);
560 563