net: sched: extend action ops with put_dev callback
As a preparation for removing dependency on rtnl lock from rules update path, all users of shared objects must take reference while working with them. Extend action ops with put_dev() API to be used on net device returned by get_dev(). Modify mirred action (only action that implements get_dev callback): - Take reference to net device in get_dev. - Implement put_dev API that releases reference to net device. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
764e9a2448
commit
84a75b329b
3 changed files with 13 additions and 1 deletions
|
@ -101,6 +101,7 @@ struct tc_action_ops {
|
|||
void (*stats_update)(struct tc_action *, u64, u32, u64);
|
||||
size_t (*get_fill_size)(const struct tc_action *act);
|
||||
struct net_device *(*get_dev)(const struct tc_action *a);
|
||||
void (*put_dev)(struct net_device *dev);
|
||||
int (*delete)(struct net *net, u32 index);
|
||||
};
|
||||
|
||||
|
|
|
@ -358,8 +358,17 @@ static struct notifier_block mirred_device_notifier = {
|
|||
static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
|
||||
{
|
||||
struct tcf_mirred *m = to_mirred(a);
|
||||
struct net_device *dev = rtnl_dereference(m->tcfm_dev);
|
||||
|
||||
return rtnl_dereference(m->tcfm_dev);
|
||||
if (dev)
|
||||
dev_hold(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void tcf_mirred_put_dev(struct net_device *dev)
|
||||
{
|
||||
dev_put(dev);
|
||||
}
|
||||
|
||||
static int tcf_mirred_delete(struct net *net, u32 index)
|
||||
|
@ -382,6 +391,7 @@ static struct tc_action_ops act_mirred_ops = {
|
|||
.lookup = tcf_mirred_search,
|
||||
.size = sizeof(struct tcf_mirred),
|
||||
.get_dev = tcf_mirred_get_dev,
|
||||
.put_dev = tcf_mirred_put_dev,
|
||||
.delete = tcf_mirred_delete,
|
||||
};
|
||||
|
||||
|
|
|
@ -2176,6 +2176,7 @@ static int tc_exts_setup_cb_egdev_call(struct tcf_exts *exts,
|
|||
if (!dev)
|
||||
continue;
|
||||
ret = tc_setup_cb_egdev_call(dev, type, type_data, err_stop);
|
||||
a->ops->put_dev(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ok_count += ret;
|
||||
|
|
Loading…
Reference in a new issue