Commit ada066b2 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski

net: sched: act_mirred: add net device refcount tracker

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e7c8ab84
...@@ -10,6 +10,7 @@ struct tcf_mirred { ...@@ -10,6 +10,7 @@ struct tcf_mirred {
int tcfm_eaction; int tcfm_eaction;
bool tcfm_mac_header_xmit; bool tcfm_mac_header_xmit;
struct net_device __rcu *tcfm_dev; struct net_device __rcu *tcfm_dev;
netdevice_tracker tcfm_dev_tracker;
struct list_head tcfm_list; struct list_head tcfm_list;
}; };
#define to_mirred(a) ((struct tcf_mirred *)a) #define to_mirred(a) ((struct tcf_mirred *)a)
......
...@@ -79,7 +79,7 @@ static void tcf_mirred_release(struct tc_action *a) ...@@ -79,7 +79,7 @@ static void tcf_mirred_release(struct tc_action *a)
/* last reference to action, no need to lock */ /* last reference to action, no need to lock */
dev = rcu_dereference_protected(m->tcfm_dev, 1); dev = rcu_dereference_protected(m->tcfm_dev, 1);
dev_put(dev); dev_put_track(dev, &m->tcfm_dev_tracker);
} }
static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = { static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
...@@ -101,7 +101,6 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, ...@@ -101,7 +101,6 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
bool mac_header_xmit = false; bool mac_header_xmit = false;
struct tc_mirred *parm; struct tc_mirred *parm;
struct tcf_mirred *m; struct tcf_mirred *m;
struct net_device *dev;
bool exists = false; bool exists = false;
int ret, err; int ret, err;
u32 index; u32 index;
...@@ -171,16 +170,19 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, ...@@ -171,16 +170,19 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
spin_lock_bh(&m->tcf_lock); spin_lock_bh(&m->tcf_lock);
if (parm->ifindex) { if (parm->ifindex) {
dev = dev_get_by_index(net, parm->ifindex); struct net_device *odev, *ndev;
if (!dev) {
ndev = dev_get_by_index(net, parm->ifindex);
if (!ndev) {
spin_unlock_bh(&m->tcf_lock); spin_unlock_bh(&m->tcf_lock);
err = -ENODEV; err = -ENODEV;
goto put_chain; goto put_chain;
} }
mac_header_xmit = dev_is_mac_header_xmit(dev); mac_header_xmit = dev_is_mac_header_xmit(ndev);
dev = rcu_replace_pointer(m->tcfm_dev, dev, odev = rcu_replace_pointer(m->tcfm_dev, ndev,
lockdep_is_held(&m->tcf_lock)); lockdep_is_held(&m->tcf_lock));
dev_put(dev); dev_put_track(odev, &m->tcfm_dev_tracker);
netdev_tracker_alloc(ndev, &m->tcfm_dev_tracker, GFP_ATOMIC);
m->tcfm_mac_header_xmit = mac_header_xmit; m->tcfm_mac_header_xmit = mac_header_xmit;
} }
goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
...@@ -400,7 +402,7 @@ static int mirred_device_event(struct notifier_block *unused, ...@@ -400,7 +402,7 @@ static int mirred_device_event(struct notifier_block *unused,
list_for_each_entry(m, &mirred_list, tcfm_list) { list_for_each_entry(m, &mirred_list, tcfm_list) {
spin_lock_bh(&m->tcf_lock); spin_lock_bh(&m->tcf_lock);
if (tcf_mirred_dev_dereference(m) == dev) { if (tcf_mirred_dev_dereference(m) == dev) {
dev_put(dev); dev_put_track(dev, &m->tcfm_dev_tracker);
/* Note : no rcu grace period necessary, as /* Note : no rcu grace period necessary, as
* net_device are already rcu protected. * net_device are already rcu protected.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment