netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area
@ 2017-07-28 14:40 Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure Jiri Pirko
                   ` (20 more replies)
  0 siblings, 21 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

This patchset is one of the couple cleanup patchsets I have in queue.
The motivation aside the obvious need to "make things nicer" is also
to prepare for shared filter blocks introduction. That requires tp->q
removal, and therefore removal of all tp->q users.

Patch 1 is just some small thing I spotted on the way
Patch 2 removes one user of tp->q, namely tcf_em_tree_change
Patches 3-8 do preparations for exts->nr_actions removal
Patch 9 does the conversion of action array into rcuized list. This is also
        one tp->q user removal.
Patches 10-11 do simple renames of functions in cls*
The rest of the patches remove unnecessary calls of tcf_exts_change helper.

Tested by tools/testing/selftests/tc-testing

Jiri Pirko (20):
  net: sched: sch_atm: use Qdisc_class_common structure
  net: sched: remove unneeded tcf_em_tree_change
  net: sched: change names of action number helpers to be aligned with
    the rest
  net: sched: use tcf_exts_has_actions in tcf_exts_exec
  net: sched: remove redundant helpers tcf_exts_is_predicative and
    tcf_exts_is_available
  net: sched: fix return value of tcf_exts_exec
  net: sched: remove check for number of actions in tcf_exts_exec
  net: sched: use tcf_exts_has_actions instead of exts->nr_actions
  net: sched: convert actions array into rcu list
  net: sched: cls_bpf: rename cls_bpf_modify_existing function
  net: sched: cls_fw: rename fw_change_attrs function
  net: sched: cls_flower: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_fw: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_matchall: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_basic: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_bpf: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_cgroup: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_flow: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_route: no need to call tcf_exts_change for newly
    allocated struct
  net: sched: cls_u32: no need to call tcf_exts_change for newly
    allocated struct

 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c  |   2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    |   4 +-
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     |   2 +-
 .../net/ethernet/mellanox/mlxsw/spectrum_flower.c  |   2 +-
 drivers/net/ethernet/netronome/nfp/bpf/offload.c   |   4 +-
 include/net/act_api.h                              |  11 +-
 include/net/pkt_cls.h                              | 143 ++++++++-------------
 net/dsa/slave.c                                    |   2 +-
 net/sched/act_api.c                                |  17 ++-
 net/sched/cls_api.c                                |  35 +++--
 net/sched/cls_basic.c                              |  21 +--
 net/sched/cls_bpf.c                                |  39 ++----
 net/sched/cls_cgroup.c                             |  22 +---
 net/sched/cls_flow.c                               |  48 +++----
 net/sched/cls_flower.c                             |  17 +--
 net/sched/cls_fw.c                                 |  44 ++-----
 net/sched/cls_matchall.c                           |  19 +--
 net/sched/cls_route.c                              |  36 ++----
 net/sched/cls_rsvp.h                               |  18 +--
 net/sched/cls_tcindex.c                            |  55 +++-----
 net/sched/cls_u32.c                                |  27 +---
 net/sched/sch_atm.c                                |  12 +-
 23 files changed, 192 insertions(+), 390 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-30 19:04   ` Jamal Hadi Salim
  2017-07-28 14:40 ` [patch net-next 02/20] net: sched: remove unneeded tcf_em_tree_change Jiri Pirko
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Even if it is only for classid now, use this common struct a be aligned
with the rest of the classful qdiscs.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/sch_atm.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 572fe25..0af4b1c 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -41,6 +41,7 @@
 #define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back))
 
 struct atm_flow_data {
+	struct Qdisc_class_common common;
 	struct Qdisc		*q;	/* FIFO, TBF, etc. */
 	struct tcf_proto __rcu	*filter_list;
 	struct tcf_block	*block;
@@ -49,7 +50,6 @@ struct atm_flow_data {
 					   struct sk_buff *skb); /* chaining */
 	struct atm_qdisc_data	*parent;	/* parent qdisc */
 	struct socket		*sock;		/* for closing */
-	u32			classid;	/* x:y type ID */
 	int			ref;		/* reference count */
 	struct gnet_stats_basic_packed	bstats;
 	struct gnet_stats_queue	qstats;
@@ -75,7 +75,7 @@ static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid)
 	struct atm_flow_data *flow;
 
 	list_for_each_entry(flow, &p->flows, list) {
-		if (flow->classid == classid)
+		if (flow->common.classid == classid)
 			return flow;
 	}
 	return NULL;
@@ -293,7 +293,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 	flow->old_pop = flow->vcc->pop;
 	flow->parent = p;
 	flow->vcc->pop = sch_atm_pop;
-	flow->classid = classid;
+	flow->common.classid = classid;
 	flow->ref = 1;
 	flow->excess = excess;
 	list_add(&flow->list, &p->link.list);
@@ -549,7 +549,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
 
 	p->link.vcc = NULL;
 	p->link.sock = NULL;
-	p->link.classid = sch->handle;
+	p->link.common.classid = sch->handle;
 	p->link.ref = 1;
 	tasklet_init(&p->task, sch_atm_dequeue, (unsigned long)sch);
 	return 0;
@@ -594,7 +594,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
 		sch, p, flow, skb, tcm);
 	if (list_empty(&flow->list))
 		return -EINVAL;
-	tcm->tcm_handle = flow->classid;
+	tcm->tcm_handle = flow->common.classid;
 	tcm->tcm_info = flow->q->handle;
 
 	nest = nla_nest_start(skb, TCA_OPTIONS);
@@ -619,7 +619,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
 			goto nla_put_failure;
 	}
 	if (flow->excess) {
-		if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->classid))
+		if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->common.classid))
 			goto nla_put_failure;
 	} else {
 		if (nla_put_u32(skb, TCA_ATM_EXCESS, 0))
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 02/20] net: sched: remove unneeded tcf_em_tree_change
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 03/20] net: sched: change names of action number helpers to be aligned with the rest Jiri Pirko
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Since tcf_em_tree_validate could be always called on a newly created
filter, there is no need for this change function.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/pkt_cls.h  | 21 ---------------------
 net/sched/cls_basic.c  |  4 +---
 net/sched/cls_cgroup.c |  4 +---
 net/sched/cls_flow.c   | 12 +++++-------
 4 files changed, 7 insertions(+), 34 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 537d0a0..f4462ec 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -333,26 +333,6 @@ int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
 			struct tcf_pkt_info *);
 
 /**
- * tcf_em_tree_change - replace ematch tree of a running classifier
- *
- * @tp: classifier kind handle
- * @dst: destination ematch tree variable
- * @src: source ematch tree (temporary tree from tcf_em_tree_validate)
- *
- * This functions replaces the ematch tree in @dst with the ematch
- * tree in @src. The classifier in charge of the ematch tree may be
- * running.
- */
-static inline void tcf_em_tree_change(struct tcf_proto *tp,
-				      struct tcf_ematch_tree *dst,
-				      struct tcf_ematch_tree *src)
-{
-	tcf_tree_lock(tp);
-	memcpy(dst, src, sizeof(*dst));
-	tcf_tree_unlock(tp);
-}
-
-/**
  * tcf_em_tree_match - evaulate an ematch tree
  *
  * @skb: socket buffer of the packet in question
@@ -386,7 +366,6 @@ struct tcf_ematch_tree {
 #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
 #define tcf_em_tree_destroy(t) do { (void)(t); } while(0)
 #define tcf_em_tree_dump(skb, t, tlv) (0)
-#define tcf_em_tree_change(tp, dst, src) do { } while(0)
 #define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
 
 #endif /* CONFIG_NET_EMATCH */
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index c4fd63a..979cd26 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -130,7 +130,6 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 {
 	int err;
 	struct tcf_exts e;
-	struct tcf_ematch_tree t;
 
 	err = tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
 	if (err < 0)
@@ -139,7 +138,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 	if (err < 0)
 		goto errout;
 
-	err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &t);
+	err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &f->ematches);
 	if (err < 0)
 		goto errout;
 
@@ -149,7 +148,6 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 	}
 
 	tcf_exts_change(tp, &f->exts, &e);
-	tcf_em_tree_change(tp, &f->ematches, &t);
 	f->tp = tp;
 
 	return 0;
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 12ce547..ce7d38b 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -76,7 +76,6 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	struct nlattr *tb[TCA_CGROUP_MAX + 1];
 	struct cls_cgroup_head *head = rtnl_dereference(tp->root);
 	struct cls_cgroup_head *new;
-	struct tcf_ematch_tree t;
 	struct tcf_exts e;
 	int err;
 
@@ -112,14 +111,13 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 		goto errout;
 	}
 
-	err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
+	err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &new->ematches);
 	if (err < 0) {
 		tcf_exts_destroy(&e);
 		goto errout;
 	}
 
 	tcf_exts_change(tp, &new->exts, &e);
-	tcf_em_tree_change(tp, &new->ematches, &t);
 
 	rcu_assign_pointer(tp->root, new);
 	if (head)
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 3065752..71fd1af 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -389,7 +389,6 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	struct nlattr *opt = tca[TCA_OPTIONS];
 	struct nlattr *tb[TCA_FLOW_MAX + 1];
 	struct tcf_exts e;
-	struct tcf_ematch_tree t;
 	unsigned int nkeys = 0;
 	unsigned int perturb_period = 0;
 	u32 baseclass = 0;
@@ -432,13 +431,13 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		goto err1;
 
-	err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &t);
-	if (err < 0)
-		goto err1;
-
 	err = -ENOBUFS;
 	fnew = kzalloc(sizeof(*fnew), GFP_KERNEL);
 	if (!fnew)
+		goto err1;
+
+	err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &fnew->ematches);
+	if (err < 0)
 		goto err2;
 
 	err = tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE);
@@ -512,7 +511,6 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 			       (unsigned long)fnew);
 
 	tcf_exts_change(tp, &fnew->exts, &e);
-	tcf_em_tree_change(tp, &fnew->ematches, &t);
 
 	netif_keep_dst(qdisc_dev(tp->q));
 
@@ -554,8 +552,8 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 
 err3:
 	tcf_exts_destroy(&fnew->exts);
+	tcf_em_tree_destroy(&fnew->ematches);
 err2:
-	tcf_em_tree_destroy(&t);
 	kfree(fnew);
 err1:
 	tcf_exts_destroy(&e);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 03/20] net: sched: change names of action number helpers to be aligned with the rest
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 02/20] net: sched: remove unneeded tcf_em_tree_change Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-30 19:46   ` Jamal Hadi Salim
  2017-07-28 14:40 ` [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec Jiri Pirko
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

The rest of the helpers are named tcf_exts_*, so change the name of
the action number helpers to be aligned. While at it, change to inline
functions.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c  |  2 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |  2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    |  4 +--
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     |  2 +-
 .../net/ethernet/mellanox/mlxsw/spectrum_flower.c  |  2 +-
 drivers/net/ethernet/netronome/nfp/bpf/offload.c   |  4 +--
 include/net/pkt_cls.h                              | 36 ++++++++++++++++------
 net/dsa/slave.c                                    |  2 +-
 net/sched/cls_api.c                                |  2 +-
 9 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
index ef06ce8..6f734c5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
@@ -96,7 +96,7 @@ static int fill_action_fields(struct adapter *adap,
 	LIST_HEAD(actions);
 
 	exts = cls->knode.exts;
-	if (tc_no_actions(exts))
+	if (!tcf_exts_has_actions(exts))
 		return -EINVAL;
 
 	tcf_exts_to_list(exts, &actions);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0f867dc..89d9aba 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8953,7 +8953,7 @@ static int parse_tc_actions(struct ixgbe_adapter *adapter,
 	LIST_HEAD(actions);
 	int err;
 
-	if (tc_no_actions(exts))
+	if (!tcf_exts_has_actions(exts))
 		return -EINVAL;
 
 	tcf_exts_to_list(exts, &actions);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 3c536f5..78f50d9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1326,7 +1326,7 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 	LIST_HEAD(actions);
 	int err;
 
-	if (tc_no_actions(exts))
+	if (!tcf_exts_has_actions(exts))
 		return -EINVAL;
 
 	attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
@@ -1839,7 +1839,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 	bool encap = false;
 	int err = 0;
 
-	if (tc_no_actions(exts))
+	if (!tcf_exts_has_actions(exts))
 		return -EINVAL;
 
 	memset(attr, 0, sizeof(*attr));
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 88b668b..66d511d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1626,7 +1626,7 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
 	LIST_HEAD(actions);
 	int err;
 
-	if (!tc_single_action(cls->exts)) {
+	if (!tcf_exts_has_one_action(cls->exts)) {
 		netdev_err(mlxsw_sp_port->dev, "only singular actions are supported\n");
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
index 400ad40..9be48d2e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
@@ -53,7 +53,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
 	LIST_HEAD(actions);
 	int err;
 
-	if (tc_no_actions(exts))
+	if (!tcf_exts_has_actions(exts))
 		return 0;
 
 	/* Count action is inserted first */
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 78d80a3..a88bb5b 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -115,14 +115,14 @@ nfp_net_bpf_get_act(struct nfp_net *nn, struct tc_cls_bpf_offload *cls_bpf)
 
 	/* TC direct action */
 	if (cls_bpf->exts_integrated) {
-		if (tc_no_actions(cls_bpf->exts))
+		if (!tcf_exts_has_actions(cls_bpf->exts))
 			return NN_ACT_DIRECT;
 
 		return -EOPNOTSUPP;
 	}
 
 	/* TC legacy mode */
-	if (!tc_single_action(cls_bpf->exts))
+	if (!tcf_exts_has_one_action(cls_bpf->exts))
 		return -EOPNOTSUPP;
 
 	tcf_exts_to_list(cls_bpf->exts, &actions);
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index f4462ec..7f25636 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -199,17 +199,35 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 	return 0;
 }
 
+/**
+ * tcf_exts_has_actions - check if at least one action is present
+ * @exts: tc filter extensions handle
+ *
+ * Returns true if at least one action is present.
+ */
+static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
+{
 #ifdef CONFIG_NET_CLS_ACT
+	return exts->nr_actions;
+#else
+	return false;
+#endif
+}
 
-#define tc_no_actions(_exts)  ((_exts)->nr_actions == 0)
-#define tc_single_action(_exts) ((_exts)->nr_actions == 1)
-
-#else /* CONFIG_NET_CLS_ACT */
-
-#define tc_no_actions(_exts) true
-#define tc_single_action(_exts) false
-
-#endif /* CONFIG_NET_CLS_ACT */
+/**
+ * tcf_exts_has_one_action - check if exactly one action is present
+ * @exts: tc filter extensions handle
+ *
+ * Returns true if exactly one action is present.
+ */
+static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	return exts->nr_actions == 1;
+#else
+	return false;
+#endif
+}
 
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
 		      struct nlattr **tb, struct nlattr *rate_tlv,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 9507bd3..9f15fcc 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -765,7 +765,7 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev,
 	if (!ds->ops->port_mirror_add)
 		return err;
 
-	if (!tc_single_action(cls->exts))
+	if (!tcf_exts_has_one_action(cls->exts))
 		return err;
 
 	tcf_exts_to_list(cls->exts, &actions);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 39da0c5..287ae6c 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -972,7 +972,7 @@ int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
 	const struct tc_action *a;
 	LIST_HEAD(actions);
 
-	if (tc_no_actions(exts))
+	if (!tcf_exts_has_actions(exts))
 		return -EINVAL;
 
 	tcf_exts_to_list(exts, &actions);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (2 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 03/20] net: sched: change names of action number helpers to be aligned with the rest Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-30 19:48   ` Jamal Hadi Salim
  2017-07-31 20:37   ` Cong Wang
  2017-07-28 14:40 ` [patch net-next 05/20] net: sched: remove redundant helpers tcf_exts_is_predicative and tcf_exts_is_available Jiri Pirko
                   ` (16 subsequent siblings)
  20 siblings, 2 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Use the tcf_exts_has_actions helper instead or directly testing
exts->nr_actions in tcf_exts_exec.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/pkt_cls.h | 46 +++++++++++++++++++++++-----------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 7f25636..322a282 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -177,29 +177,6 @@ tcf_exts_stats_update(const struct tcf_exts *exts,
 }
 
 /**
- * tcf_exts_exec - execute tc filter extensions
- * @skb: socket buffer
- * @exts: tc filter extensions handle
- * @res: desired result
- *
- * Executes all configured extensions. Returns 0 on a normal execution,
- * a negative number if the filter must be considered unmatched or
- * a positive action code (TC_ACT_*) which must be returned to the
- * underlying layer.
- */
-static inline int
-tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
-	       struct tcf_result *res)
-{
-#ifdef CONFIG_NET_CLS_ACT
-	if (exts->nr_actions)
-		return tcf_action_exec(skb, exts->actions, exts->nr_actions,
-				       res);
-#endif
-	return 0;
-}
-
-/**
  * tcf_exts_has_actions - check if at least one action is present
  * @exts: tc filter extensions handle
  *
@@ -229,6 +206,29 @@ static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
 #endif
 }
 
+/**
+ * tcf_exts_exec - execute tc filter extensions
+ * @skb: socket buffer
+ * @exts: tc filter extensions handle
+ * @res: desired result
+ *
+ * Executes all configured extensions. Returns 0 on a normal execution,
+ * a negative number if the filter must be considered unmatched or
+ * a positive action code (TC_ACT_*) which must be returned to the
+ * underlying layer.
+ */
+static inline int
+tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
+	      struct tcf_result *res)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (tcf_exts_has_actions(exts))
+		return tcf_action_exec(skb, exts->actions, exts->nr_actions,
+				       res);
+#endif
+	return 0;
+}
+
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
 		      struct nlattr **tb, struct nlattr *rate_tlv,
 		      struct tcf_exts *exts, bool ovr);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 05/20] net: sched: remove redundant helpers tcf_exts_is_predicative and tcf_exts_is_available
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (3 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 06/20] net: sched: fix return value of tcf_exts_exec Jiri Pirko
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

These two helpers are doing the same as tcf_exts_has_actions, so remove
them and use tcf_exts_has_actions instead.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/pkt_cls.h   | 30 ------------------------------
 net/sched/cls_fw.c      |  2 +-
 net/sched/cls_route.c   |  2 +-
 net/sched/cls_tcindex.c |  2 +-
 4 files changed, 3 insertions(+), 33 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 322a282..817badf 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -113,36 +113,6 @@ static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
 	return 0;
 }
 
-/**
- * tcf_exts_is_predicative - check if a predicative extension is present
- * @exts: tc filter extensions handle
- *
- * Returns 1 if a predicative extension is present, i.e. an extension which
- * might cause further actions and thus overrule the regular tcf_result.
- */
-static inline int
-tcf_exts_is_predicative(struct tcf_exts *exts)
-{
-#ifdef CONFIG_NET_CLS_ACT
-	return exts->nr_actions;
-#else
-	return 0;
-#endif
-}
-
-/**
- * tcf_exts_is_available - check if at least one extension is present
- * @exts: tc filter extensions handle
- *
- * Returns 1 if at least one extension is present.
- */
-static inline int
-tcf_exts_is_available(struct tcf_exts *exts)
-{
-	/* All non-predicative extensions must be added here. */
-	return tcf_exts_is_predicative(exts);
-}
-
 static inline void tcf_exts_to_list(const struct tcf_exts *exts,
 				    struct list_head *actions)
 {
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index d388536..a53fa75 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -387,7 +387,7 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 	t->tcm_handle = f->id;
 
-	if (!f->res.classid && !tcf_exts_is_available(&f->exts))
+	if (!f->res.classid && !tcf_exts_has_actions(&f->exts))
 		return skb->len;
 
 	nest = nla_nest_start(skb, TCA_OPTIONS);
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index d63d550..26f8636 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -113,7 +113,7 @@ static inline int route4_hash_wild(void)
 #define ROUTE4_APPLY_RESULT()					\
 {								\
 	*res = f->res;						\
-	if (tcf_exts_is_available(&f->exts)) {			\
+	if (tcf_exts_has_actions(&f->exts)) {			\
 		int r = tcf_exts_exec(skb, &f->exts, res);	\
 		if (r < 0) {					\
 			dont_cache = 1;				\
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 8a8a583..66924d1 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -52,7 +52,7 @@ struct tcindex_data {
 
 static inline int tcindex_filter_is_set(struct tcindex_filter_result *r)
 {
-	return tcf_exts_is_predicative(&r->exts) || r->res.classid;
+	return tcf_exts_has_actions(&r->exts) || r->res.classid;
 }
 
 static struct tcindex_filter_result *tcindex_lookup(struct tcindex_data *p,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 06/20] net: sched: fix return value of tcf_exts_exec
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (4 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 05/20] net: sched: remove redundant helpers tcf_exts_is_predicative and tcf_exts_is_available Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 07/20] net: sched: remove check for number of actions in tcf_exts_exec Jiri Pirko
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Return the defined TC_ACT_OK instead of 0.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/pkt_cls.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 817badf..61ce521 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -182,7 +182,7 @@ static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
  * @exts: tc filter extensions handle
  * @res: desired result
  *
- * Executes all configured extensions. Returns 0 on a normal execution,
+ * Executes all configured extensions. Returns TC_ACT_OK on a normal execution,
  * a negative number if the filter must be considered unmatched or
  * a positive action code (TC_ACT_*) which must be returned to the
  * underlying layer.
@@ -196,7 +196,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 		return tcf_action_exec(skb, exts->actions, exts->nr_actions,
 				       res);
 #endif
-	return 0;
+	return TC_ACT_OK;
 }
 
 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 07/20] net: sched: remove check for number of actions in tcf_exts_exec
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (5 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 06/20] net: sched: fix return value of tcf_exts_exec Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 08/20] net: sched: use tcf_exts_has_actions instead of exts->nr_actions Jiri Pirko
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Leave it to tcf_action_exec to return TC_ACT_OK in case there is no
action present.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/pkt_cls.h | 4 +---
 net/sched/act_api.c   | 3 ++-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 61ce521..b8959c9 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -192,9 +192,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 	      struct tcf_result *res)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	if (tcf_exts_has_actions(exts))
-		return tcf_action_exec(skb, exts->actions, exts->nr_actions,
-				       res);
+	return tcf_action_exec(skb, exts->actions, exts->nr_actions, res);
 #endif
 	return TC_ACT_OK;
 }
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index f2e9ed3..8d2e506 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -460,9 +460,10 @@ static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
 int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
 		    int nr_actions, struct tcf_result *res)
 {
-	int ret = -1, i;
 	u32 jmp_prgcnt = 0;
 	u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */
+	int i;
+	int ret = TC_ACT_OK;
 
 	if (skb_skip_tc_classify(skb))
 		return TC_ACT_OK;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 08/20] net: sched: use tcf_exts_has_actions instead of exts->nr_actions
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (6 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 07/20] net: sched: remove check for number of actions in tcf_exts_exec Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 09/20] net: sched: convert actions array into rcu list Jiri Pirko
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

For check in tcf_exts_dump use tcf_exts_has_actions helper instead
of exts->nr_actions for checking if there are any actions present.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_api.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 287ae6c..735d556 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -915,7 +915,7 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts)
 #ifdef CONFIG_NET_CLS_ACT
 	struct nlattr *nest;
 
-	if (exts->action && exts->nr_actions) {
+	if (exts->action && tcf_exts_has_actions(exts)) {
 		/*
 		 * again for backward compatible mode - we want
 		 * to work with both old and new modes of entering
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 09/20] net: sched: convert actions array into rcu list
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (7 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 08/20] net: sched: use tcf_exts_has_actions instead of exts->nr_actions Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-30 20:17   ` Jamal Hadi Salim
  2017-07-31 21:07   ` Cong Wang
  2017-07-28 14:40 ` [patch net-next 10/20] net: sched: cls_bpf: rename cls_bpf_modify_existing function Jiri Pirko
                   ` (11 subsequent siblings)
  20 siblings, 2 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Currently the actions are stored in array with array size. To traverse
this array in fastpath, tcf_tree_lock is taken to protect it. Convert
the array into a singly linked list, similar to the filter chains style
and allow traversal protected by rcu.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/act_api.h    | 11 +++++++---
 include/net/pkt_cls.h    | 46 ++++++++++++++++++-----------------------
 net/sched/act_api.c      | 16 ++++++++-------
 net/sched/cls_api.c      | 31 ++++++++++++----------------
 net/sched/cls_basic.c    | 10 +++------
 net/sched/cls_bpf.c      | 10 +++------
 net/sched/cls_cgroup.c   | 10 +++------
 net/sched/cls_flow.c     | 10 +++------
 net/sched/cls_flower.c   | 10 +++------
 net/sched/cls_fw.c       | 16 ++++-----------
 net/sched/cls_matchall.c | 11 +++-------
 net/sched/cls_route.c    | 10 +++------
 net/sched/cls_rsvp.h     | 18 +++++-----------
 net/sched/cls_tcindex.c  | 53 ++++++++++++++----------------------------------
 net/sched/cls_u32.c      | 15 ++++----------
 15 files changed, 99 insertions(+), 178 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 26ffd83..74e2657 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -21,6 +21,8 @@ struct tcf_hashinfo {
 struct tc_action_ops;
 
 struct tc_action {
+	/* Fast access part */
+	struct tc_action __rcu		*next;
 	const struct tc_action_ops	*ops;
 	__u32				type; /* for backward compat(TCA_OLD_COMPAT) */
 	__u32				order;
@@ -179,15 +181,18 @@ int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
 int tcf_unregister_action(struct tc_action_ops *a,
 			  struct pernet_operations *ops);
 int tcf_action_destroy(struct list_head *actions, int bind);
-int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
-		    int nr_actions, struct tcf_result *res);
+
+struct tcf_exts;
+
+int tcf_action_exec(struct sk_buff *skb, struct tcf_exts *exts,
+		    struct tcf_result *res);
 int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
 		    struct nlattr *est, char *name, int ovr, int bind,
 		    struct list_head *actions);
 struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
 				    struct nlattr *nla, struct nlattr *est,
 				    char *name, int ovr, int bind);
-int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
+int tcf_action_dump(struct sk_buff *skb, struct list_head *actions, int, int);
 int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
 int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index b8959c9..8257a4e 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -88,8 +88,7 @@ tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
 struct tcf_exts {
 #ifdef CONFIG_NET_CLS_ACT
 	__u32	type; /* for backward compat(TCA_OLD_COMPAT) */
-	int nr_actions;
-	struct tc_action **actions;
+	struct tc_action __rcu *action_list;
 #endif
 	/* Map to export classifier specific extension TLV types to the
 	 * generic extensions API. Unsupported extensions must be set to 0.
@@ -98,32 +97,32 @@ struct tcf_exts {
 	int police;
 };
 
-static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
+#define tcf_exts_for_each(a, exts)				\
+	for (a = rtnl_dereference(exts->action_list);		\
+	     a; a = rtnl_dereference(a->next))
+
+#define tcf_exts_for_each_rcu_bh(a, exts)			\
+	for (a = rcu_dereference_bh(exts->action_list);		\
+	     a; a = rcu_dereference_bh(a->next))
+
+static inline void tcf_exts_init(struct tcf_exts *exts, int action, int police)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	exts->type = 0;
-	exts->nr_actions = 0;
-	exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
-				GFP_KERNEL);
-	if (!exts->actions)
-		return -ENOMEM;
+	RCU_INIT_POINTER(exts->action_list, NULL);
 #endif
 	exts->action = action;
 	exts->police = police;
-	return 0;
 }
 
 static inline void tcf_exts_to_list(const struct tcf_exts *exts,
 				    struct list_head *actions)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	int i;
-
-	for (i = 0; i < exts->nr_actions; i++) {
-		struct tc_action *a = exts->actions[i];
+	struct tc_action *a;
 
+	tcf_exts_for_each(a, exts)
 		list_add_tail(&a->list, actions);
-	}
 #endif
 }
 
@@ -132,16 +131,11 @@ tcf_exts_stats_update(const struct tcf_exts *exts,
 		      u64 bytes, u64 packets, u64 lastuse)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	int i;
+	struct tc_action *a;
 
 	preempt_disable();
-
-	for (i = 0; i < exts->nr_actions; i++) {
-		struct tc_action *a = exts->actions[i];
-
+	tcf_exts_for_each(a, exts)
 		tcf_action_stats_update(a, bytes, packets, lastuse);
-	}
-
 	preempt_enable();
 #endif
 }
@@ -155,7 +149,7 @@ tcf_exts_stats_update(const struct tcf_exts *exts,
 static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	return exts->nr_actions;
+	return rtnl_dereference(exts->action_list);
 #else
 	return false;
 #endif
@@ -170,7 +164,8 @@ static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
 static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	return exts->nr_actions == 1;
+	return rtnl_dereference(exts->action_list) &&
+	       !rtnl_dereference(exts->action_list->next);
 #else
 	return false;
 #endif
@@ -192,7 +187,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
 	      struct tcf_result *res)
 {
 #ifdef CONFIG_NET_CLS_ACT
-	return tcf_action_exec(skb, exts->actions, exts->nr_actions, res);
+	return tcf_action_exec(skb, exts, res);
 #endif
 	return TC_ACT_OK;
 }
@@ -201,8 +196,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
 		      struct nlattr **tb, struct nlattr *rate_tlv,
 		      struct tcf_exts *exts, bool ovr);
 void tcf_exts_destroy(struct tcf_exts *exts);
-void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
-		     struct tcf_exts *src);
+void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
 int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
 int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 8d2e506..177b9ab 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -457,21 +457,19 @@ static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
 
 /*TCA_ACT_MAX_PRIO is 32, there count upto 32 */
 #define TCA_ACT_MAX_PRIO_MASK 0x1FF
-int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
-		    int nr_actions, struct tcf_result *res)
+int tcf_action_exec(struct sk_buff *skb, struct tcf_exts *exts,
+		    struct tcf_result *res)
 {
 	u32 jmp_prgcnt = 0;
 	u32 jmp_ttl = TCA_ACT_MAX_PRIO; /*matches actions per filter */
-	int i;
+	struct tc_action *a;
 	int ret = TC_ACT_OK;
 
 	if (skb_skip_tc_classify(skb))
 		return TC_ACT_OK;
 
 restart_act_graph:
-	for (i = 0; i < nr_actions; i++) {
-		const struct tc_action *a = actions[i];
-
+	tcf_exts_for_each_rcu_bh(a, exts) {
 		if (jmp_prgcnt > 0) {
 			jmp_prgcnt -= 1;
 			continue;
@@ -483,7 +481,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
 
 		if (TC_ACT_EXT_CMP(ret, TC_ACT_JUMP)) {
 			jmp_prgcnt = ret & TCA_ACT_MAX_PRIO_MASK;
-			if (!jmp_prgcnt || (jmp_prgcnt > nr_actions)) {
+			if (!jmp_prgcnt) {
 				/* faulty opcode, stop pipeline */
 				return TC_ACT_OK;
 			} else {
@@ -501,6 +499,10 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
 			break;
 	}
 
+	if (jmp_prgcnt > 0)
+		/* faulty opcode, stop pipeline */
+		return TC_ACT_OK;
+
 	return ret;
 }
 EXPORT_SYMBOL(tcf_action_exec);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 735d556..129f314 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -836,8 +836,6 @@ void tcf_exts_destroy(struct tcf_exts *exts)
 
 	tcf_exts_to_list(exts, &actions);
 	tcf_action_destroy(&actions, TCA_ACT_UNBIND);
-	kfree(exts->actions);
-	exts->nr_actions = 0;
 #endif
 }
 EXPORT_SYMBOL(tcf_exts_destroy);
@@ -857,20 +855,22 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
 				return PTR_ERR(act);
 
 			act->type = exts->type = TCA_OLD_COMPAT;
-			exts->actions[0] = act;
-			exts->nr_actions = 1;
+			exts->action_list = act;
 		} else if (exts->action && tb[exts->action]) {
+			struct tc_action **pprev;
 			LIST_HEAD(actions);
-			int err, i = 0;
+			int err;
 
 			err = tcf_action_init(net, tp, tb[exts->action],
 					      rate_tlv, NULL, ovr, TCA_ACT_BIND,
 					      &actions);
 			if (err)
 				return err;
-			list_for_each_entry(act, &actions, list)
-				exts->actions[i++] = act;
-			exts->nr_actions = i;
+			pprev = &exts->action_list;
+			list_for_each_entry(act, &actions, list) {
+				*pprev = act;
+				pprev = &act->next;
+			}
 		}
 	}
 #else
@@ -883,18 +883,16 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
 }
 EXPORT_SYMBOL(tcf_exts_validate);
 
-void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
-		     struct tcf_exts *src)
+void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	struct tcf_exts old = *dst;
 
-	tcf_tree_lock(tp);
-	dst->nr_actions = src->nr_actions;
-	dst->actions = src->actions;
+	rcu_assign_pointer(dst->action_list,
+			   rtnl_dereference(src->action_list));
 	dst->type = src->type;
-	tcf_tree_unlock(tp);
 
+	synchronize_rcu();
 	tcf_exts_destroy(&old);
 #endif
 }
@@ -903,10 +901,7 @@ EXPORT_SYMBOL(tcf_exts_change);
 #ifdef CONFIG_NET_CLS_ACT
 static struct tc_action *tcf_exts_first_act(struct tcf_exts *exts)
 {
-	if (exts->nr_actions == 0)
-		return NULL;
-	else
-		return exts->actions[0];
+	return exts->action_list;
 }
 #endif
 
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 979cd26..dc12d79 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -131,9 +131,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 	int err;
 	struct tcf_exts e;
 
-	err = tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
 	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -147,7 +145,7 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_exts_change(&f->exts, &e);
 	f->tp = tp;
 
 	return 0;
@@ -183,9 +181,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
 	if (!fnew)
 		return -ENOBUFS;
 
-	err = tcf_exts_init(&fnew->exts, TCA_BASIC_ACT, TCA_BASIC_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&fnew->exts, TCA_BASIC_ACT, TCA_BASIC_POLICE);
 
 	err = -EINVAL;
 	if (handle) {
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index f57bd53..49f311a 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -397,9 +397,7 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 	if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
 		return -EINVAL;
 
-	ret = tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
-	if (ret < 0)
-		return ret;
+	tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
 	ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
 	if (ret < 0)
 		goto errout;
@@ -436,7 +434,7 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &prog->res, base);
 	}
 
-	tcf_exts_change(tp, &prog->exts, &exts);
+	tcf_exts_change(&prog->exts, &exts);
 	return 0;
 
 errout:
@@ -488,9 +486,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
 	if (!prog)
 		return -ENOBUFS;
 
-	ret = tcf_exts_init(&prog->exts, TCA_BPF_ACT, TCA_BPF_POLICE);
-	if (ret < 0)
-		goto errout;
+	tcf_exts_init(&prog->exts, TCA_BPF_ACT, TCA_BPF_POLICE);
 
 	if (oldprog) {
 		if (handle && oldprog->handle != handle) {
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index ce7d38b..f6f302a 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -92,9 +92,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (!new)
 		return -ENOBUFS;
 
-	err = tcf_exts_init(&new->exts, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&new->exts, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
 	new->handle = handle;
 	new->tp = tp;
 	err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
@@ -102,9 +100,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		goto errout;
 
-	err = tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
 	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0) {
 		tcf_exts_destroy(&e);
@@ -117,7 +113,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 		goto errout;
 	}
 
-	tcf_exts_change(tp, &new->exts, &e);
+	tcf_exts_change(&new->exts, &e);
 
 	rcu_assign_pointer(tp->root, new);
 	if (head)
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 71fd1af..a2441c0 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -424,9 +424,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 			return -EOPNOTSUPP;
 	}
 
-	err = tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE);
-	if (err < 0)
-		goto err1;
+	tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE);
 	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		goto err1;
@@ -440,9 +438,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		goto err2;
 
-	err = tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE);
-	if (err < 0)
-		goto err3;
+	tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE);
 
 	fold = (struct flow_filter *)*arg;
 	if (fold) {
@@ -510,7 +506,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	setup_deferrable_timer(&fnew->perturb_timer, flow_perturbation,
 			       (unsigned long)fnew);
 
-	tcf_exts_change(tp, &fnew->exts, &e);
+	tcf_exts_change(&fnew->exts, &e);
 
 	netif_keep_dst(qdisc_dev(tp->q));
 
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 7832eb9..4bba357 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -855,9 +855,7 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
 	struct tcf_exts e;
 	int err;
 
-	err = tcf_exts_init(&e, TCA_FLOWER_ACT, 0);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_FLOWER_ACT, 0);
 	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -874,7 +872,7 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
 	fl_mask_update_range(mask);
 	fl_set_masked_key(&f->mkey, &f->key, mask);
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_exts_change(&f->exts, &e);
 
 	return 0;
 errout:
@@ -938,9 +936,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 		goto errout_tb;
 	}
 
-	err = tcf_exts_init(&fnew->exts, TCA_FLOWER_ACT, 0);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&fnew->exts, TCA_FLOWER_ACT, 0);
 
 	if (!handle) {
 		handle = fl_grab_new_handle(tp, head);
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index a53fa75..46a0e32 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -200,9 +200,7 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
 	u32 mask;
 	int err;
 
-	err = tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);
 	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -232,7 +230,7 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
 	} else if (head->mask != 0xFFFFFFFF)
 		goto errout;
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_exts_change(&f->exts, &e);
 
 	return 0;
 errout:
@@ -276,11 +274,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 #endif /* CONFIG_NET_CLS_IND */
 		fnew->tp = f->tp;
 
-		err = tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE);
-		if (err < 0) {
-			kfree(fnew);
-			return err;
-		}
+		tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE);
 
 		err = fw_change_attrs(net, tp, fnew, tb, tca, base, ovr);
 		if (err < 0) {
@@ -324,9 +318,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 	if (f == NULL)
 		return -ENOBUFS;
 
-	err = tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE);
 	f->id = handle;
 	f->tp = tp;
 
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index 9dc26c3..0b77f6e 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -123,9 +123,7 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
 	struct tcf_exts e;
 	int err;
 
-	err = tcf_exts_init(&e, TCA_MATCHALL_ACT, 0);
-	if (err)
-		return err;
+	tcf_exts_init(&e, TCA_MATCHALL_ACT, 0);
 	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -135,7 +133,7 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &head->res, base);
 	}
 
-	tcf_exts_change(tp, &head->exts, &e);
+	tcf_exts_change(&head->exts, &e);
 
 	return 0;
 errout:
@@ -176,9 +174,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
 	if (!new)
 		return -ENOBUFS;
 
-	err = tcf_exts_init(&new->exts, TCA_MATCHALL_ACT, 0);
-	if (err)
-		goto err_exts_init;
+	tcf_exts_init(&new->exts, TCA_MATCHALL_ACT, 0);
 
 	if (!handle)
 		handle = 1;
@@ -209,7 +205,6 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
 err_replace_hw_filter:
 err_set_parms:
 	tcf_exts_destroy(&new->exts);
-err_exts_init:
 	kfree(new);
 	return err;
 }
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 26f8636..60be2c4 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -375,9 +375,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 	struct tcf_exts e;
 	int err;
 
-	err = tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
 	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -450,7 +448,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
-	tcf_exts_change(tp, &f->exts, &e);
+	tcf_exts_change(&f->exts, &e);
 
 	return 0;
 errout:
@@ -488,9 +486,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
 	if (!f)
 		goto errout;
 
-	err = tcf_exts_init(&f->exts, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&f->exts, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
 
 	if (fold) {
 		f->id = fold->id;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 0d9d077..2088262 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -486,9 +486,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		return err;
 
-	err = tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
 	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
 	if (err < 0)
 		goto errout2;
@@ -507,18 +505,14 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 			goto errout2;
 		}
 
-		err = tcf_exts_init(&n->exts, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-		if (err < 0) {
-			kfree(n);
-			goto errout2;
-		}
+		tcf_exts_init(&n->exts, TCA_RSVP_ACT, TCA_RSVP_POLICE);
 
 		if (tb[TCA_RSVP_CLASSID]) {
 			n->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID]);
 			tcf_bind_filter(tp, &n->res, base);
 		}
 
-		tcf_exts_change(tp, &n->exts, &e);
+		tcf_exts_change(&n->exts, &e);
 		rsvp_replace(tp, n, handle);
 		return 0;
 	}
@@ -535,9 +529,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 	if (f == NULL)
 		goto errout2;
 
-	err = tcf_exts_init(&f->exts, TCA_RSVP_ACT, TCA_RSVP_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&f->exts, TCA_RSVP_ACT, TCA_RSVP_POLICE);
 	h2 = 16;
 	if (tb[TCA_RSVP_SRC]) {
 		memcpy(f->src, nla_data(tb[TCA_RSVP_SRC]), sizeof(f->src));
@@ -591,7 +583,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
 			if (f->tunnelhdr == 0)
 				tcf_bind_filter(tp, &f->res, base);
 
-			tcf_exts_change(tp, &f->exts, &e);
+			tcf_exts_change(&f->exts, &e);
 
 			fp = &s->ht[h2];
 			for (nfp = rtnl_dereference(*fp); nfp;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 66924d1..b2d771c 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -223,10 +223,10 @@ static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = {
 	[TCA_TCINDEX_CLASSID]		= { .type = NLA_U32 },
 };
 
-static int tcindex_filter_result_init(struct tcindex_filter_result *r)
+static void tcindex_filter_result_init(struct tcindex_filter_result *r)
 {
 	memset(r, 0, sizeof(*r));
-	return tcf_exts_init(&r->exts, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
+	tcf_exts_init(&r->exts, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
 }
 
 static void __tcindex_partial_destroy(struct rcu_head *head)
@@ -248,25 +248,18 @@ static void tcindex_free_perfect_hash(struct tcindex_data *cp)
 
 static int tcindex_alloc_perfect_hash(struct tcindex_data *cp)
 {
-	int i, err = 0;
+	int i;
 
 	cp->perfect = kcalloc(cp->hash, sizeof(struct tcindex_filter_result),
 			      GFP_KERNEL);
 	if (!cp->perfect)
 		return -ENOMEM;
 
-	for (i = 0; i < cp->hash; i++) {
-		err = tcf_exts_init(&cp->perfect[i].exts,
-				    TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
-		if (err < 0)
-			goto errout;
-	}
+	for (i = 0; i < cp->hash; i++)
+		tcf_exts_init(&cp->perfect[i].exts,
+			      TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
 
 	return 0;
-
-errout:
-	tcindex_free_perfect_hash(cp);
-	return err;
 }
 
 static int
@@ -282,9 +275,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 	int err, balloc = 0;
 	struct tcf_exts e;
 
-	err = tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
 	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -316,12 +307,8 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 	}
 	cp->h = p->h;
 
-	err = tcindex_filter_result_init(&new_filter_result);
-	if (err < 0)
-		goto errout1;
-	err = tcindex_filter_result_init(&cr);
-	if (err < 0)
-		goto errout1;
+	tcindex_filter_result_init(&new_filter_result);
+	tcindex_filter_result_init(&cr);
 	if (old_r)
 		cr.res = r->res;
 
@@ -406,11 +393,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 			goto errout_alloc;
 		f->key = handle;
 		f->next = NULL;
-		err = tcindex_filter_result_init(&f->result);
-		if (err < 0) {
-			kfree(f);
-			goto errout_alloc;
-		}
+		tcindex_filter_result_init(&f->result);
 	}
 
 	if (tb[TCA_TCINDEX_CLASSID]) {
@@ -419,17 +402,12 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 	}
 
 	if (old_r)
-		tcf_exts_change(tp, &r->exts, &e);
+		tcf_exts_change(&r->exts, &e);
 	else
-		tcf_exts_change(tp, &cr.exts, &e);
+		tcf_exts_change(&cr.exts, &e);
 
-	if (old_r && old_r != r) {
-		err = tcindex_filter_result_init(old_r);
-		if (err < 0) {
-			kfree(f);
-			goto errout_alloc;
-		}
-	}
+	if (old_r && old_r != r)
+		tcindex_filter_result_init(old_r);
 
 	oldp = p;
 	r->res = cr.res;
@@ -439,7 +417,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 		struct tcindex_filter *nfp;
 		struct tcindex_filter __rcu **fp;
 
-		tcf_exts_change(tp, &f->result.exts, &r->exts);
+		tcf_exts_change(&f->result.exts, &r->exts);
 
 		fp = cp->h + (handle % cp->hash);
 		for (nfp = rtnl_dereference(*fp);
@@ -459,7 +437,6 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 		tcindex_free_perfect_hash(cp);
 	else if (balloc == 2)
 		kfree(cp->h);
-errout1:
 	tcf_exts_destroy(&cr.exts);
 	tcf_exts_destroy(&new_filter_result.exts);
 errout:
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 2d01195..2c834f3 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -726,9 +726,7 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 	struct tcf_exts e;
 	int err;
 
-	err = tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE);
-	if (err < 0)
-		return err;
+	tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE);
 	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
 	if (err < 0)
 		goto errout;
@@ -769,7 +767,7 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 		n->ifindex = ret;
 	}
 #endif
-	tcf_exts_change(tp, &n->exts, &e);
+	tcf_exts_change(&n->exts, &e);
 
 	return 0;
 errout:
@@ -848,10 +846,7 @@ static struct tc_u_knode *u32_init_knode(struct tcf_proto *tp,
 	new->tp = tp;
 	memcpy(&new->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
 
-	if (tcf_exts_init(&new->exts, TCA_U32_ACT, TCA_U32_POLICE)) {
-		kfree(new);
-		return NULL;
-	}
+	tcf_exts_init(&new->exts, TCA_U32_ACT, TCA_U32_POLICE);
 
 	return new;
 }
@@ -1007,9 +1002,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
 	n->flags = flags;
 	n->tp = tp;
 
-	err = tcf_exts_init(&n->exts, TCA_U32_ACT, TCA_U32_POLICE);
-	if (err < 0)
-		goto errout;
+	tcf_exts_init(&n->exts, TCA_U32_ACT, TCA_U32_POLICE);
 
 #ifdef CONFIG_CLS_U32_MARK
 	n->pcpu_success = alloc_percpu(u32);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 10/20] net: sched: cls_bpf: rename cls_bpf_modify_existing function
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (8 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 09/20] net: sched: convert actions array into rcu list Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-31  9:30   ` Daniel Borkmann
  2017-07-28 14:40 ` [patch net-next 11/20] net: sched: cls_fw: rename fw_change_attrs function Jiri Pirko
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

The name cls_bpf_modify_existing is highly misleading, as it indeed does
not modify anything existing. It does not modify at all.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_bpf.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 49f311a..929cae9 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -382,10 +382,9 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,
 	return 0;
 }
 
-static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
-				   struct cls_bpf_prog *prog,
-				   unsigned long base, struct nlattr **tb,
-				   struct nlattr *est, bool ovr)
+static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
+			     struct cls_bpf_prog *prog, unsigned long base,
+			     struct nlattr **tb, struct nlattr *est, bool ovr)
 {
 	bool is_bpf, is_ebpf, have_exts = false;
 	struct tcf_exts exts;
@@ -504,8 +503,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
 		goto errout;
 	}
 
-	ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE],
-				      ovr);
+	ret = cls_bpf_set_parms(net, tp, prog, base, tb, tca[TCA_RATE], ovr);
 	if (ret < 0)
 		goto errout;
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 11/20] net: sched: cls_fw: rename fw_change_attrs function
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (9 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 10/20] net: sched: cls_bpf: rename cls_bpf_modify_existing function Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 12/20] net: sched: cls_flower: no need to call tcf_exts_change for newly allocated struct Jiri Pirko
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Since the function name is misleading since it is not changing
anything, name it similarly to other cls.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_fw.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 46a0e32..a30a098 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -190,10 +190,9 @@ static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = {
 	[TCA_FW_MASK]		= { .type = NLA_U32 },
 };
 
-static int
-fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
-		struct nlattr **tb, struct nlattr **tca, unsigned long base,
-		bool ovr)
+static int fw_set_parms(struct net *net, struct tcf_proto *tp,
+			struct fw_filter *f, struct nlattr **tb,
+			struct nlattr **tca, unsigned long base, bool ovr)
 {
 	struct fw_head *head = rtnl_dereference(tp->root);
 	struct tcf_exts e;
@@ -276,7 +275,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 
 		tcf_exts_init(&fnew->exts, TCA_FW_ACT, TCA_FW_POLICE);
 
-		err = fw_change_attrs(net, tp, fnew, tb, tca, base, ovr);
+		err = fw_set_parms(net, tp, fnew, tb, tca, base, ovr);
 		if (err < 0) {
 			tcf_exts_destroy(&fnew->exts);
 			kfree(fnew);
@@ -322,7 +321,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
 	f->id = handle;
 	f->tp = tp;
 
-	err = fw_change_attrs(net, tp, f, tb, tca, base, ovr);
+	err = fw_set_parms(net, tp, f, tb, tca, base, ovr);
 	if (err < 0)
 		goto errout;
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 12/20] net: sched: cls_flower: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (10 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 11/20] net: sched: cls_fw: rename fw_change_attrs function Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 13/20] net: sched: cls_fw: " Jiri Pirko
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the f struct was allocated right before fl_set_parms call, no need
to use tcf_exts_change to do atomic change, and we can just fill-up
the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_flower.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 4bba357..32cbbb3 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -852,13 +852,11 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
 			unsigned long base, struct nlattr **tb,
 			struct nlattr *est, bool ovr)
 {
-	struct tcf_exts e;
 	int err;
 
-	tcf_exts_init(&e, TCA_FLOWER_ACT, 0);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr);
 	if (err < 0)
-		goto errout;
+		return err;
 
 	if (tb[TCA_FLOWER_CLASSID]) {
 		f->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]);
@@ -867,17 +865,12 @@ static int fl_set_parms(struct net *net, struct tcf_proto *tp,
 
 	err = fl_set_key(net, tb, &f->key, &mask->key);
 	if (err)
-		goto errout;
+		return err;
 
 	fl_mask_update_range(mask);
 	fl_set_masked_key(&f->mkey, &f->key, mask);
 
-	tcf_exts_change(&f->exts, &e);
-
 	return 0;
-errout:
-	tcf_exts_destroy(&e);
-	return err;
 }
 
 static u32 fl_grab_new_handle(struct tcf_proto *tp,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 13/20] net: sched: cls_fw: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (11 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 12/20] net: sched: cls_flower: no need to call tcf_exts_change for newly allocated struct Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 14/20] net: sched: cls_matchall: " Jiri Pirko
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the f struct was allocated right before fw_set_parms call, no need
to use tcf_exts_change to do atomic change, and we can just fill-up
the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_fw.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index a30a098..d8c084a 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -195,14 +195,12 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp,
 			struct nlattr **tca, unsigned long base, bool ovr)
 {
 	struct fw_head *head = rtnl_dereference(tp->root);
-	struct tcf_exts e;
 	u32 mask;
 	int err;
 
-	tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &f->exts, ovr);
 	if (err < 0)
-		goto errout;
+		return err;
 
 	if (tb[TCA_FW_CLASSID]) {
 		f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
@@ -213,10 +211,8 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp,
 	if (tb[TCA_FW_INDEV]) {
 		int ret;
 		ret = tcf_change_indev(net, tb[TCA_FW_INDEV]);
-		if (ret < 0) {
-			err = ret;
-			goto errout;
-		}
+		if (ret < 0)
+			return ret;
 		f->ifindex = ret;
 	}
 #endif /* CONFIG_NET_CLS_IND */
@@ -225,16 +221,11 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp,
 	if (tb[TCA_FW_MASK]) {
 		mask = nla_get_u32(tb[TCA_FW_MASK]);
 		if (mask != head->mask)
-			goto errout;
+			return err;
 	} else if (head->mask != 0xFFFFFFFF)
-		goto errout;
-
-	tcf_exts_change(&f->exts, &e);
+		return err;
 
 	return 0;
-errout:
-	tcf_exts_destroy(&e);
-	return err;
 }
 
 static int fw_change(struct net *net, struct sk_buff *in_skb,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 14/20] net: sched: cls_matchall: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (12 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 13/20] net: sched: cls_fw: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 15/20] net: sched: cls_basic: " Jiri Pirko
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the head struct was allocated right before mall_set_parms call,
no need to use tcf_exts_change to do atomic change, and we can just
fill-up the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_matchall.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index 0b77f6e..94181e5 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -120,25 +120,17 @@ static int mall_set_parms(struct net *net, struct tcf_proto *tp,
 			  unsigned long base, struct nlattr **tb,
 			  struct nlattr *est, bool ovr)
 {
-	struct tcf_exts e;
 	int err;
 
-	tcf_exts_init(&e, TCA_MATCHALL_ACT, 0);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_exts_validate(net, tp, tb, est, &head->exts, ovr);
 	if (err < 0)
-		goto errout;
+		return err;
 
 	if (tb[TCA_MATCHALL_CLASSID]) {
 		head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]);
 		tcf_bind_filter(tp, &head->res, base);
 	}
-
-	tcf_exts_change(&head->exts, &e);
-
 	return 0;
-errout:
-	tcf_exts_destroy(&e);
-	return err;
 }
 
 static int mall_change(struct net *net, struct sk_buff *in_skb,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 15/20] net: sched: cls_basic: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (13 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 14/20] net: sched: cls_matchall: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 16/20] net: sched: cls_bpf: " Jiri Pirko
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the f struct was allocated right before basic_set_parms call, no need
to use tcf_exts_change to do atomic change, and we can just fill-up
the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_basic.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index dc12d79..0a35cb5 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -129,29 +129,22 @@ static int basic_set_parms(struct net *net, struct tcf_proto *tp,
 			   struct nlattr *est, bool ovr)
 {
 	int err;
-	struct tcf_exts e;
 
-	tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr);
 	if (err < 0)
-		goto errout;
+		return err;
 
 	err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &f->ematches);
 	if (err < 0)
-		goto errout;
+		return err;
 
 	if (tb[TCA_BASIC_CLASSID]) {
 		f->res.classid = nla_get_u32(tb[TCA_BASIC_CLASSID]);
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
-	tcf_exts_change(&f->exts, &e);
 	f->tp = tp;
-
 	return 0;
-errout:
-	tcf_exts_destroy(&e);
-	return err;
 }
 
 static int basic_change(struct net *net, struct sk_buff *in_skb,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 16/20] net: sched: cls_bpf: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (14 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 15/20] net: sched: cls_basic: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-31 10:02   ` Daniel Borkmann
  2017-07-28 14:40 ` [patch net-next 17/20] net: sched: cls_cgroup: " Jiri Pirko
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the prog struct was allocated right before cls_bpf_set_parms call,
no need to use tcf_exts_change to do atomic change, and we can just
fill-up the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_bpf.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 929cae9..d8bc3ec 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -387,7 +387,6 @@ static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
 			     struct nlattr **tb, struct nlattr *est, bool ovr)
 {
 	bool is_bpf, is_ebpf, have_exts = false;
-	struct tcf_exts exts;
 	u32 gen_flags = 0;
 	int ret;
 
@@ -396,28 +395,23 @@ static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
 	if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
 		return -EINVAL;
 
-	tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
-	ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
+	ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, ovr);
 	if (ret < 0)
-		goto errout;
+		return ret;
 
 	if (tb[TCA_BPF_FLAGS]) {
 		u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]);
 
-		if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) {
-			ret = -EINVAL;
-			goto errout;
-		}
+		if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT)
+			return -EINVAL;
 
 		have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT;
 	}
 	if (tb[TCA_BPF_FLAGS_GEN]) {
 		gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]);
 		if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS ||
-		    !tc_flags_valid(gen_flags)) {
-			ret = -EINVAL;
-			goto errout;
-		}
+		    !tc_flags_valid(gen_flags))
+			return -EINVAL;
 	}
 
 	prog->exts_integrated = have_exts;
@@ -426,19 +420,14 @@ static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp,
 	ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) :
 		       cls_bpf_prog_from_efd(tb, prog, tp);
 	if (ret < 0)
-		goto errout;
+		return ret;
 
 	if (tb[TCA_BPF_CLASSID]) {
 		prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
 		tcf_bind_filter(tp, &prog->res, base);
 	}
 
-	tcf_exts_change(&prog->exts, &exts);
 	return 0;
-
-errout:
-	tcf_exts_destroy(&exts);
-	return ret;
 }
 
 static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 17/20] net: sched: cls_cgroup: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (15 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 16/20] net: sched: cls_bpf: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 18/20] net: sched: cls_flow: " Jiri Pirko
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the new struct just was allocated, so no need to use tcf_exts_change
to do atomic change, and we can just fill-up the unused exts struct
directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_cgroup.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index f6f302a..676855f 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -76,7 +76,6 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	struct nlattr *tb[TCA_CGROUP_MAX + 1];
 	struct cls_cgroup_head *head = rtnl_dereference(tp->root);
 	struct cls_cgroup_head *new;
-	struct tcf_exts e;
 	int err;
 
 	if (!tca[TCA_OPTIONS])
@@ -100,20 +99,13 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
 	if (err < 0)
 		goto errout;
 
-	tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
-	if (err < 0) {
-		tcf_exts_destroy(&e);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &new->exts, ovr);
+	if (err < 0)
 		goto errout;
-	}
 
 	err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &new->ematches);
-	if (err < 0) {
-		tcf_exts_destroy(&e);
+	if (err < 0)
 		goto errout;
-	}
-
-	tcf_exts_change(&new->exts, &e);
 
 	rcu_assign_pointer(tp->root, new);
 	if (head)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 18/20] net: sched: cls_flow: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (16 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 17/20] net: sched: cls_cgroup: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 19/20] net: sched: cls_route: " Jiri Pirko
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the fnew struct just was allocated, so no need to use tcf_exts_change
to do atomic change, and we can just fill-up the unused exts struct
directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_flow.c | 36 ++++++++++++++----------------------
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index a2441c0..232f30b 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -388,7 +388,6 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	struct flow_filter *fold, *fnew;
 	struct nlattr *opt = tca[TCA_OPTIONS];
 	struct nlattr *tb[TCA_FLOW_MAX + 1];
-	struct tcf_exts e;
 	unsigned int nkeys = 0;
 	unsigned int perturb_period = 0;
 	u32 baseclass = 0;
@@ -424,27 +423,24 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 			return -EOPNOTSUPP;
 	}
 
-	tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE);
-	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
-	if (err < 0)
-		goto err1;
-
-	err = -ENOBUFS;
 	fnew = kzalloc(sizeof(*fnew), GFP_KERNEL);
 	if (!fnew)
-		goto err1;
+		return -ENOBUFS;
 
 	err = tcf_em_tree_validate(tp, tb[TCA_FLOW_EMATCHES], &fnew->ematches);
 	if (err < 0)
-		goto err2;
+		goto err1;
 
 	tcf_exts_init(&fnew->exts, TCA_FLOW_ACT, TCA_FLOW_POLICE);
+	err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &fnew->exts, ovr);
+	if (err < 0)
+		goto err2;
 
 	fold = (struct flow_filter *)*arg;
 	if (fold) {
 		err = -EINVAL;
 		if (fold->handle != handle && handle)
-			goto err3;
+			goto err2;
 
 		/* Copy fold into fnew */
 		fnew->tp = fold->tp;
@@ -464,31 +460,31 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 		if (tb[TCA_FLOW_MODE])
 			mode = nla_get_u32(tb[TCA_FLOW_MODE]);
 		if (mode != FLOW_MODE_HASH && nkeys > 1)
-			goto err3;
+			goto err2;
 
 		if (mode == FLOW_MODE_HASH)
 			perturb_period = fold->perturb_period;
 		if (tb[TCA_FLOW_PERTURB]) {
 			if (mode != FLOW_MODE_HASH)
-				goto err3;
+				goto err2;
 			perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ;
 		}
 	} else {
 		err = -EINVAL;
 		if (!handle)
-			goto err3;
+			goto err2;
 		if (!tb[TCA_FLOW_KEYS])
-			goto err3;
+			goto err2;
 
 		mode = FLOW_MODE_MAP;
 		if (tb[TCA_FLOW_MODE])
 			mode = nla_get_u32(tb[TCA_FLOW_MODE]);
 		if (mode != FLOW_MODE_HASH && nkeys > 1)
-			goto err3;
+			goto err2;
 
 		if (tb[TCA_FLOW_PERTURB]) {
 			if (mode != FLOW_MODE_HASH)
-				goto err3;
+				goto err2;
 			perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ;
 		}
 
@@ -506,8 +502,6 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 	setup_deferrable_timer(&fnew->perturb_timer, flow_perturbation,
 			       (unsigned long)fnew);
 
-	tcf_exts_change(&fnew->exts, &e);
-
 	netif_keep_dst(qdisc_dev(tp->q));
 
 	if (tb[TCA_FLOW_KEYS]) {
@@ -546,13 +540,11 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
 		call_rcu(&fold->rcu, flow_destroy_filter);
 	return 0;
 
-err3:
+err2:
 	tcf_exts_destroy(&fnew->exts);
 	tcf_em_tree_destroy(&fnew->ematches);
-err2:
-	kfree(fnew);
 err1:
-	tcf_exts_destroy(&e);
+	kfree(fnew);
 	return err;
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 19/20] net: sched: cls_route: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (17 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 18/20] net: sched: cls_flow: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-28 14:40 ` [patch net-next 20/20] net: sched: cls_u32: " Jiri Pirko
  2017-07-31 21:35 ` [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area David Miller
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the f struct was allocated right before route4_set_parms call,
no need to use tcf_exts_change to do atomic change, and we can just
fill-up the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_route.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 60be2c4..a3a09fc 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -372,35 +372,32 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 	struct route4_filter *fp;
 	unsigned int h1;
 	struct route4_bucket *b;
-	struct tcf_exts e;
 	int err;
 
-	tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_exts_validate(net, tp, tb, est, &f->exts, ovr);
 	if (err < 0)
-		goto errout;
+		return err;
 
-	err = -EINVAL;
 	if (tb[TCA_ROUTE4_TO]) {
 		if (new && handle & 0x8000)
-			goto errout;
+			return -EINVAL;
 		to = nla_get_u32(tb[TCA_ROUTE4_TO]);
 		if (to > 0xFF)
-			goto errout;
+			return -EINVAL;
 		nhandle = to;
 	}
 
 	if (tb[TCA_ROUTE4_FROM]) {
 		if (tb[TCA_ROUTE4_IIF])
-			goto errout;
+			return -EINVAL;
 		id = nla_get_u32(tb[TCA_ROUTE4_FROM]);
 		if (id > 0xFF)
-			goto errout;
+			return -EINVAL;
 		nhandle |= id << 16;
 	} else if (tb[TCA_ROUTE4_IIF]) {
 		id = nla_get_u32(tb[TCA_ROUTE4_IIF]);
 		if (id > 0x7FFF)
-			goto errout;
+			return -EINVAL;
 		nhandle |= (id | 0x8000) << 16;
 	} else
 		nhandle |= 0xFFFF << 16;
@@ -408,27 +405,25 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 	if (handle && new) {
 		nhandle |= handle & 0x7F00;
 		if (nhandle != handle)
-			goto errout;
+			return -EINVAL;
 	}
 
 	h1 = to_hash(nhandle);
 	b = rtnl_dereference(head->table[h1]);
 	if (!b) {
-		err = -ENOBUFS;
 		b = kzalloc(sizeof(struct route4_bucket), GFP_KERNEL);
 		if (b == NULL)
-			goto errout;
+			return -ENOBUFS;
 
 		rcu_assign_pointer(head->table[h1], b);
 	} else {
 		unsigned int h2 = from_hash(nhandle >> 16);
 
-		err = -EEXIST;
 		for (fp = rtnl_dereference(b->ht[h2]);
 		     fp;
 		     fp = rtnl_dereference(fp->next))
 			if (fp->handle == f->handle)
-				goto errout;
+				return -EEXIST;
 	}
 
 	if (tb[TCA_ROUTE4_TO])
@@ -448,12 +443,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
-	tcf_exts_change(&f->exts, &e);
-
 	return 0;
-errout:
-	tcf_exts_destroy(&e);
-	return err;
 }
 
 static int route4_change(struct net *net, struct sk_buff *in_skb,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [patch net-next 20/20] net: sched: cls_u32: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (18 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 19/20] net: sched: cls_route: " Jiri Pirko
@ 2017-07-28 14:40 ` Jiri Pirko
  2017-07-31 21:35 ` [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area David Miller
  20 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-28 14:40 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

As the n struct was allocated right before u32_set_parms call,
no need to use tcf_exts_change to do atomic change, and we can just
fill-up the unused exts struct directly by tcf_exts_validate.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_u32.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 2c834f3..b8b0786 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -723,27 +723,24 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 			 struct tc_u_knode *n, struct nlattr **tb,
 			 struct nlattr *est, bool ovr)
 {
-	struct tcf_exts e;
 	int err;
 
-	tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE);
-	err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
+	err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr);
 	if (err < 0)
-		goto errout;
+		return err;
 
-	err = -EINVAL;
 	if (tb[TCA_U32_LINK]) {
 		u32 handle = nla_get_u32(tb[TCA_U32_LINK]);
 		struct tc_u_hnode *ht_down = NULL, *ht_old;
 
 		if (TC_U32_KEY(handle))
-			goto errout;
+			return -EINVAL;
 
 		if (handle) {
 			ht_down = u32_lookup_ht(ht->tp_c, handle);
 
 			if (ht_down == NULL)
-				goto errout;
+				return -EINVAL;
 			ht_down->refcnt++;
 		}
 
@@ -763,16 +760,11 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp,
 		int ret;
 		ret = tcf_change_indev(net, tb[TCA_U32_INDEV]);
 		if (ret < 0)
-			goto errout;
+			return -EINVAL;
 		n->ifindex = ret;
 	}
 #endif
-	tcf_exts_change(&n->exts, &e);
-
 	return 0;
-errout:
-	tcf_exts_destroy(&e);
-	return err;
 }
 
 static void u32_replace_knode(struct tcf_proto *tp, struct tc_u_common *tp_c,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure
  2017-07-28 14:40 ` [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure Jiri Pirko
@ 2017-07-30 19:04   ` Jamal Hadi Salim
  0 siblings, 0 replies; 35+ messages in thread
From: Jamal Hadi Salim @ 2017-07-30 19:04 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, xiyou.wangcong, daniel, mlxsw

On 17-07-28 10:40 AM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Even if it is only for classid now, use this common struct a be aligned
> with the rest of the classful qdiscs.
> 
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Looks good to me.

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>

cheers,
jamal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 03/20] net: sched: change names of action number helpers to be aligned with the rest
  2017-07-28 14:40 ` [patch net-next 03/20] net: sched: change names of action number helpers to be aligned with the rest Jiri Pirko
@ 2017-07-30 19:46   ` Jamal Hadi Salim
  0 siblings, 0 replies; 35+ messages in thread
From: Jamal Hadi Salim @ 2017-07-30 19:46 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, xiyou.wangcong, daniel, mlxsw

On 17-07-28 10:40 AM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> The rest of the helpers are named tcf_exts_*, so change the name of
> the action number helpers to be aligned. While at it, change to inline
> functions.
> 
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Looks reasonable.

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>

cheers,
jamal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-28 14:40 ` [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec Jiri Pirko
@ 2017-07-30 19:48   ` Jamal Hadi Salim
  2017-07-31  6:36     ` Jiri Pirko
  2017-07-31 20:37   ` Cong Wang
  1 sibling, 1 reply; 35+ messages in thread
From: Jamal Hadi Salim @ 2017-07-30 19:48 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, xiyou.wangcong, daniel, mlxsw

I am probably missing something. All those changes to just
replace "if (exts->nr_actions)" with "if (tcf_exts_has_actions(exts))" ?

cheers,
jamal

On 17-07-28 10:40 AM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Use the tcf_exts_has_actions helper instead or directly testing
> exts->nr_actions in tcf_exts_exec.
> 
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
> ---
>   include/net/pkt_cls.h | 46 +++++++++++++++++++++++-----------------------
>   1 file changed, 23 insertions(+), 23 deletions(-)
> 
> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> index 7f25636..322a282 100644
> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -177,29 +177,6 @@ tcf_exts_stats_update(const struct tcf_exts *exts,
>   }
>   
>   /**
> - * tcf_exts_exec - execute tc filter extensions
> - * @skb: socket buffer
> - * @exts: tc filter extensions handle
> - * @res: desired result
> - *
> - * Executes all configured extensions. Returns 0 on a normal execution,
> - * a negative number if the filter must be considered unmatched or
> - * a positive action code (TC_ACT_*) which must be returned to the
> - * underlying layer.
> - */
> -static inline int
> -tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
> -	       struct tcf_result *res)
> -{
> -#ifdef CONFIG_NET_CLS_ACT
> -	if (exts->nr_actions)
> -		return tcf_action_exec(skb, exts->actions, exts->nr_actions,
> -				       res);
> -#endif
> -	return 0;
> -}
> -
> -/**
>    * tcf_exts_has_actions - check if at least one action is present
>    * @exts: tc filter extensions handle
>    *
> @@ -229,6 +206,29 @@ static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
>   #endif
>   }
>   
> +/**
> + * tcf_exts_exec - execute tc filter extensions
> + * @skb: socket buffer
> + * @exts: tc filter extensions handle
> + * @res: desired result
> + *
> + * Executes all configured extensions. Returns 0 on a normal execution,
> + * a negative number if the filter must be considered unmatched or
> + * a positive action code (TC_ACT_*) which must be returned to the
> + * underlying layer.
> + */
> +static inline int
> +tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
> +	      struct tcf_result *res)
> +{
> +#ifdef CONFIG_NET_CLS_ACT
> +	if (tcf_exts_has_actions(exts))
> +		return tcf_action_exec(skb, exts->actions, exts->nr_actions,
> +				       res);
> +#endif
> +	return 0;
> +}
> +
>   int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
>   		      struct nlattr **tb, struct nlattr *rate_tlv,
>   		      struct tcf_exts *exts, bool ovr);
> 

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 09/20] net: sched: convert actions array into rcu list
  2017-07-28 14:40 ` [patch net-next 09/20] net: sched: convert actions array into rcu list Jiri Pirko
@ 2017-07-30 20:17   ` Jamal Hadi Salim
  2017-07-31 21:07   ` Cong Wang
  1 sibling, 0 replies; 35+ messages in thread
From: Jamal Hadi Salim @ 2017-07-30 20:17 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, xiyou.wangcong, daniel, mlxsw

On 17-07-28 10:40 AM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Currently the actions are stored in array with array size. To traverse
> this array in fastpath, tcf_tree_lock is taken to protect it. Convert
> the array into a singly linked list, similar to the filter chains style
> and allow traversal protected by rcu.
> 

Looks sane. But lets have Cong provide an opinion (since he said he was
trying to rcu the actions).

cheers,
jamal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-30 19:48   ` Jamal Hadi Salim
@ 2017-07-31  6:36     ` Jiri Pirko
  2017-07-31 12:09       ` Jamal Hadi Salim
  0 siblings, 1 reply; 35+ messages in thread
From: Jiri Pirko @ 2017-07-31  6:36 UTC (permalink / raw)
  To: Jamal Hadi Salim; +Cc: netdev, davem, xiyou.wangcong, daniel, mlxsw

Sun, Jul 30, 2017 at 09:48:24PM CEST, jhs@mojatatu.com wrote:
>I am probably missing something. All those changes to just
>replace "if (exts->nr_actions)" with "if (tcf_exts_has_actions(exts))" ?

That is what the description says :)


>
>cheers,
>jamal
>
>On 17-07-28 10:40 AM, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>> 
>> Use the tcf_exts_has_actions helper instead or directly testing
>> exts->nr_actions in tcf_exts_exec.
>> 
>> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 10/20] net: sched: cls_bpf: rename cls_bpf_modify_existing function
  2017-07-28 14:40 ` [patch net-next 10/20] net: sched: cls_bpf: rename cls_bpf_modify_existing function Jiri Pirko
@ 2017-07-31  9:30   ` Daniel Borkmann
  0 siblings, 0 replies; 35+ messages in thread
From: Daniel Borkmann @ 2017-07-31  9:30 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, jhs, xiyou.wangcong, mlxsw

On 07/28/2017 04:40 PM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> The name cls_bpf_modify_existing is highly misleading, as it indeed does
> not modify anything existing. It does not modify at all.
>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 16/20] net: sched: cls_bpf: no need to call tcf_exts_change for newly allocated struct
  2017-07-28 14:40 ` [patch net-next 16/20] net: sched: cls_bpf: " Jiri Pirko
@ 2017-07-31 10:02   ` Daniel Borkmann
  0 siblings, 0 replies; 35+ messages in thread
From: Daniel Borkmann @ 2017-07-31 10:02 UTC (permalink / raw)
  To: Jiri Pirko, netdev; +Cc: davem, jhs, xiyou.wangcong, mlxsw

On 07/28/2017 04:40 PM, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> As the prog struct was allocated right before cls_bpf_set_parms call,
> no need to use tcf_exts_change to do atomic change, and we can just
> fill-up the unused exts struct directly by tcf_exts_validate.
>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-31  6:36     ` Jiri Pirko
@ 2017-07-31 12:09       ` Jamal Hadi Salim
  2017-07-31 12:23         ` Jiri Pirko
  0 siblings, 1 reply; 35+ messages in thread
From: Jamal Hadi Salim @ 2017-07-31 12:09 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev, davem, xiyou.wangcong, daniel, mlxsw

On 17-07-31 02:36 AM, Jiri Pirko wrote:
> Sun, Jul 30, 2017 at 09:48:24PM CEST, jhs@mojatatu.com wrote:
>> I am probably missing something. All those changes to just
>> replace "if (exts->nr_actions)" with "if (tcf_exts_has_actions(exts))" ?
> 
> That is what the description says :)
> 

I meant I wouldve expected few liners added/removed.

cheers,
jamal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-31 12:09       ` Jamal Hadi Salim
@ 2017-07-31 12:23         ` Jiri Pirko
  0 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-07-31 12:23 UTC (permalink / raw)
  To: Jamal Hadi Salim; +Cc: netdev, davem, xiyou.wangcong, daniel, mlxsw

Mon, Jul 31, 2017 at 02:09:22PM CEST, jhs@mojatatu.com wrote:
>On 17-07-31 02:36 AM, Jiri Pirko wrote:
>> Sun, Jul 30, 2017 at 09:48:24PM CEST, jhs@mojatatu.com wrote:
>> > I am probably missing something. All those changes to just
>> > replace "if (exts->nr_actions)" with "if (tcf_exts_has_actions(exts))" ?
>> 
>> That is what the description says :)
>> 
>
>I meant I wouldve expected few liners added/removed.

one actually. But the function tcf_exts_exec had to be moved since
tcf_exts_has_actions was defined after originaly

>
>cheers,
>jamal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-28 14:40 ` [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec Jiri Pirko
  2017-07-30 19:48   ` Jamal Hadi Salim
@ 2017-07-31 20:37   ` Cong Wang
  2017-08-01  4:53     ` Jiri Pirko
  1 sibling, 1 reply; 35+ messages in thread
From: Cong Wang @ 2017-07-31 20:37 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Daniel Borkmann, mlxsw

On Fri, Jul 28, 2017 at 7:40 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> +static inline int
> +tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
> +             struct tcf_result *res)
> +{
> +#ifdef CONFIG_NET_CLS_ACT
> +       if (tcf_exts_has_actions(exts))
> +               return tcf_action_exec(skb, exts->actions, exts->nr_actions,
> +                                      res);
> +#endif
> +       return 0;
> +}


While you are on it, can we get rid of this macro too?

tcf_action_exec() is only defined with CONFIG_NET_CLS_ACT,
not sure if compiler is kind enough to eliminate the false branch
for us:

if (false)
    return tcf_action_exec(...); // not defined but the branch is dead

At least you can add a wrapper for tcf_action_exec() to just
return 0.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 09/20] net: sched: convert actions array into rcu list
  2017-07-28 14:40 ` [patch net-next 09/20] net: sched: convert actions array into rcu list Jiri Pirko
  2017-07-30 20:17   ` Jamal Hadi Salim
@ 2017-07-31 21:07   ` Cong Wang
  2017-08-01  4:59     ` Jiri Pirko
  1 sibling, 1 reply; 35+ messages in thread
From: Cong Wang @ 2017-07-31 21:07 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Daniel Borkmann, mlxsw

On Fri, Jul 28, 2017 at 7:40 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> Currently the actions are stored in array with array size. To traverse
> this array in fastpath, tcf_tree_lock is taken to protect it. Convert
> the array into a singly linked list, similar to the filter chains style
> and allow traversal protected by rcu.

Did you read commit 22dc13c837c33207548c8ee5116 ?

An action can't be shared by multiple filters if you put them
in a list (no matter singly or double), this is why I use pointers.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area
  2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
                   ` (19 preceding siblings ...)
  2017-07-28 14:40 ` [patch net-next 20/20] net: sched: cls_u32: " Jiri Pirko
@ 2017-07-31 21:35 ` David Miller
  20 siblings, 0 replies; 35+ messages in thread
From: David Miller @ 2017-07-31 21:35 UTC (permalink / raw)
  To: jiri; +Cc: netdev, jhs, xiyou.wangcong, daniel, mlxsw

From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 28 Jul 2017 16:40:22 +0200

> From: Jiri Pirko <jiri@mellanox.com>
> 
> This patchset is one of the couple cleanup patchsets I have in queue.
> The motivation aside the obvious need to "make things nicer" is also
> to prepare for shared filter blocks introduction. That requires tp->q
> removal, and therefore removal of all tp->q users.
> 
> Patch 1 is just some small thing I spotted on the way
> Patch 2 removes one user of tp->q, namely tcf_em_tree_change
> Patches 3-8 do preparations for exts->nr_actions removal
> Patch 9 does the conversion of action array into rcuized list. This is also
>         one tp->q user removal.
> Patches 10-11 do simple renames of functions in cls*
> The rest of the patches remove unnecessary calls of tcf_exts_change helper.
> 
> Tested by tools/testing/selftests/tc-testing

It looks like patch #9 needs some changes, or at least more explanation
in the commit log message, based upon Cong's feedback.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec
  2017-07-31 20:37   ` Cong Wang
@ 2017-08-01  4:53     ` Jiri Pirko
  0 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-08-01  4:53 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Daniel Borkmann, mlxsw

Mon, Jul 31, 2017 at 10:37:21PM CEST, xiyou.wangcong@gmail.com wrote:
>On Fri, Jul 28, 2017 at 7:40 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> +static inline int
>> +tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
>> +             struct tcf_result *res)
>> +{
>> +#ifdef CONFIG_NET_CLS_ACT
>> +       if (tcf_exts_has_actions(exts))
>> +               return tcf_action_exec(skb, exts->actions, exts->nr_actions,
>> +                                      res);
>> +#endif
>> +       return 0;
>> +}
>
>
>While you are on it, can we get rid of this macro too?
>
>tcf_action_exec() is only defined with CONFIG_NET_CLS_ACT,
>not sure if compiler is kind enough to eliminate the false branch
>for us:
>
>if (false)
>    return tcf_action_exec(...); // not defined but the branch is dead
>
>At least you can add a wrapper for tcf_action_exec() to just
>return 0.

Did you see?
net: sched: remove check for number of actions in tcf_exts_exec

I will add static inline stub for tcf_action_exec in case CONFIG_NET_CLS_ACT
is not set.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch net-next 09/20] net: sched: convert actions array into rcu list
  2017-07-31 21:07   ` Cong Wang
@ 2017-08-01  4:59     ` Jiri Pirko
  0 siblings, 0 replies; 35+ messages in thread
From: Jiri Pirko @ 2017-08-01  4:59 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Daniel Borkmann, mlxsw

Mon, Jul 31, 2017 at 11:07:13PM CEST, xiyou.wangcong@gmail.com wrote:
>On Fri, Jul 28, 2017 at 7:40 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> Currently the actions are stored in array with array size. To traverse
>> this array in fastpath, tcf_tree_lock is taken to protect it. Convert
>> the array into a singly linked list, similar to the filter chains style
>> and allow traversal protected by rcu.
>
>Did you read commit 22dc13c837c33207548c8ee5116 ?
>
>An action can't be shared by multiple filters if you put them
>in a list (no matter singly or double), this is why I use pointers.

Allright. Will check it out.

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2017-08-01  4:59 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-28 14:40 [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area Jiri Pirko
2017-07-28 14:40 ` [patch net-next 01/20] net: sched: sch_atm: use Qdisc_class_common structure Jiri Pirko
2017-07-30 19:04   ` Jamal Hadi Salim
2017-07-28 14:40 ` [patch net-next 02/20] net: sched: remove unneeded tcf_em_tree_change Jiri Pirko
2017-07-28 14:40 ` [patch net-next 03/20] net: sched: change names of action number helpers to be aligned with the rest Jiri Pirko
2017-07-30 19:46   ` Jamal Hadi Salim
2017-07-28 14:40 ` [patch net-next 04/20] net: sched: use tcf_exts_has_actions in tcf_exts_exec Jiri Pirko
2017-07-30 19:48   ` Jamal Hadi Salim
2017-07-31  6:36     ` Jiri Pirko
2017-07-31 12:09       ` Jamal Hadi Salim
2017-07-31 12:23         ` Jiri Pirko
2017-07-31 20:37   ` Cong Wang
2017-08-01  4:53     ` Jiri Pirko
2017-07-28 14:40 ` [patch net-next 05/20] net: sched: remove redundant helpers tcf_exts_is_predicative and tcf_exts_is_available Jiri Pirko
2017-07-28 14:40 ` [patch net-next 06/20] net: sched: fix return value of tcf_exts_exec Jiri Pirko
2017-07-28 14:40 ` [patch net-next 07/20] net: sched: remove check for number of actions in tcf_exts_exec Jiri Pirko
2017-07-28 14:40 ` [patch net-next 08/20] net: sched: use tcf_exts_has_actions instead of exts->nr_actions Jiri Pirko
2017-07-28 14:40 ` [patch net-next 09/20] net: sched: convert actions array into rcu list Jiri Pirko
2017-07-30 20:17   ` Jamal Hadi Salim
2017-07-31 21:07   ` Cong Wang
2017-08-01  4:59     ` Jiri Pirko
2017-07-28 14:40 ` [patch net-next 10/20] net: sched: cls_bpf: rename cls_bpf_modify_existing function Jiri Pirko
2017-07-31  9:30   ` Daniel Borkmann
2017-07-28 14:40 ` [patch net-next 11/20] net: sched: cls_fw: rename fw_change_attrs function Jiri Pirko
2017-07-28 14:40 ` [patch net-next 12/20] net: sched: cls_flower: no need to call tcf_exts_change for newly allocated struct Jiri Pirko
2017-07-28 14:40 ` [patch net-next 13/20] net: sched: cls_fw: " Jiri Pirko
2017-07-28 14:40 ` [patch net-next 14/20] net: sched: cls_matchall: " Jiri Pirko
2017-07-28 14:40 ` [patch net-next 15/20] net: sched: cls_basic: " Jiri Pirko
2017-07-28 14:40 ` [patch net-next 16/20] net: sched: cls_bpf: " Jiri Pirko
2017-07-31 10:02   ` Daniel Borkmann
2017-07-28 14:40 ` [patch net-next 17/20] net: sched: cls_cgroup: " Jiri Pirko
2017-07-28 14:40 ` [patch net-next 18/20] net: sched: cls_flow: " Jiri Pirko
2017-07-28 14:40 ` [patch net-next 19/20] net: sched: cls_route: " Jiri Pirko
2017-07-28 14:40 ` [patch net-next 20/20] net: sched: cls_u32: " Jiri Pirko
2017-07-31 21:35 ` [patch net-next 00/20] net: sched: summer cleanup part 1, mainly in exts area David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).