Commit 036bb443 authored by Vlad Buslov's avatar Vlad Buslov Committed by David S. Miller

net: sched: change type of reference and bind counters

Change type of action reference counter to refcount_t.

Change type of action bind counter to atomic_t.
This type is used to allow decrementing bind counter without testing
for 0 result.
Reviewed-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarVlad Buslov <vladbu@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eec94fdb
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Public action API for classifiers/qdiscs * Public action API for classifiers/qdiscs
*/ */
#include <linux/refcount.h>
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
...@@ -26,8 +27,8 @@ struct tc_action { ...@@ -26,8 +27,8 @@ struct tc_action {
struct tcf_idrinfo *idrinfo; struct tcf_idrinfo *idrinfo;
u32 tcfa_index; u32 tcfa_index;
int tcfa_refcnt; refcount_t tcfa_refcnt;
int tcfa_bindcnt; atomic_t tcfa_bindcnt;
u32 tcfa_capab; u32 tcfa_capab;
int tcfa_action; int tcfa_action;
struct tcf_t tcfa_tm; struct tcf_t tcfa_tm;
......
...@@ -105,14 +105,26 @@ int __tcf_idr_release(struct tc_action *p, bool bind, bool strict) ...@@ -105,14 +105,26 @@ int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)
ASSERT_RTNL(); ASSERT_RTNL();
/* Release with strict==1 and bind==0 is only called through act API
* interface (classifiers always bind). Only case when action with
* positive reference count and zero bind count can exist is when it was
* also created with act API (unbinding last classifier will destroy the
* action if it was created by classifier). So only case when bind count
* can be changed after initial check is when unbound action is
* destroyed by act API while classifier binds to action with same id
* concurrently. This result either creation of new action(same behavior
* as before), or reusing existing action if concurrent process
* increments reference count before action is deleted. Both scenarios
* are acceptable.
*/
if (p) { if (p) {
if (bind) if (bind)
p->tcfa_bindcnt--; atomic_dec(&p->tcfa_bindcnt);
else if (strict && p->tcfa_bindcnt > 0) else if (strict && atomic_read(&p->tcfa_bindcnt) > 0)
return -EPERM; return -EPERM;
p->tcfa_refcnt--; if (atomic_read(&p->tcfa_bindcnt) <= 0 &&
if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) { refcount_dec_and_test(&p->tcfa_refcnt)) {
if (p->ops->cleanup) if (p->ops->cleanup)
p->ops->cleanup(p); p->ops->cleanup(p);
tcf_idr_remove(p->idrinfo, p); tcf_idr_remove(p->idrinfo, p);
...@@ -304,8 +316,8 @@ bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a, ...@@ -304,8 +316,8 @@ bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
if (index && p) { if (index && p) {
if (bind) if (bind)
p->tcfa_bindcnt++; atomic_inc(&p->tcfa_bindcnt);
p->tcfa_refcnt++; refcount_inc(&p->tcfa_refcnt);
*a = p; *a = p;
return true; return true;
} }
...@@ -324,9 +336,9 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, ...@@ -324,9 +336,9 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
if (unlikely(!p)) if (unlikely(!p))
return -ENOMEM; return -ENOMEM;
p->tcfa_refcnt = 1; refcount_set(&p->tcfa_refcnt, 1);
if (bind) if (bind)
p->tcfa_bindcnt = 1; atomic_set(&p->tcfa_bindcnt, 1);
if (cpustats) { if (cpustats) {
p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
...@@ -782,7 +794,7 @@ static void cleanup_a(struct list_head *actions, int ovr) ...@@ -782,7 +794,7 @@ static void cleanup_a(struct list_head *actions, int ovr)
return; return;
list_for_each_entry(a, actions, list) list_for_each_entry(a, actions, list)
a->tcfa_refcnt--; refcount_dec(&a->tcfa_refcnt);
} }
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
...@@ -810,7 +822,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, ...@@ -810,7 +822,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
act->order = i; act->order = i;
sz += tcf_action_fill_size(act); sz += tcf_action_fill_size(act);
if (ovr) if (ovr)
act->tcfa_refcnt++; refcount_inc(&act->tcfa_refcnt);
list_add_tail(&act->list, actions); list_add_tail(&act->list, actions);
} }
......
...@@ -141,8 +141,8 @@ static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act, ...@@ -141,8 +141,8 @@ static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act,
struct tcf_bpf *prog = to_bpf(act); struct tcf_bpf *prog = to_bpf(act);
struct tc_act_bpf opt = { struct tc_act_bpf opt = {
.index = prog->tcf_index, .index = prog->tcf_index,
.refcnt = prog->tcf_refcnt - ref, .refcnt = refcount_read(&prog->tcf_refcnt) - ref,
.bindcnt = prog->tcf_bindcnt - bind, .bindcnt = atomic_read(&prog->tcf_bindcnt) - bind,
.action = prog->tcf_action, .action = prog->tcf_action,
}; };
struct tcf_t tm; struct tcf_t tm;
......
...@@ -154,8 +154,8 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -154,8 +154,8 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
struct tc_connmark opt = { struct tc_connmark opt = {
.index = ci->tcf_index, .index = ci->tcf_index,
.refcnt = ci->tcf_refcnt - ref, .refcnt = refcount_read(&ci->tcf_refcnt) - ref,
.bindcnt = ci->tcf_bindcnt - bind, .bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
.action = ci->tcf_action, .action = ci->tcf_action,
.zone = ci->zone, .zone = ci->zone,
}; };
......
...@@ -597,8 +597,8 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind, ...@@ -597,8 +597,8 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
struct tcf_csum_params *params; struct tcf_csum_params *params;
struct tc_csum opt = { struct tc_csum opt = {
.index = p->tcf_index, .index = p->tcf_index,
.refcnt = p->tcf_refcnt - ref, .refcnt = refcount_read(&p->tcf_refcnt) - ref,
.bindcnt = p->tcf_bindcnt - bind, .bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -169,8 +169,8 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -169,8 +169,8 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_gact *gact = to_gact(a); struct tcf_gact *gact = to_gact(a);
struct tc_gact opt = { struct tc_gact opt = {
.index = gact->tcf_index, .index = gact->tcf_index,
.refcnt = gact->tcf_refcnt - ref, .refcnt = refcount_read(&gact->tcf_refcnt) - ref,
.bindcnt = gact->tcf_bindcnt - bind, .bindcnt = atomic_read(&gact->tcf_bindcnt) - bind,
.action = gact->tcf_action, .action = gact->tcf_action,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -596,8 +596,8 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind, ...@@ -596,8 +596,8 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind,
struct tcf_ife_params *p = rtnl_dereference(ife->params); struct tcf_ife_params *p = rtnl_dereference(ife->params);
struct tc_ife opt = { struct tc_ife opt = {
.index = ife->tcf_index, .index = ife->tcf_index,
.refcnt = ife->tcf_refcnt - ref, .refcnt = refcount_read(&ife->tcf_refcnt) - ref,
.bindcnt = ife->tcf_bindcnt - bind, .bindcnt = atomic_read(&ife->tcf_bindcnt) - bind,
.action = ife->tcf_action, .action = ife->tcf_action,
.flags = p->flags, .flags = p->flags,
}; };
......
...@@ -280,8 +280,8 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, ...@@ -280,8 +280,8 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind,
if (unlikely(!t)) if (unlikely(!t))
goto nla_put_failure; goto nla_put_failure;
c.bindcnt = ipt->tcf_bindcnt - bind; c.bindcnt = atomic_read(&ipt->tcf_bindcnt) - bind;
c.refcnt = ipt->tcf_refcnt - ref; c.refcnt = refcount_read(&ipt->tcf_refcnt) - ref;
strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name); strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
if (nla_put(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t) || if (nla_put(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t) ||
......
...@@ -250,8 +250,8 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, ...@@ -250,8 +250,8 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
struct tc_mirred opt = { struct tc_mirred opt = {
.index = m->tcf_index, .index = m->tcf_index,
.action = m->tcf_action, .action = m->tcf_action,
.refcnt = m->tcf_refcnt - ref, .refcnt = refcount_read(&m->tcf_refcnt) - ref,
.bindcnt = m->tcf_bindcnt - bind, .bindcnt = atomic_read(&m->tcf_bindcnt) - bind,
.eaction = m->tcfm_eaction, .eaction = m->tcfm_eaction,
.ifindex = dev ? dev->ifindex : 0, .ifindex = dev ? dev->ifindex : 0,
}; };
......
...@@ -257,8 +257,8 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -257,8 +257,8 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
.index = p->tcf_index, .index = p->tcf_index,
.action = p->tcf_action, .action = p->tcf_action,
.refcnt = p->tcf_refcnt - ref, .refcnt = refcount_read(&p->tcf_refcnt) - ref,
.bindcnt = p->tcf_bindcnt - bind, .bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -409,8 +409,8 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -409,8 +409,8 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
opt->nkeys = p->tcfp_nkeys; opt->nkeys = p->tcfp_nkeys;
opt->flags = p->tcfp_flags; opt->flags = p->tcfp_flags;
opt->action = p->tcf_action; opt->action = p->tcf_action;
opt->refcnt = p->tcf_refcnt - ref; opt->refcnt = refcount_read(&p->tcf_refcnt) - ref;
opt->bindcnt = p->tcf_bindcnt - bind; opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind;
if (p->tcfp_keys_ex) { if (p->tcfp_keys_ex) {
tcf_pedit_key_ex_dump(skb, p->tcfp_keys_ex, p->tcfp_nkeys); tcf_pedit_key_ex_dump(skb, p->tcfp_keys_ex, p->tcfp_nkeys);
......
...@@ -274,8 +274,8 @@ static int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -274,8 +274,8 @@ static int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a,
.action = police->tcf_action, .action = police->tcf_action,
.mtu = police->tcfp_mtu, .mtu = police->tcfp_mtu,
.burst = PSCHED_NS2TICKS(police->tcfp_burst), .burst = PSCHED_NS2TICKS(police->tcfp_burst),
.refcnt = police->tcf_refcnt - ref, .refcnt = refcount_read(&police->tcf_refcnt) - ref,
.bindcnt = police->tcf_bindcnt - bind, .bindcnt = atomic_read(&police->tcf_bindcnt) - bind,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -173,8 +173,8 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -173,8 +173,8 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
struct tc_sample opt = { struct tc_sample opt = {
.index = s->tcf_index, .index = s->tcf_index,
.action = s->tcf_action, .action = s->tcf_action,
.refcnt = s->tcf_refcnt - ref, .refcnt = refcount_read(&s->tcf_refcnt) - ref,
.bindcnt = s->tcf_bindcnt - bind, .bindcnt = atomic_read(&s->tcf_bindcnt) - bind,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -145,8 +145,8 @@ static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -145,8 +145,8 @@ static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_defact *d = to_defact(a); struct tcf_defact *d = to_defact(a);
struct tc_defact opt = { struct tc_defact opt = {
.index = d->tcf_index, .index = d->tcf_index,
.refcnt = d->tcf_refcnt - ref, .refcnt = refcount_read(&d->tcf_refcnt) - ref,
.bindcnt = d->tcf_bindcnt - bind, .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
.action = d->tcf_action, .action = d->tcf_action,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -208,8 +208,8 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -208,8 +208,8 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_skbedit *d = to_skbedit(a); struct tcf_skbedit *d = to_skbedit(a);
struct tc_skbedit opt = { struct tc_skbedit opt = {
.index = d->tcf_index, .index = d->tcf_index,
.refcnt = d->tcf_refcnt - ref, .refcnt = refcount_read(&d->tcf_refcnt) - ref,
.bindcnt = d->tcf_bindcnt - bind, .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
.action = d->tcf_action, .action = d->tcf_action,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -205,8 +205,8 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -205,8 +205,8 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_skbmod_params *p = rtnl_dereference(d->skbmod_p); struct tcf_skbmod_params *p = rtnl_dereference(d->skbmod_p);
struct tc_skbmod opt = { struct tc_skbmod opt = {
.index = d->tcf_index, .index = d->tcf_index,
.refcnt = d->tcf_refcnt - ref, .refcnt = refcount_read(&d->tcf_refcnt) - ref,
.bindcnt = d->tcf_bindcnt - bind, .bindcnt = atomic_read(&d->tcf_bindcnt) - bind,
.action = d->tcf_action, .action = d->tcf_action,
}; };
struct tcf_t t; struct tcf_t t;
......
...@@ -474,8 +474,8 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -474,8 +474,8 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_tunnel_key_params *params; struct tcf_tunnel_key_params *params;
struct tc_tunnel_key opt = { struct tc_tunnel_key opt = {
.index = t->tcf_index, .index = t->tcf_index,
.refcnt = t->tcf_refcnt - ref, .refcnt = refcount_read(&t->tcf_refcnt) - ref,
.bindcnt = t->tcf_bindcnt - bind, .bindcnt = atomic_read(&t->tcf_bindcnt) - bind,
}; };
struct tcf_t tm; struct tcf_t tm;
......
...@@ -239,8 +239,8 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -239,8 +239,8 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
struct tcf_vlan_params *p = rtnl_dereference(v->vlan_p); struct tcf_vlan_params *p = rtnl_dereference(v->vlan_p);
struct tc_vlan opt = { struct tc_vlan opt = {
.index = v->tcf_index, .index = v->tcf_index,
.refcnt = v->tcf_refcnt - ref, .refcnt = refcount_read(&v->tcf_refcnt) - ref,
.bindcnt = v->tcf_bindcnt - bind, .bindcnt = atomic_read(&v->tcf_bindcnt) - bind,
.action = v->tcf_action, .action = v->tcf_action,
.v_action = p->tcfv_action, .v_action = p->tcfv_action,
}; };
......
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