aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-08-25 23:06:33 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-26 14:01:44 -0400
commited7aa879ce1a0ff6468c5a6d3eb4e31169b95c4a (patch)
treef219143241249dbe1e1fd49ec9d420363ebd8cbe /net/sched
parentfaa54be4c78da6aa2148c539659867afdecd3e8d (diff)
net_sched: convert tcindex to call tcf_exts_destroy from rcu callback
Adjust destroy path of cls_tcindex to call tcf_exts_destroy() after rcu grace period. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/cls_tcindex.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index a557dbaf5afe..944c8ff45055 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -27,6 +27,7 @@
27struct tcindex_filter_result { 27struct tcindex_filter_result {
28 struct tcf_exts exts; 28 struct tcf_exts exts;
29 struct tcf_result res; 29 struct tcf_result res;
30 struct rcu_head rcu;
30}; 31};
31 32
32struct tcindex_filter { 33struct tcindex_filter {
@@ -133,8 +134,23 @@ static int tcindex_init(struct tcf_proto *tp)
133 return 0; 134 return 0;
134} 135}
135 136
136static int 137static void tcindex_destroy_rexts(struct rcu_head *head)
137tcindex_delete(struct tcf_proto *tp, unsigned long arg) 138{
139 struct tcindex_filter_result *r;
140
141 r = container_of(head, struct tcindex_filter_result, rcu);
142 tcf_exts_destroy(&r->exts);
143}
144
145static void tcindex_destroy_fexts(struct rcu_head *head)
146{
147 struct tcindex_filter *f = container_of(head, struct tcindex_filter, rcu);
148
149 tcf_exts_destroy(&f->result.exts);
150 kfree(f);
151}
152
153static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
138{ 154{
139 struct tcindex_data *p = rtnl_dereference(tp->root); 155 struct tcindex_data *p = rtnl_dereference(tp->root);
140 struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; 156 struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
@@ -162,9 +178,14 @@ found:
162 rcu_assign_pointer(*walk, rtnl_dereference(f->next)); 178 rcu_assign_pointer(*walk, rtnl_dereference(f->next));
163 } 179 }
164 tcf_unbind_filter(tp, &r->res); 180 tcf_unbind_filter(tp, &r->res);
165 tcf_exts_destroy(&r->exts); 181 /* all classifiers are required to call tcf_exts_destroy() after rcu
182 * grace period, since converted-to-rcu actions are relying on that
183 * in cleanup() callback
184 */
166 if (f) 185 if (f)
167 kfree_rcu(f, rcu); 186 call_rcu(&f->rcu, tcindex_destroy_fexts);
187 else
188 call_rcu(&r->rcu, tcindex_destroy_rexts);
168 return 0; 189 return 0;
169} 190}
170 191