All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.