diff options
author | Vlad Buslov <vladbu@mellanox.com> | 2019-09-13 11:28:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-16 03:18:03 -0400 |
commit | 470d5060e6b3b8fae47d944601855e9ece7a2470 (patch) | |
tree | b91a0dfb567b5ed2878d5543014a65196f7fe7ae | |
parent | 4a5da47d5cb6aba3c26a5cc0dddfb2d577e851e9 (diff) |
net: sched: use get_dev() action API in flow_action infra
When filling in hardware intermediate representation tc_setup_flow_action()
directly obtains, checks and takes reference to dev used by mirred action,
instead of using act->ops->get_dev() API created specifically for this
purpose. In order to remove code duplication, refactor flow_action infra to
use action API when obtaining mirred action target dev. Extend get_dev()
with additional argument that is used to provide dev destructor to the
user.
Fixes: 5a6ff4b13d59 ("net: sched: take reference to action dev before calling offloads")
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/act_api.h | 4 | ||||
-rw-r--r-- | net/sched/act_mirred.c | 21 | ||||
-rw-r--r-- | net/sched/cls_api.c | 13 |
3 files changed, 18 insertions, 20 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index 4be8b0daedf0..b18c699681ca 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h | |||
@@ -101,8 +101,8 @@ struct tc_action_ops { | |||
101 | struct netlink_ext_ack *); | 101 | struct netlink_ext_ack *); |
102 | void (*stats_update)(struct tc_action *, u64, u32, u64, bool); | 102 | void (*stats_update)(struct tc_action *, u64, u32, u64, bool); |
103 | size_t (*get_fill_size)(const struct tc_action *act); | 103 | size_t (*get_fill_size)(const struct tc_action *act); |
104 | struct net_device *(*get_dev)(const struct tc_action *a); | 104 | struct net_device *(*get_dev)(const struct tc_action *a, |
105 | void (*put_dev)(struct net_device *dev); | 105 | tc_action_priv_destructor *destructor); |
106 | struct psample_group * | 106 | struct psample_group * |
107 | (*get_psample_group)(const struct tc_action *a, | 107 | (*get_psample_group)(const struct tc_action *a, |
108 | tc_action_priv_destructor *destructor); | 108 | tc_action_priv_destructor *destructor); |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9d1bf508075a..9ce073a05414 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -408,25 +408,31 @@ static struct notifier_block mirred_device_notifier = { | |||
408 | .notifier_call = mirred_device_event, | 408 | .notifier_call = mirred_device_event, |
409 | }; | 409 | }; |
410 | 410 | ||
411 | static struct net_device *tcf_mirred_get_dev(const struct tc_action *a) | 411 | static void tcf_mirred_dev_put(void *priv) |
412 | { | ||
413 | struct net_device *dev = priv; | ||
414 | |||
415 | dev_put(dev); | ||
416 | } | ||
417 | |||
418 | static struct net_device * | ||
419 | tcf_mirred_get_dev(const struct tc_action *a, | ||
420 | tc_action_priv_destructor *destructor) | ||
412 | { | 421 | { |
413 | struct tcf_mirred *m = to_mirred(a); | 422 | struct tcf_mirred *m = to_mirred(a); |
414 | struct net_device *dev; | 423 | struct net_device *dev; |
415 | 424 | ||
416 | rcu_read_lock(); | 425 | rcu_read_lock(); |
417 | dev = rcu_dereference(m->tcfm_dev); | 426 | dev = rcu_dereference(m->tcfm_dev); |
418 | if (dev) | 427 | if (dev) { |
419 | dev_hold(dev); | 428 | dev_hold(dev); |
429 | *destructor = tcf_mirred_dev_put; | ||
430 | } | ||
420 | rcu_read_unlock(); | 431 | rcu_read_unlock(); |
421 | 432 | ||
422 | return dev; | 433 | return dev; |
423 | } | 434 | } |
424 | 435 | ||
425 | static void tcf_mirred_put_dev(struct net_device *dev) | ||
426 | { | ||
427 | dev_put(dev); | ||
428 | } | ||
429 | |||
430 | static size_t tcf_mirred_get_fill_size(const struct tc_action *act) | 436 | static size_t tcf_mirred_get_fill_size(const struct tc_action *act) |
431 | { | 437 | { |
432 | return nla_total_size(sizeof(struct tc_mirred)); | 438 | return nla_total_size(sizeof(struct tc_mirred)); |
@@ -446,7 +452,6 @@ static struct tc_action_ops act_mirred_ops = { | |||
446 | .get_fill_size = tcf_mirred_get_fill_size, | 452 | .get_fill_size = tcf_mirred_get_fill_size, |
447 | .size = sizeof(struct tcf_mirred), | 453 | .size = sizeof(struct tcf_mirred), |
448 | .get_dev = tcf_mirred_get_dev, | 454 | .get_dev = tcf_mirred_get_dev, |
449 | .put_dev = tcf_mirred_put_dev, | ||
450 | }; | 455 | }; |
451 | 456 | ||
452 | static __net_init int mirred_init_net(struct net *net) | 457 | static __net_init int mirred_init_net(struct net *net) |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 60d44b14750a..32577c248968 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -3288,22 +3288,15 @@ void tc_cleanup_flow_action(struct flow_action *flow_action) | |||
3288 | } | 3288 | } |
3289 | EXPORT_SYMBOL(tc_cleanup_flow_action); | 3289 | EXPORT_SYMBOL(tc_cleanup_flow_action); |
3290 | 3290 | ||
3291 | static void tcf_mirred_put_dev(void *priv) | ||
3292 | { | ||
3293 | struct net_device *dev = priv; | ||
3294 | |||
3295 | dev_put(dev); | ||
3296 | } | ||
3297 | |||
3298 | static void tcf_mirred_get_dev(struct flow_action_entry *entry, | 3291 | static void tcf_mirred_get_dev(struct flow_action_entry *entry, |
3299 | const struct tc_action *act) | 3292 | const struct tc_action *act) |
3300 | { | 3293 | { |
3301 | entry->dev = tcf_mirred_dev(act); | 3294 | #ifdef CONFIG_NET_CLS_ACT |
3295 | entry->dev = act->ops->get_dev(act, &entry->destructor); | ||
3302 | if (!entry->dev) | 3296 | if (!entry->dev) |
3303 | return; | 3297 | return; |
3304 | dev_hold(entry->dev); | ||
3305 | entry->destructor = tcf_mirred_put_dev; | ||
3306 | entry->destructor_priv = entry->dev; | 3298 | entry->destructor_priv = entry->dev; |
3299 | #endif | ||
3307 | } | 3300 | } |
3308 | 3301 | ||
3309 | static void tcf_tunnel_encap_put_tunnel(void *priv) | 3302 | static void tcf_tunnel_encap_put_tunnel(void *priv) |