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

net: sched: update action implementations to support flags



Extend struct tc_action with new "tcfa_flags" field. Set the field in
tcf_idr_create() function and provide new helper
tcf_idr_create_from_flags() that derives 'cpustats' boolean from flags
value. Update individual hardware-offloaded actions init() to pass their
"flags" argument to new helper in order to skip percpu stats allocation
when user requested it through flags.

Signed-off-by: default avatarVlad Buslov <vladbu@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent abbb0d33
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct tc_action {
	struct gnet_stats_queue __percpu *cpu_qstats;
	struct tc_cookie	__rcu *act_cookie;
	struct tcf_chain	__rcu *goto_chain;
	u32			tcfa_flags;
};
#define tcf_index	common.tcfa_index
#define tcf_refcnt	common.tcfa_refcnt
@@ -154,7 +155,11 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
		   struct tc_action **a, const struct tc_action_ops *ops,
		   int bind, bool cpustats);
		   int bind, bool cpustats, u32 flags);
int tcf_idr_create_from_flags(struct tc_action_net *tn, u32 index,
			      struct nlattr *est, struct tc_action **a,
			      const struct tc_action_ops *ops, int bind,
			      u32 flags);
void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a);

void tcf_idr_cleanup(struct tc_action_net *tn, u32 index);
+21 −1
Original line number Diff line number Diff line
@@ -399,7 +399,7 @@ static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)

int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
		   struct tc_action **a, const struct tc_action_ops *ops,
		   int bind, bool cpustats)
		   int bind, bool cpustats, u32 flags)
{
	struct tc_action *p = kzalloc(ops->size, GFP_KERNEL);
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
@@ -427,6 +427,7 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
	p->tcfa_tm.install = jiffies;
	p->tcfa_tm.lastuse = jiffies;
	p->tcfa_tm.firstuse = 0;
	p->tcfa_flags = flags;
	if (est) {
		err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
					&p->tcfa_rate_est,
@@ -451,6 +452,17 @@ err1:
}
EXPORT_SYMBOL(tcf_idr_create);

int tcf_idr_create_from_flags(struct tc_action_net *tn, u32 index,
			      struct nlattr *est, struct tc_action **a,
			      const struct tc_action_ops *ops, int bind,
			      u32 flags)
{
	/* Set cpustats according to actions flags. */
	return tcf_idr_create(tn, index, est, a, ops, bind,
			      !(flags & TCA_ACT_FLAGS_NO_PERCPU_STATS), flags);
}
EXPORT_SYMBOL(tcf_idr_create_from_flags);

void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a)
{
	struct tcf_idrinfo *idrinfo = tn->idrinfo;
@@ -773,6 +785,14 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
	}
	rcu_read_unlock();

	if (a->tcfa_flags) {
		struct nla_bitfield32 flags = { a->tcfa_flags,
						a->tcfa_flags, };

		if (nla_put(skb, TCA_ACT_FLAGS, sizeof(flags), &flags))
			goto nla_put_failure;
	}

	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
	if (nest == NULL)
		goto nla_put_failure;
+1 −1
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
	ret = tcf_idr_check_alloc(tn, &index, act, bind);
	if (!ret) {
		ret = tcf_idr_create(tn, index, est, act,
				     &act_bpf_ops, bind, true);
				     &act_bpf_ops, bind, true, 0);
		if (ret < 0) {
			tcf_idr_cleanup(tn, index);
			return ret;
+1 −1
Original line number Diff line number Diff line
@@ -121,7 +121,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
	ret = tcf_idr_check_alloc(tn, &index, a, bind);
	if (!ret) {
		ret = tcf_idr_create(tn, index, est, a,
				     &act_connmark_ops, bind, false);
				     &act_connmark_ops, bind, false, 0);
		if (ret) {
			tcf_idr_cleanup(tn, index);
			return ret;
+2 −2
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
	index = parm->index;
	err = tcf_idr_check_alloc(tn, &index, a, bind);
	if (!err) {
		ret = tcf_idr_create(tn, index, est, a,
				     &act_csum_ops, bind, true);
		ret = tcf_idr_create_from_flags(tn, index, est, a,
						&act_csum_ops, bind, flags);
		if (ret) {
			tcf_idr_cleanup(tn, index);
			return ret;
Loading