Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 * Public action API for classifiers/qdiscs
*/

#include <linux/refcount.h>
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
@@ -26,8 +27,8 @@ struct tc_action {
	struct tcf_idrinfo		*idrinfo;

	u32				tcfa_index;
	int				tcfa_refcnt;
	int				tcfa_bindcnt;
	refcount_t			tcfa_refcnt;
	atomic_t			tcfa_bindcnt;
	u32				tcfa_capab;
	int				tcfa_action;
	struct tcf_t			tcfa_tm;
+22 −10
Original line number Diff line number Diff line
@@ -105,14 +105,26 @@ int __tcf_idr_release(struct tc_action *p, bool bind, bool strict)

	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 (bind)
			p->tcfa_bindcnt--;
		else if (strict && p->tcfa_bindcnt > 0)
			atomic_dec(&p->tcfa_bindcnt);
		else if (strict && atomic_read(&p->tcfa_bindcnt) > 0)
			return -EPERM;

		p->tcfa_refcnt--;
		if (p->tcfa_bindcnt <= 0 && p->tcfa_refcnt <= 0) {
		if (atomic_read(&p->tcfa_bindcnt) <= 0 &&
		    refcount_dec_and_test(&p->tcfa_refcnt)) {
			if (p->ops->cleanup)
				p->ops->cleanup(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,

	if (index && p) {
		if (bind)
			p->tcfa_bindcnt++;
		p->tcfa_refcnt++;
			atomic_inc(&p->tcfa_bindcnt);
		refcount_inc(&p->tcfa_refcnt);
		*a = p;
		return true;
	}
@@ -324,9 +336,9 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,

	if (unlikely(!p))
		return -ENOMEM;
	p->tcfa_refcnt = 1;
	refcount_set(&p->tcfa_refcnt, 1);
	if (bind)
		p->tcfa_bindcnt = 1;
		atomic_set(&p->tcfa_bindcnt, 1);

	if (cpustats) {
		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)
		return;

	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,
@@ -810,7 +822,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
		act->order = i;
		sz += tcf_action_fill_size(act);
		if (ovr)
			act->tcfa_refcnt++;
			refcount_inc(&act->tcfa_refcnt);
		list_add_tail(&act->list, actions);
	}

+2 −2
Original line number Diff line number Diff line
@@ -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 tc_act_bpf opt = {
		.index   = prog->tcf_index,
		.refcnt  = prog->tcf_refcnt - ref,
		.bindcnt = prog->tcf_bindcnt - bind,
		.refcnt  = refcount_read(&prog->tcf_refcnt) - ref,
		.bindcnt = atomic_read(&prog->tcf_bindcnt) - bind,
		.action  = prog->tcf_action,
	};
	struct tcf_t tm;
+2 −2
Original line number Diff line number Diff line
@@ -154,8 +154,8 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,

	struct tc_connmark opt = {
		.index   = ci->tcf_index,
		.refcnt  = ci->tcf_refcnt - ref,
		.bindcnt = ci->tcf_bindcnt - bind,
		.refcnt  = refcount_read(&ci->tcf_refcnt) - ref,
		.bindcnt = atomic_read(&ci->tcf_bindcnt) - bind,
		.action  = ci->tcf_action,
		.zone   = ci->zone,
	};
+2 −2
Original line number Diff line number Diff line
@@ -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 tc_csum opt = {
		.index   = p->tcf_index,
		.refcnt  = p->tcf_refcnt - ref,
		.bindcnt = p->tcf_bindcnt - bind,
		.refcnt  = refcount_read(&p->tcf_refcnt) - ref,
		.bindcnt = atomic_read(&p->tcf_bindcnt) - bind,
	};
	struct tcf_t t;

Loading