Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: sched: remove tcf_proto from ematch calls

This removes the tcf_proto argument from the ematch code paths that
only need it to reference the net namespace. This allows simplifying
qdisc code paths especially when we need to tear down the ematch
from an RCU callback. In this case we can not guarentee that the
tcf_proto structure is still valid.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Cong Wang <cwang@twopensource.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

John Fastabend and committed by
David S. Miller
82a470f1 fcbeb976

+26 -25
+5 -5
include/net/pkt_cls.h
··· 166 166 unsigned int datalen; 167 167 u16 matchid; 168 168 u16 flags; 169 + struct net *net; 169 170 }; 170 171 171 172 static inline int tcf_em_is_container(struct tcf_ematch *em) ··· 230 229 struct tcf_ematch_ops { 231 230 int kind; 232 231 int datalen; 233 - int (*change)(struct tcf_proto *, void *, 232 + int (*change)(struct net *net, void *, 234 233 int, struct tcf_ematch *); 235 234 int (*match)(struct sk_buff *, struct tcf_ematch *, 236 235 struct tcf_pkt_info *); 237 - void (*destroy)(struct tcf_proto *, 238 - struct tcf_ematch *); 236 + void (*destroy)(struct tcf_ematch *); 239 237 int (*dump)(struct sk_buff *, struct tcf_ematch *); 240 238 struct module *owner; 241 239 struct list_head link; ··· 244 244 void tcf_em_unregister(struct tcf_ematch_ops *); 245 245 int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *, 246 246 struct tcf_ematch_tree *); 247 - void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *); 247 + void tcf_em_tree_destroy(struct tcf_ematch_tree *); 248 248 int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int); 249 249 int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *, 250 250 struct tcf_pkt_info *); ··· 301 301 }; 302 302 303 303 #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0) 304 - #define tcf_em_tree_destroy(tp, t) do { (void)(t); } while(0) 304 + #define tcf_em_tree_destroy(t) do { (void)(t); } while(0) 305 305 #define tcf_em_tree_dump(skb, t, tlv) (0) 306 306 #define tcf_em_tree_change(tp, dst, src) do { } while(0) 307 307 #define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
+1 -1
net/sched/cls_basic.c
··· 95 95 96 96 tcf_unbind_filter(tp, &f->res); 97 97 tcf_exts_destroy(&f->exts); 98 - tcf_em_tree_destroy(tp, &f->ematches); 98 + tcf_em_tree_destroy(&f->ematches); 99 99 kfree(f); 100 100 } 101 101
+2 -2
net/sched/cls_cgroup.c
··· 87 87 rcu); 88 88 89 89 tcf_exts_destroy(&head->exts); 90 - tcf_em_tree_destroy(head->tp, &head->ematches); 90 + tcf_em_tree_destroy(&head->ematches); 91 91 kfree(head); 92 92 } 93 93 ··· 157 157 158 158 if (head) { 159 159 tcf_exts_destroy(&head->exts); 160 - tcf_em_tree_destroy(tp, &head->ematches); 160 + tcf_em_tree_destroy(&head->ematches); 161 161 RCU_INIT_POINTER(tp->root, NULL); 162 162 kfree_rcu(head, rcu); 163 163 }
+2 -2
net/sched/cls_flow.c
··· 355 355 356 356 del_timer_sync(&f->perturb_timer); 357 357 tcf_exts_destroy(&f->exts); 358 - tcf_em_tree_destroy(f->tp, &f->ematches); 358 + tcf_em_tree_destroy(&f->ematches); 359 359 kfree(f); 360 360 } 361 361 ··· 530 530 return 0; 531 531 532 532 err2: 533 - tcf_em_tree_destroy(tp, &t); 533 + tcf_em_tree_destroy(&t); 534 534 kfree(fnew); 535 535 err1: 536 536 tcf_exts_destroy(&e);
+2 -2
net/sched/em_canid.c
··· 120 120 return match; 121 121 } 122 122 123 - static int em_canid_change(struct tcf_proto *tp, void *data, int len, 123 + static int em_canid_change(struct net *net, void *data, int len, 124 124 struct tcf_ematch *m) 125 125 { 126 126 struct can_filter *conf = data; /* Array with rules */ ··· 183 183 return 0; 184 184 } 185 185 186 - static void em_canid_destroy(struct tcf_proto *tp, struct tcf_ematch *m) 186 + static void em_canid_destroy(struct tcf_ematch *m) 187 187 { 188 188 struct canid_match *cm = em_canid_priv(m); 189 189
+3 -4
net/sched/em_ipset.c
··· 19 19 #include <net/ip.h> 20 20 #include <net/pkt_cls.h> 21 21 22 - static int em_ipset_change(struct tcf_proto *tp, void *data, int data_len, 22 + static int em_ipset_change(struct net *net, void *data, int data_len, 23 23 struct tcf_ematch *em) 24 24 { 25 25 struct xt_set_info *set = data; 26 26 ip_set_id_t index; 27 - struct net *net = dev_net(qdisc_dev(tp->q)); 28 27 29 28 if (data_len != sizeof(*set)) 30 29 return -EINVAL; ··· 41 42 return -ENOMEM; 42 43 } 43 44 44 - static void em_ipset_destroy(struct tcf_proto *p, struct tcf_ematch *em) 45 + static void em_ipset_destroy(struct tcf_ematch *em) 45 46 { 46 47 const struct xt_set_info *set = (const void *) em->data; 47 48 if (set) { 48 - ip_set_nfnl_put(dev_net(qdisc_dev(p->q)), set->index); 49 + ip_set_nfnl_put(em->net, set->index); 49 50 kfree((void *) em->data); 50 51 } 51 52 }
+2 -2
net/sched/em_meta.c
··· 856 856 [TCA_EM_META_HDR] = { .len = sizeof(struct tcf_meta_hdr) }, 857 857 }; 858 858 859 - static int em_meta_change(struct tcf_proto *tp, void *data, int len, 859 + static int em_meta_change(struct net *net, void *data, int len, 860 860 struct tcf_ematch *m) 861 861 { 862 862 int err; ··· 908 908 return err; 909 909 } 910 910 911 - static void em_meta_destroy(struct tcf_proto *tp, struct tcf_ematch *m) 911 + static void em_meta_destroy(struct tcf_ematch *m) 912 912 { 913 913 if (m) 914 914 meta_delete((struct meta_match *) m->data);
+1 -1
net/sched/em_nbyte.c
··· 23 23 char pattern[0]; 24 24 }; 25 25 26 - static int em_nbyte_change(struct tcf_proto *tp, void *data, int data_len, 26 + static int em_nbyte_change(struct net *net, void *data, int data_len, 27 27 struct tcf_ematch *em) 28 28 { 29 29 struct tcf_em_nbyte *nbyte = data;
+2 -2
net/sched/em_text.c
··· 45 45 return skb_find_text(skb, from, to, tm->config, &state) != UINT_MAX; 46 46 } 47 47 48 - static int em_text_change(struct tcf_proto *tp, void *data, int len, 48 + static int em_text_change(struct net *net, void *data, int len, 49 49 struct tcf_ematch *m) 50 50 { 51 51 struct text_match *tm; ··· 100 100 return 0; 101 101 } 102 102 103 - static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) 103 + static void em_text_destroy(struct tcf_ematch *m) 104 104 { 105 105 if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) 106 106 textsearch_destroy(EM_TEXT_PRIV(m)->config);
+6 -4
net/sched/ematch.c
··· 178 178 struct tcf_ematch_hdr *em_hdr = nla_data(nla); 179 179 int data_len = nla_len(nla) - sizeof(*em_hdr); 180 180 void *data = (void *) em_hdr + sizeof(*em_hdr); 181 + struct net *net = dev_net(qdisc_dev(tp->q)); 181 182 182 183 if (!TCF_EM_REL_VALID(em_hdr->flags)) 183 184 goto errout; ··· 241 240 goto errout; 242 241 243 242 if (em->ops->change) { 244 - err = em->ops->change(tp, data, data_len, em); 243 + err = em->ops->change(net, data, data_len, em); 245 244 if (err < 0) 246 245 goto errout; 247 246 } else if (data_len > 0) { ··· 272 271 em->matchid = em_hdr->matchid; 273 272 em->flags = em_hdr->flags; 274 273 em->datalen = data_len; 274 + em->net = net; 275 275 276 276 err = 0; 277 277 errout: ··· 380 378 return err; 381 379 382 380 errout_abort: 383 - tcf_em_tree_destroy(tp, tree); 381 + tcf_em_tree_destroy(tree); 384 382 return err; 385 383 } 386 384 EXPORT_SYMBOL(tcf_em_tree_validate); ··· 395 393 * tcf_em_tree_validate()/tcf_em_tree_change(). You must ensure that 396 394 * the ematch tree is not in use before calling this function. 397 395 */ 398 - void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree) 396 + void tcf_em_tree_destroy(struct tcf_ematch_tree *tree) 399 397 { 400 398 int i; 401 399 ··· 407 405 408 406 if (em->ops) { 409 407 if (em->ops->destroy) 410 - em->ops->destroy(tp, em); 408 + em->ops->destroy(em); 411 409 else if (!tcf_em_is_simple(em)) 412 410 kfree((void *) em->data); 413 411 module_put(em->ops->owner);