All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next V2 00/10] cls_flower hardware offload support
@ 2016-03-03 14:55 Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
                   ` (9 more replies)
  0 siblings, 10 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Hi,

This patchset is identical to V1 but with a fixed return value of tc_no_actions
in patch 3/10 ("net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef").

Please see changes from V1 at the bottom.

This patchset introduces cls_flower hardware offload support over ConnectX-4
driver, more hardware vendors are welcome to use it too.

This patchset is based on John's infrastructure for tc offloading [2] to add
hardware offload support to the flower filter. It also extends the support to
an additional tc action - skbedit mark operation.
NIC driver that was used is ConnectX-4. Feature is off by default and could be
turned on using ethtool.

Some commands to use this code:

export TC=../iproute2/tc/tc
export ETH=ens9

ethtool  -K ens9 hw-tc-offload on

# add an ingress qdisc
$TC qdisc add dev $ETH ingress

# Drop ICMP (ip_proto 1) packets
$TC filter add dev $ETH protocol ip prio 20 parent ffff: \
	flower ip_proto 1 \
	dst_mac 7c:fe:90:69:81:62 \
	src_mac 7c:fe:90:69:81:56 \
	dst_ip 11.11.11.11 \
	src_ip 11.11.11.12 \
	indev $ETH \
	action drop

# Mark (with 0x1234) TCP (ip_proto 6) packets
$TC filter add dev $ETH protocol ip prio 30 parent ffff: \
	flower ip_proto 6 \
	indev $ETH \
	action skbedit mark 0x1234

# A NOP software filter used to count marked packets using "tc show -s"
$TC filter add dev $ETH protocol ip prio 10 parent ffff: \
	handle 0x1234 fw action pass

The code was tested and applied on top of commit 3ebeac1 ("Merge branch
'cxgb4-next'")

Changes from V0:
- Use tc_no_actions and tc_for_each_action instead of ifdef CONFIG_NET_CLS_ACT
- Replace ENOTSUPP (and some EINVAL) with EOPNOTSUPP
- Name the flower command enum
- fl_hw_destroy_filter() to return void - nobody uses the return value
- mlx5e_tc_init() and mlx5e_tc_cleanup() to be called from the right places.
- When adding HW rule fails - fail the command
- Rules are added to be processed both by HW and SW unless SKIP_HW is given
- Adding patch 6/10 ("net/mlx5e: Relax ndo_setup_tc handle restriction")

Main changes from the RFC [1]:
- API
  - Using ndo_setup_tc() instead of switchdev
- act_skbedit, act_gact
  - Actions are not serialized to NIC driver, instead using access functions.
- cls_flower
  - prevent double classification by software by not adding
    successfuly offloaded filters to the hashtable
  - Fixed some bugs in original RFC with rule delete  
- mlx5
  - Adding flow table to kernel namespace instead of a new namespace
  - s/offload/tc/ in many places
  - no need for a special kconfig since switchdev is not used

Thanks,
Amir

[1] - http://permalink.gmane.org/gmane.linux.network/397064
[2] - http://permalink.gmane.org/gmane.linux.network/397045 
[3] - http://permalink.gmane.org/gmane.linux.network/401226

Amir Vadai (10):
  net/flower: Introduce hardware offload support
  net/flow_dissector: Make dissector_uses_key() and
    skb_flow_dissector_target() public
  net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  net/act_skbedit: Utility functions for mark action
  net/mlx5_core: Set flow steering dest only for forward rules
  net/mlx5e: Relax ndo_setup_tc handle restriction
  net/mlx5e: Add a new priority for kernel flow tables
  net/mlx5e: Introduce tc offload support
  net/mlx5e: Support offload cls_flower with drop action
  net/mlx5e: Support offload cls_flower with skbedit mark action

 drivers/net/ethernet/mellanox/mlx5/core/Makefile  |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en.h      |   9 +
 drivers/net/ethernet/mellanox/mlx5/core/en_fs.c   |   4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c |  47 ++-
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c   |   3 +
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c   | 429 ++++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h   |  51 +++
 drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c  |  29 +-
 drivers/net/ethernet/mellanox/mlx5/core/fs_core.c |  22 +-
 include/linux/netdevice.h                         |   2 +
 include/net/act_api.h                             |  21 +-
 include/net/flow_dissector.h                      |  13 +
 include/net/pkt_cls.h                             |  14 +
 include/net/tc_act/tc_gact.h                      |   4 +-
 include/net/tc_act/tc_skbedit.h                   |  15 +
 include/uapi/linux/pkt_cls.h                      |   2 +
 net/core/flow_dissector.c                         |  13 -
 net/sched/cls_flower.c                            |  71 +++-
 18 files changed, 704 insertions(+), 47 deletions(-)
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h

-- 
2.7.0

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

* [PATCH net-next V2 01/10] net/flower: Introduce hardware offload support
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
                     ` (2 more replies)
  2016-03-03 14:55 ` [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public Amir Vadai
                   ` (8 subsequent siblings)
  9 siblings, 3 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

This patch is based on a patch made by John Fastabend.
It adds support for offloading cls_flower.
when NETIF_F_HW_TC is on:
  flags = 0       => Rule will be processed twice - by hardware, and if
                     still relevant, by software.
  flags = SKIP_HW => Rull will be processed by software only

If hardare fail/not capabale to apply the rule, operation will fail.

Suggested-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Amir Vadai <amir@vadai.me>
---
 include/linux/netdevice.h    |  2 ++
 include/net/pkt_cls.h        | 14 +++++++++
 include/uapi/linux/pkt_cls.h |  2 ++
 net/sched/cls_flower.c       | 71 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index efe7cec..12db9d6 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -785,6 +785,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
 enum {
 	TC_SETUP_MQPRIO,
 	TC_SETUP_CLSU32,
+	TC_SETUP_CLSFLOWER,
 };
 
 struct tc_cls_u32_offload;
@@ -794,6 +795,7 @@ struct tc_to_netdev {
 	union {
 		u8 tc;
 		struct tc_cls_u32_offload *cls_u32;
+		struct tc_cls_flower_offload *cls_flower;
 	};
 };
 
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index bea14ee..5b4e8f0 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -409,4 +409,18 @@ static inline bool tc_should_offload(struct net_device *dev, u32 flags)
 	return true;
 }
 
+enum tc_fl_command {
+	TC_CLSFLOWER_REPLACE,
+	TC_CLSFLOWER_DESTROY,
+};
+
+struct tc_cls_flower_offload {
+	enum tc_fl_command command;
+	u64 cookie;
+	struct flow_dissector *dissector;
+	struct fl_flow_key *mask;
+	struct fl_flow_key *key;
+	struct tcf_exts *exts;
+};
+
 #endif
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 9874f568..c43c5f7 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -417,6 +417,8 @@ enum {
 	TCA_FLOWER_KEY_TCP_DST,		/* be16 */
 	TCA_FLOWER_KEY_UDP_SRC,		/* be16 */
 	TCA_FLOWER_KEY_UDP_DST,		/* be16 */
+
+	TCA_FLOWER_FLAGS,
 	__TCA_FLOWER_MAX,
 };
 
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 95b0212..ed3cd5a 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -165,6 +165,52 @@ static void fl_destroy_filter(struct rcu_head *head)
 	kfree(f);
 }
 
+static void fl_hw_destroy_filter(struct tcf_proto *tp, u64 cookie)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_flower_offload offload = {0};
+	struct tc_to_netdev tc;
+
+	if (!tc_should_offload(dev, 0))
+		return;
+
+	offload.command = TC_CLSFLOWER_DESTROY;
+	offload.cookie = cookie;
+
+	tc.type = TC_SETUP_CLSFLOWER;
+	tc.cls_flower = &offload;
+
+	dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc);
+}
+
+static int fl_hw_replace_filter(struct tcf_proto *tp,
+				struct flow_dissector *dissector,
+				struct fl_flow_key *mask,
+				struct fl_flow_key *key,
+				struct tcf_exts *actions,
+				u64 cookie, u32 flags)
+{
+	struct net_device *dev = tp->q->dev_queue->dev;
+	struct tc_cls_flower_offload offload = {0};
+	struct tc_to_netdev tc;
+
+	if (!tc_should_offload(dev, flags))
+		return 0;
+
+	offload.command = TC_CLSFLOWER_REPLACE;
+	offload.cookie = cookie;
+	offload.dissector = dissector;
+	offload.mask = mask;
+	offload.key = key;
+	offload.exts = actions;
+
+	tc.type = TC_SETUP_CLSFLOWER;
+	tc.cls_flower = &offload;
+
+	return dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
+					     &tc);
+}
+
 static bool fl_destroy(struct tcf_proto *tp, bool force)
 {
 	struct cls_fl_head *head = rtnl_dereference(tp->root);
@@ -174,6 +220,7 @@ static bool fl_destroy(struct tcf_proto *tp, bool force)
 		return false;
 
 	list_for_each_entry_safe(f, next, &head->filters, list) {
+		fl_hw_destroy_filter(tp, (u64)f);
 		list_del_rcu(&f->list);
 		call_rcu(&f->rcu, fl_destroy_filter);
 	}
@@ -454,11 +501,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 		     u32 handle, struct nlattr **tca,
 		     unsigned long *arg, bool ovr)
 {
+	struct net_device *dev = tp->q->dev_queue->dev;
 	struct cls_fl_head *head = rtnl_dereference(tp->root);
 	struct cls_fl_filter *fold = (struct cls_fl_filter *) *arg;
 	struct cls_fl_filter *fnew;
 	struct nlattr *tb[TCA_FLOWER_MAX + 1];
 	struct fl_flow_mask mask = {};
+	u32 flags = 0;
 	int err;
 
 	if (!tca[TCA_OPTIONS])
@@ -486,6 +535,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 	}
 	fnew->handle = handle;
 
+	if (tb[TCA_FLOWER_FLAGS])
+		flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
+
 	err = fl_set_parms(net, tp, fnew, &mask, base, tb, tca[TCA_RATE], ovr);
 	if (err)
 		goto errout;
@@ -498,9 +550,22 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 				     head->ht_params);
 	if (err)
 		goto errout;
-	if (fold)
+
+	err = fl_hw_replace_filter(tp,
+				   &head->dissector,
+				   &mask.key,
+				   &fnew->key,
+				   &fnew->exts,
+				   (u64)fnew,
+				   flags);
+	if (err)
+		goto err_hash_remove;
+
+	if (fold) {
 		rhashtable_remove_fast(&head->ht, &fold->ht_node,
 				       head->ht_params);
+		fl_hw_destroy_filter(tp, (u64)fold);
+	}
 
 	*arg = (unsigned long) fnew;
 
@@ -514,6 +579,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
 
 	return 0;
 
+err_hash_remove:
+	rhashtable_remove_fast(&head->ht, &fnew->ht_node, head->ht_params);
+
 errout:
 	kfree(fnew);
 	return err;
@@ -527,6 +595,7 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
 	rhashtable_remove_fast(&head->ht, &f->ht_node,
 			       head->ht_params);
 	list_del_rcu(&f->list);
+	fl_hw_destroy_filter(tp, (u64)f);
 	tcf_unbind_filter(tp, &f->res);
 	call_rcu(&f->rcu, fl_destroy_filter);
 	return 0;
-- 
2.7.0

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

* [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
  2016-03-04 16:55   ` John Fastabend
  2016-03-03 14:55 ` [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef Amir Vadai
                   ` (7 subsequent siblings)
  9 siblings, 2 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Will be used in a following patch to query if a key is being used, and
what it's value in the target object.

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 include/net/flow_dissector.h | 13 +++++++++++++
 net/core/flow_dissector.c    | 13 -------------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index 8c8548c..d3d60dc 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -184,4 +184,17 @@ static inline bool flow_keys_have_l4(struct flow_keys *keys)
 
 u32 flow_hash_from_keys(struct flow_keys *keys);
 
+static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
+				      enum flow_dissector_key_id key_id)
+{
+	return flow_dissector->used_keys & (1 << key_id);
+}
+
+static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
+					      enum flow_dissector_key_id key_id,
+					      void *target_container)
+{
+	return ((char *)target_container) + flow_dissector->offset[key_id];
+}
+
 #endif
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 7c7b873..a669dea 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -19,25 +19,12 @@
 #include <net/flow_dissector.h>
 #include <scsi/fc/fc_fcoe.h>
 
-static bool dissector_uses_key(const struct flow_dissector *flow_dissector,
-			       enum flow_dissector_key_id key_id)
-{
-	return flow_dissector->used_keys & (1 << key_id);
-}
-
 static void dissector_set_key(struct flow_dissector *flow_dissector,
 			      enum flow_dissector_key_id key_id)
 {
 	flow_dissector->used_keys |= (1 << key_id);
 }
 
-static void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
-				       enum flow_dissector_key_id key_id,
-				       void *target_container)
-{
-	return ((char *) target_container) + flow_dissector->offset[key_id];
-}
-
 void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
 			     const struct flow_dissector_key *key,
 			     unsigned int key_count)
-- 
2.7.0

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

* [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
                     ` (2 more replies)
  2016-03-03 14:55 ` [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action Amir Vadai
                   ` (6 subsequent siblings)
  9 siblings, 3 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Introduce the macros tc_no_actions and tc_for_each_action to make code
clearer.

Suggested-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Amir Vadai <amir@vadai.me>
---
 include/net/act_api.h        | 21 ++++++++++++++++-----
 include/net/tc_act/tc_gact.h |  4 ++--
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 342be6c..2a19fe1 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -78,11 +78,6 @@ static inline void tcf_lastuse_update(struct tcf_t *tm)
 		tm->lastuse = now;
 }
 
-#ifdef CONFIG_NET_CLS_ACT
-
-#define ACT_P_CREATED 1
-#define ACT_P_DELETED 1
-
 struct tc_action {
 	void			*priv;
 	const struct tc_action_ops	*ops;
@@ -92,6 +87,11 @@ struct tc_action {
 	struct tcf_hashinfo	*hinfo;
 };
 
+#ifdef CONFIG_NET_CLS_ACT
+
+#define ACT_P_CREATED 1
+#define ACT_P_DELETED 1
+
 struct tc_action_ops {
 	struct list_head head;
 	char    kind[IFNAMSIZ];
@@ -171,5 +171,16 @@ int tcf_action_dump(struct sk_buff *skb, struct list_head *, 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);
+
+#define tc_no_actions(_exts) \
+	(list_empty(&(_exts)->actions))
+
+#define tc_for_each_action(_a, _exts) \
+	list_for_each_entry(a, &(_exts)->actions, list)
+#else /* CONFIG_NET_CLS_ACT */
+
+#define tc_no_actions(_exts) true
+#define tc_for_each_action(_a, _exts) while (0)
+
 #endif /* CONFIG_NET_CLS_ACT */
 #endif
diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h
index 04a3183..93c520b 100644
--- a/include/net/tc_act/tc_gact.h
+++ b/include/net/tc_act/tc_gact.h
@@ -16,9 +16,9 @@ struct tcf_gact {
 #define to_gact(a) \
 	container_of(a->priv, struct tcf_gact, common)
 
-#ifdef CONFIG_NET_CLS_ACT
 static inline bool is_tcf_gact_shot(const struct tc_action *a)
 {
+#ifdef CONFIG_NET_CLS_ACT
 	struct tcf_gact *gact;
 
 	if (a->ops && a->ops->type != TCA_ACT_GACT)
@@ -28,7 +28,7 @@ static inline bool is_tcf_gact_shot(const struct tc_action *a)
 	if (gact->tcf_action == TC_ACT_SHOT)
 		return true;
 
+#endif
 	return false;
 }
-#endif
 #endif /* __NET_TC_GACT_H */
-- 
2.7.0

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

* [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (2 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
  2016-03-03 17:48   ` Cong Wang
  2016-03-03 14:55 ` [PATCH net-next V2 05/10] net/mlx5_core: Set flow steering dest only for forward rules Amir Vadai
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Enable device drivers to query the action if is a mark action and what
value to use for marking.

Signed-off-by: Amir Vadai <amir@vadai.me>
---
 include/net/tc_act/tc_skbedit.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h
index 0df9a0d..4497460 100644
--- a/include/net/tc_act/tc_skbedit.h
+++ b/include/net/tc_act/tc_skbedit.h
@@ -20,6 +20,7 @@
 #define __NET_TC_SKBEDIT_H
 
 #include <net/act_api.h>
+#include <linux/tc_act/tc_skbedit.h>
 
 struct tcf_skbedit {
 	struct tcf_common	common;
@@ -32,4 +33,18 @@ struct tcf_skbedit {
 #define to_skbedit(a) \
 	container_of(a->priv, struct tcf_skbedit, common)
 
+static inline bool is_tcf_skbedit_mark(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (a->ops && a->ops->type == TCA_ACT_SKBEDIT)
+		return to_skbedit(a)->flags == SKBEDIT_F_MARK;
+#endif
+	return false;
+}
+
+static inline u32 tcf_skbedit_mark(const struct tc_action *a)
+{
+	return to_skbedit(a)->mark;
+}
+
 #endif /* __NET_TC_SKBEDIT_H */
-- 
2.7.0

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

* [PATCH net-next V2 05/10] net/mlx5_core: Set flow steering dest only for forward rules
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (3 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 06/10] net/mlx5e: Relax ndo_setup_tc handle restriction Amir Vadai
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai, Maor Gottlieb

We need to handle flow table entry destinations only if the action
associated with the rule is forwarding (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST).

Fixes: 26a8145390b3 ('net/mlx5_core: Introduce flow steering firmware commands')
Signed-off-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c  | 29 +++++++++++++----------
 drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 18 +++++++++-----
 2 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
index a9894d2..f46f1db 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
@@ -218,19 +218,22 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
 				      match_value);
 	memcpy(in_match_value, &fte->val, MLX5_ST_SZ_BYTES(fte_match_param));
 
-	in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
-	list_for_each_entry(dst, &fte->node.children, node.list) {
-		unsigned int id;
-
-		MLX5_SET(dest_format_struct, in_dests, destination_type,
-			 dst->dest_attr.type);
-		if (dst->dest_attr.type ==
-		    MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
-			id = dst->dest_attr.ft->id;
-		else
-			id = dst->dest_attr.tir_num;
-		MLX5_SET(dest_format_struct, in_dests, destination_id, id);
-		in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
+	if (fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
+		in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
+		list_for_each_entry(dst, &fte->node.children, node.list) {
+			unsigned int id;
+
+			MLX5_SET(dest_format_struct, in_dests, destination_type,
+				 dst->dest_attr.type);
+			if (dst->dest_attr.type ==
+			    MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE) {
+				id = dst->dest_attr.ft->id;
+			} else {
+				id = dst->dest_attr.tir_num;
+			}
+			MLX5_SET(dest_format_struct, in_dests, destination_id, id);
+			in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
+		}
 	}
 	memset(out, 0, sizeof(out));
 	err = mlx5_cmd_exec_check_status(dev, in, inlen, out,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 6f68dba..f0e67d2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -360,8 +360,8 @@ static void del_rule(struct fs_node *node)
 	memcpy(match_value, fte->val, sizeof(fte->val));
 	fs_get_obj(ft, fg->node.parent);
 	list_del(&rule->node.list);
-	fte->dests_size--;
-	if (fte->dests_size) {
+	if ((fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) &&
+	    --fte->dests_size) {
 		err = mlx5_cmd_update_fte(dev, ft,
 					  fg->id, fte);
 		if (err)
@@ -763,7 +763,8 @@ static struct mlx5_flow_rule *alloc_rule(struct mlx5_flow_destination *dest)
 		return NULL;
 
 	rule->node.type = FS_TYPE_FLOW_DEST;
-	memcpy(&rule->dest_attr, dest, sizeof(*dest));
+	if (dest)
+		memcpy(&rule->dest_attr, dest, sizeof(*dest));
 
 	return rule;
 }
@@ -785,8 +786,9 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
 	/* Add dest to dests list- added as first element after the head */
 	tree_init_node(&rule->node, 1, del_rule);
 	list_add_tail(&rule->node.list, &fte->node.children);
-	fte->dests_size++;
-	if (fte->dests_size == 1)
+	if (dest)
+		fte->dests_size++;
+	if (fte->dests_size == 1 || !dest)
 		err = mlx5_cmd_create_fte(get_dev(&ft->node),
 					  ft, fg->id, fte);
 	else
@@ -802,7 +804,8 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
 free_rule:
 	list_del(&rule->node.list);
 	kfree(rule);
-	fte->dests_size--;
+	if (dest)
+		fte->dests_size--;
 	return ERR_PTR(err);
 }
 
@@ -996,6 +999,9 @@ mlx5_add_flow_rule(struct mlx5_flow_table *ft,
 	struct mlx5_flow_group *g;
 	struct mlx5_flow_rule *rule;
 
+	if ((action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && !dest)
+		return ERR_PTR(-EINVAL);
+
 	nested_lock_ref_node(&ft->node, FS_MUTEX_GRANDPARENT);
 	fs_for_each_fg(g, ft)
 		if (compare_match_criteria(g->mask.match_criteria_enable,
-- 
2.7.0

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

* [PATCH net-next V2 06/10] net/mlx5e: Relax ndo_setup_tc handle restriction
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (4 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 05/10] net/mlx5_core: Set flow steering dest only for forward rules Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 07/10] net/mlx5e: Add a new priority for kernel flow tables Amir Vadai
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Restricting handle to TC_H_ROOT breaks the old instantiation of mqprio
to setup a hardware qdisc. This patch relaxes the test, to only check the
type.

Fixes: 08fb1da ("net/mlx5e: Support DCBNL IEEE ETS")
Signed-off-by: Amir Vadai <amir@vadai.me>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5063c0e..5e3692f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1883,7 +1883,7 @@ static int mlx5e_setup_tc(struct net_device *netdev, u8 tc)
 static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
 			      __be16 proto, struct tc_to_netdev *tc)
 {
-	if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+	if (tc->type != TC_SETUP_MQPRIO)
 		return -EINVAL;
 
 	return mlx5e_setup_tc(dev, tc->tc);
-- 
2.7.0

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

* [PATCH net-next V2 07/10] net/mlx5e: Add a new priority for kernel flow tables
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (5 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 06/10] net/mlx5e: Relax ndo_setup_tc handle restriction Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 08/10] net/mlx5e: Introduce tc offload support Amir Vadai
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Move the vlan and main flow tables to use priority 1. This will allow
the upcoming TC offload logic to use a higher priority (0) for the
offload steering table.

Signed-off-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_fs.c   | 4 ++--
 drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index 80d81ab..d00a242 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -1041,7 +1041,7 @@ static int mlx5e_create_main_flow_table(struct mlx5e_priv *priv)
 	int err;
 
 	ft->num_groups = 0;
-	ft->t = mlx5_create_flow_table(priv->fts.ns, 0, MLX5E_MAIN_TABLE_SIZE);
+	ft->t = mlx5_create_flow_table(priv->fts.ns, 1, MLX5E_MAIN_TABLE_SIZE);
 
 	if (IS_ERR(ft->t)) {
 		err = PTR_ERR(ft->t);
@@ -1150,7 +1150,7 @@ static int mlx5e_create_vlan_flow_table(struct mlx5e_priv *priv)
 	int err;
 
 	ft->num_groups = 0;
-	ft->t = mlx5_create_flow_table(priv->fts.ns, 0, MLX5E_VLAN_TABLE_SIZE);
+	ft->t = mlx5_create_flow_table(priv->fts.ns, 1, MLX5E_VLAN_TABLE_SIZE);
 
 	if (IS_ERR(ft->t)) {
 		err = PTR_ERR(ft->t);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index f0e67d2..e848d70 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -73,8 +73,8 @@
 #define BY_PASS_MIN_LEVEL (KENREL_MIN_LEVEL + MLX5_BY_PASS_NUM_PRIOS +\
 			   LEFTOVERS_MAX_FT)
 
-#define KERNEL_MAX_FT 2
-#define KERNEL_NUM_PRIOS 1
+#define KERNEL_MAX_FT 3
+#define KERNEL_NUM_PRIOS 2
 #define KENREL_MIN_LEVEL 2
 
 struct node_caps {
-- 
2.7.0

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

* [PATCH net-next V2 08/10] net/mlx5e: Introduce tc offload support
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (6 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 07/10] net/mlx5e: Add a new priority for kernel flow tables Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:55 ` [PATCH net-next V2 09/10] net/mlx5e: Support offload cls_flower with drop action Amir Vadai
  2016-03-03 14:56 ` [PATCH net-next V2 10/10] net/mlx5e: Support offload cls_flower with skbedit mark action Amir Vadai
  9 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Extend ndo_setup_tc() to support ingress tc offloading. Will be used by
later patches to offload tc flower filter.

Feature is off by default and could be enabled by issuing:
 # ethtool  -K eth0 hw-tc-offload on

Offloads flow table is dynamically created when first filter is
added.
Rules are saved in a hash table that is maintained by the consumer (for
example - the flower offload in the next patch).
When last filter is removed and no filters exist in the hash table, the
offload flow table is destroyed.

Signed-off-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/Makefile  |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en.h      |   9 ++
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c |  38 ++++++-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c   | 131 ++++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h   |  44 ++++++++
 5 files changed, 222 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 11b592d..4fc45ee 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -6,6 +6,6 @@ mlx5_core-y :=	main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
 
 mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o eswitch.o \
 		en_main.o en_fs.o en_ethtool.o en_tx.o en_rx.o \
-		en_txrx.o en_clock.o vxlan.o
+		en_txrx.o en_clock.o vxlan.o en_tc.o
 
 mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) +=  en_dcbnl.o
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 9c0e80e..36f3dba 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -43,6 +43,7 @@
 #include <linux/mlx5/port.h>
 #include <linux/mlx5/vport.h>
 #include <linux/mlx5/transobj.h>
+#include <linux/rhashtable.h>
 #include "wq.h"
 #include "mlx5_core.h"
 
@@ -526,8 +527,16 @@ struct mlx5e_flow_table {
 	struct mlx5_flow_group		**g;
 };
 
+struct mlx5e_tc_flow_table {
+	struct mlx5_flow_table		*t;
+
+	struct rhashtable_params        ht_params;
+	struct rhashtable               ht;
+};
+
 struct mlx5e_flow_tables {
 	struct mlx5_flow_namespace	*ns;
+	struct mlx5e_tc_flow_table	tc;
 	struct mlx5e_flow_table		vlan;
 	struct mlx5e_flow_table		main;
 };
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5e3692f..011c4f6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -30,9 +30,12 @@
  * SOFTWARE.
  */
 
+#include <net/tc_act/tc_gact.h>
+#include <net/pkt_cls.h>
 #include <linux/mlx5/fs.h>
 #include <net/vxlan.h>
 #include "en.h"
+#include "en_tc.h"
 #include "eswitch.h"
 #include "vxlan.h"
 
@@ -1883,6 +1886,17 @@ static int mlx5e_setup_tc(struct net_device *netdev, u8 tc)
 static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
 			      __be16 proto, struct tc_to_netdev *tc)
 {
+	struct mlx5e_priv *priv = netdev_priv(dev);
+
+	if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
+		goto mqprio;
+
+	switch (tc->type) {
+	default:
+		return -EOPNOTSUPP;
+	}
+
+mqprio:
 	if (tc->type != TC_SETUP_MQPRIO)
 		return -EINVAL;
 
@@ -1966,6 +1980,13 @@ static int mlx5e_set_features(struct net_device *netdev,
 			mlx5e_disable_vlan_filter(priv);
 	}
 
+	if ((changes & NETIF_F_HW_TC) && !(features & NETIF_F_HW_TC) &&
+	    mlx5e_tc_num_filters(priv)) {
+		netdev_err(netdev,
+			   "Active offloaded tc filters, can't turn hw_tc_offload off\n");
+		return -EINVAL;
+	}
+
 	return err;
 }
 
@@ -2365,6 +2386,13 @@ static void mlx5e_build_netdev(struct net_device *netdev)
 	if (!priv->params.lro_en)
 		netdev->features  &= ~NETIF_F_LRO;
 
+#define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f)
+	if (FT_CAP(flow_modify_en) &&
+	    FT_CAP(modify_root) &&
+	    FT_CAP(identified_miss_table_mode) &&
+	    FT_CAP(flow_table_modify))
+		priv->netdev->hw_features      |= NETIF_F_HW_TC;
+
 	netdev->features         |= NETIF_F_HIGHDMA;
 
 	netdev->priv_flags       |= IFF_UNICAST_FLT;
@@ -2486,6 +2514,10 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
 
 	mlx5e_vxlan_init(priv);
 
+	err = mlx5e_tc_init(priv);
+	if (err)
+		goto err_destroy_flow_tables;
+
 #ifdef CONFIG_MLX5_CORE_EN_DCB
 	mlx5e_dcbnl_ieee_setets_core(priv, &priv->params.ets);
 #endif
@@ -2493,7 +2525,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
 	err = register_netdev(netdev);
 	if (err) {
 		mlx5_core_err(mdev, "register_netdev failed, %d\n", err);
-		goto err_destroy_flow_tables;
+		goto err_tc_cleanup;
 	}
 
 	if (mlx5e_vxlan_allowed(mdev))
@@ -2504,6 +2536,9 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
 
 	return priv;
 
+err_tc_cleanup:
+	mlx5e_tc_cleanup(priv);
+
 err_destroy_flow_tables:
 	mlx5e_destroy_flow_tables(priv);
 
@@ -2551,6 +2586,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
 	mlx5e_disable_async_events(priv);
 	flush_scheduled_work();
 	unregister_netdev(netdev);
+	mlx5e_tc_cleanup(priv);
 	mlx5e_vxlan_cleanup(priv);
 	mlx5e_destroy_flow_tables(priv);
 	mlx5e_destroy_tirs(priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
new file mode 100644
index 0000000..9457173
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/mlx5/fs.h>
+#include <linux/mlx5/device.h>
+#include <linux/rhashtable.h>
+#include "en.h"
+#include "en_tc.h"
+
+struct mlx5e_tc_flow {
+	struct rhash_head	node;
+	u64			cookie;
+	struct mlx5_flow_rule	*rule;
+};
+
+#define MLX5E_TC_FLOW_TABLE_NUM_ENTRIES 1024
+#define MLX5E_TC_FLOW_TABLE_NUM_GROUPS 4
+
+struct mlx5_flow_rule *mlx5e_tc_add_flow(struct mlx5e_priv *priv,
+					 u32 *match_c, u32 *match_v,
+					 u32 action, u32 flow_tag)
+{
+	struct mlx5_flow_destination dest = {
+		.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE,
+		{.ft = priv->fts.vlan.t},
+	};
+	struct mlx5_flow_rule *rule;
+	bool table_created = false;
+
+	if (IS_ERR_OR_NULL(priv->fts.tc.t)) {
+		priv->fts.tc.t =
+			mlx5_create_auto_grouped_flow_table(priv->fts.ns, 0,
+							    MLX5E_TC_FLOW_TABLE_NUM_ENTRIES,
+							    MLX5E_TC_FLOW_TABLE_NUM_GROUPS);
+		if (IS_ERR(priv->fts.tc.t)) {
+			netdev_err(priv->netdev,
+				   "Failed to create tc offload table\n");
+			return ERR_CAST(priv->fts.tc.t);
+		}
+
+		table_created = true;
+	}
+
+	rule = mlx5_add_flow_rule(priv->fts.tc.t, MLX5_MATCH_OUTER_HEADERS,
+				  match_c, match_v,
+				  action, flow_tag,
+				  action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ? &dest : NULL);
+
+	if (IS_ERR(rule) && table_created) {
+		mlx5_destroy_flow_table(priv->fts.tc.t);
+		priv->fts.tc.t = NULL;
+	}
+
+	return rule;
+}
+
+static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
+			      struct mlx5_flow_rule *rule)
+{
+	mlx5_del_flow_rule(rule);
+
+	if (!mlx5e_tc_num_filters(priv)) {
+		mlx5_destroy_flow_table(priv->fts.tc.t);
+		priv->fts.tc.t = NULL;
+	}
+}
+
+static const struct rhashtable_params mlx5e_tc_flow_ht_params = {
+	.head_offset = offsetof(struct mlx5e_tc_flow, node),
+	.key_offset = offsetof(struct mlx5e_tc_flow, cookie),
+	.key_len = sizeof(((struct mlx5e_tc_flow *)0)->cookie),
+	.automatic_shrinking = true,
+};
+
+int mlx5e_tc_init(struct mlx5e_priv *priv)
+{
+	struct mlx5e_tc_flow_table *tc = &priv->fts.tc;
+
+	tc->ht_params = mlx5e_tc_flow_ht_params;
+	return rhashtable_init(&tc->ht, &tc->ht_params);
+}
+
+static void _mlx5e_tc_del_flow(void *ptr, void *arg)
+{
+	struct mlx5e_tc_flow *flow = ptr;
+	struct mlx5e_priv *priv = arg;
+
+	mlx5e_tc_del_flow(priv, flow->rule);
+	kfree(flow);
+}
+
+void mlx5e_tc_cleanup(struct mlx5e_priv *priv)
+{
+	struct mlx5e_tc_flow_table *tc = &priv->fts.tc;
+
+	rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, priv);
+
+	if (!IS_ERR_OR_NULL(priv->fts.tc.t)) {
+		mlx5_destroy_flow_table(priv->fts.tc.t);
+		priv->fts.tc.t = NULL;
+	}
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
new file mode 100644
index 0000000..46eacc5
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __MLX5_EN_TC_H__
+#define __MLX5_EN_TC_H__
+
+int mlx5e_tc_init(struct mlx5e_priv *priv);
+void mlx5e_tc_cleanup(struct mlx5e_priv *priv);
+
+static inline int mlx5e_tc_num_filters(struct mlx5e_priv *priv)
+{
+	return atomic_read(&priv->fts.tc.ht.nelems);
+}
+
+#endif /* __MLX5_EN_TC_H__ */
-- 
2.7.0

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

* [PATCH net-next V2 09/10] net/mlx5e: Support offload cls_flower with drop action
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (7 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 08/10] net/mlx5e: Introduce tc offload support Amir Vadai
@ 2016-03-03 14:55 ` Amir Vadai
  2016-03-03 14:56 ` [PATCH net-next V2 10/10] net/mlx5e: Support offload cls_flower with skbedit mark action Amir Vadai
  9 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:55 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Parse tc_cls_flower_offload into device specific commands and program
the hardware to classify and act accordingly.

For example, to drop ICMP (ip_proto 1) packets from specific smac, dmac,
src_ip, src_ip, arriving to interface ens9:

 # tc qdisc add dev ens9 ingress

 # tc filter add dev ens9 protocol ip parent ffff: \
     flower ip_proto 1 \
     dst_mac 7c:fe:90:69:81:62 src_mac 7c:fe:90:69:81:56 \
     dst_ip 11.11.11.11 src_ip 11.11.11.12 indev ens9 \
     action drop

Signed-off-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c |   7 +
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c   | 297 ++++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h   |   5 +
 3 files changed, 309 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 011c4f6..9aa9103 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1892,6 +1892,13 @@ static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
 		goto mqprio;
 
 	switch (tc->type) {
+	case TC_SETUP_CLSFLOWER:
+		switch (tc->cls_flower->command) {
+		case TC_CLSFLOWER_REPLACE:
+			return mlx5e_configure_flower(priv, proto, tc->cls_flower);
+		case TC_CLSFLOWER_DESTROY:
+			return mlx5e_delete_flower(priv, tc->cls_flower);
+		}
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 9457173..3aea5da 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -30,6 +30,9 @@
  * SOFTWARE.
  */
 
+#include <net/flow_dissector.h>
+#include <net/pkt_cls.h>
+#include <net/tc_act/tc_gact.h>
 #include <linux/mlx5/fs.h>
 #include <linux/mlx5/device.h>
 #include <linux/rhashtable.h>
@@ -94,6 +97,300 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
 	}
 }
 
+static int parse_cls_flower(struct mlx5e_priv *priv,
+			    u32 *match_c, u32 *match_v,
+			    struct tc_cls_flower_offload *f)
+{
+	void *headers_c = MLX5_ADDR_OF(fte_match_param, match_c, outer_headers);
+	void *headers_v = MLX5_ADDR_OF(fte_match_param, match_v, outer_headers);
+	u16 addr_type = 0;
+	u8 ip_proto = 0;
+
+	if (f->dissector->used_keys &
+	    ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
+	      BIT(FLOW_DISSECTOR_KEY_BASIC) |
+	      BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
+	      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
+	      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
+	      BIT(FLOW_DISSECTOR_KEY_PORTS))) {
+		netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n",
+			    f->dissector->used_keys);
+		return -EOPNOTSUPP;
+	}
+
+	if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
+		struct flow_dissector_key_control *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_BASIC,
+						  f->key);
+		addr_type = key->addr_type;
+	}
+
+	if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
+		struct flow_dissector_key_basic *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_BASIC,
+						  f->key);
+		struct flow_dissector_key_basic *mask =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_BASIC,
+						  f->mask);
+		ip_proto = key->ip_proto;
+
+		MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype,
+			 ntohs(mask->n_proto));
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype,
+			 ntohs(key->n_proto));
+
+		MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
+			 mask->ip_proto);
+		MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
+			 key->ip_proto);
+	}
+
+	if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
+		struct flow_dissector_key_eth_addrs *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_ETH_ADDRS,
+						  f->key);
+		struct flow_dissector_key_eth_addrs *mask =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_ETH_ADDRS,
+						  f->mask);
+
+		ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
+					     dmac_47_16),
+				mask->dst);
+		ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
+					     dmac_47_16),
+				key->dst);
+
+		ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
+					     smac_47_16),
+				mask->src);
+		ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
+					     smac_47_16),
+				key->src);
+	}
+
+	if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+		struct flow_dissector_key_ipv4_addrs *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+						  f->key);
+		struct flow_dissector_key_ipv4_addrs *mask =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+						  f->mask);
+
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
+				    src_ipv4_src_ipv6.ipv4_layout.ipv4),
+		       &mask->src, sizeof(mask->src));
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
+				    src_ipv4_src_ipv6.ipv4_layout.ipv4),
+		       &key->src, sizeof(key->src));
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
+				    dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
+		       &mask->dst, sizeof(mask->dst));
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
+				    dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
+		       &key->dst, sizeof(key->dst));
+	}
+
+	if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+		struct flow_dissector_key_ipv6_addrs *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+						  f->key);
+		struct flow_dissector_key_ipv6_addrs *mask =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_IPV6_ADDRS,
+						  f->mask);
+
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
+				    src_ipv4_src_ipv6.ipv6_layout.ipv6),
+		       &mask->src, sizeof(mask->src));
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
+				    src_ipv4_src_ipv6.ipv6_layout.ipv6),
+		       &key->src, sizeof(key->src));
+
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
+				    dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+		       &mask->dst, sizeof(mask->dst));
+		memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
+				    dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
+		       &key->dst, sizeof(key->dst));
+	}
+
+	if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
+		struct flow_dissector_key_ports *key =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_PORTS,
+						  f->key);
+		struct flow_dissector_key_ports *mask =
+			skb_flow_dissector_target(f->dissector,
+						  FLOW_DISSECTOR_KEY_PORTS,
+						  f->mask);
+		switch (ip_proto) {
+		case IPPROTO_TCP:
+			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
+				 tcp_sport, ntohs(mask->src));
+			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
+				 tcp_sport, ntohs(key->src));
+
+			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
+				 tcp_dport, ntohs(mask->dst));
+			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
+				 tcp_dport, ntohs(key->dst));
+			break;
+
+		case IPPROTO_UDP:
+			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
+				 udp_sport, ntohs(mask->src));
+			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
+				 udp_sport, ntohs(key->src));
+
+			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
+				 udp_dport, ntohs(mask->dst));
+			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
+				 udp_dport, ntohs(key->dst));
+			break;
+		default:
+			netdev_err(priv->netdev,
+				   "Only UDP and TCP transport are supported\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int parse_tc_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
+			    u32 *action, u32 *flow_tag)
+{
+	const struct tc_action *a;
+
+	if (tc_no_actions(exts))
+		return -EINVAL;
+
+	*flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
+	*action = 0;
+
+	tc_for_each_action(a, exts) {
+		/* Only support a single action per rule */
+		if (*action)
+			return -EINVAL;
+
+		if (is_tcf_gact_shot(a)) {
+			*action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
+			continue;
+		}
+
+		if (is_tcf_skbedit_mark(a)) {
+			u32 mark = tcf_skbedit_mark(a);
+
+			if (mark & ~MLX5E_TC_FLOW_ID_MASK) {
+				netdev_warn(priv->netdev, "Bad flow mark - only 16 bit is supported: 0x%x\n",
+					    mark);
+				return -EINVAL;
+			}
+
+			*flow_tag = mark;
+			*action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+			continue;
+		}
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
+			   struct tc_cls_flower_offload *f)
+{
+	struct mlx5e_tc_flow_table *tc = &priv->fts.tc;
+	u32 *match_c;
+	u32 *match_v;
+	int err = 0;
+	u32 flow_tag;
+	u32 action;
+	struct mlx5e_tc_flow *flow;
+	struct mlx5_flow_rule *old = NULL;
+
+	flow = rhashtable_lookup_fast(&tc->ht, &f->cookie,
+				      tc->ht_params);
+	if (flow)
+		old = flow->rule;
+	else
+		flow = kzalloc(sizeof(*flow), GFP_KERNEL);
+
+	match_c = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+	match_v = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+	if (!match_c || !match_v || !flow) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	flow->cookie = f->cookie;
+
+	err = parse_cls_flower(priv, match_c, match_v, f);
+	if (err < 0)
+		goto err_free;
+
+	err = parse_tc_actions(priv, f->exts, &action, &flow_tag);
+	if (err < 0)
+		goto err_free;
+
+	err = rhashtable_insert_fast(&tc->ht, &flow->node,
+				     tc->ht_params);
+	if (err)
+		goto err_free;
+
+	flow->rule = mlx5e_tc_add_flow(priv, match_c, match_v, action,
+				       flow_tag);
+	if (IS_ERR(flow->rule)) {
+		err = PTR_ERR(flow->rule);
+		goto err_hash_del;
+	}
+
+	if (old)
+		mlx5e_tc_del_flow(priv, old);
+
+	goto out;
+
+err_hash_del:
+	rhashtable_remove_fast(&tc->ht, &flow->node, tc->ht_params);
+
+err_free:
+	if (!old)
+		kfree(flow);
+out:
+	kfree(match_c);
+	kfree(match_v);
+	return err;
+}
+
+int mlx5e_delete_flower(struct mlx5e_priv *priv,
+			struct tc_cls_flower_offload *f)
+{
+	struct mlx5e_tc_flow *flow;
+	struct mlx5e_tc_flow_table *tc = &priv->fts.tc;
+
+	flow = rhashtable_lookup_fast(&tc->ht, &f->cookie,
+				      tc->ht_params);
+	if (!flow)
+		return -EINVAL;
+
+	rhashtable_remove_fast(&tc->ht, &flow->node, tc->ht_params);
+
+	mlx5e_tc_del_flow(priv, flow->rule);
+
+	kfree(flow);
+
+	return 0;
+}
+
 static const struct rhashtable_params mlx5e_tc_flow_ht_params = {
 	.head_offset = offsetof(struct mlx5e_tc_flow, node),
 	.key_offset = offsetof(struct mlx5e_tc_flow, cookie),
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
index 46eacc5..70642f4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
@@ -36,6 +36,11 @@
 int mlx5e_tc_init(struct mlx5e_priv *priv);
 void mlx5e_tc_cleanup(struct mlx5e_priv *priv);
 
+int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
+			   struct tc_cls_flower_offload *f);
+int mlx5e_delete_flower(struct mlx5e_priv *priv,
+			struct tc_cls_flower_offload *f);
+
 static inline int mlx5e_tc_num_filters(struct mlx5e_priv *priv)
 {
 	return atomic_read(&priv->fts.tc.ht.nelems);
-- 
2.7.0

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

* [PATCH net-next V2 10/10] net/mlx5e: Support offload cls_flower with skbedit mark action
  2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
                   ` (8 preceding siblings ...)
  2016-03-03 14:55 ` [PATCH net-next V2 09/10] net/mlx5e: Support offload cls_flower with drop action Amir Vadai
@ 2016-03-03 14:56 ` Amir Vadai
  9 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 14:56 UTC (permalink / raw
  To: David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim, Amir Vadai

Introduce offloading of skbedit mark action.

For example, to mark with 0x1234, all TCP (ip_proto 6) packets arriving
to interface ens9:

 # tc qdisc add dev ens9 ingress
 # tc filter add dev ens9 protocol ip parent ffff: \
     flower ip_proto 6 \
     indev ens9 \
     action skbedit mark 0x1234

Signed-off-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 3 +++
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 1 +
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 519a07f..f293afe 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -35,6 +35,7 @@
 #include <linux/tcp.h>
 #include <net/busy_poll.h>
 #include "en.h"
+#include "en_tc.h"
 
 static inline bool mlx5e_rx_hw_stamp(struct mlx5e_tstamp *tstamp)
 {
@@ -224,6 +225,8 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
 	if (cqe_has_vlan(cqe))
 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
 				       be16_to_cpu(cqe->vlan_info));
+
+	skb->mark = be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK;
 }
 
 int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 3aea5da..544c739 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -33,6 +33,7 @@
 #include <net/flow_dissector.h>
 #include <net/pkt_cls.h>
 #include <net/tc_act/tc_gact.h>
+#include <net/tc_act/tc_skbedit.h>
 #include <linux/mlx5/fs.h>
 #include <linux/mlx5/device.h>
 #include <linux/rhashtable.h>
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
index 70642f4..d677428 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
@@ -33,6 +33,8 @@
 #ifndef __MLX5_EN_TC_H__
 #define __MLX5_EN_TC_H__
 
+#define MLX5E_TC_FLOW_ID_MASK 0x0000ffff
+
 int mlx5e_tc_init(struct mlx5e_priv *priv);
 void mlx5e_tc_cleanup(struct mlx5e_priv *priv);
 
-- 
2.7.0

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

* Re: [PATCH net-next V2 01/10] net/flower: Introduce hardware offload support
  2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
@ 2016-03-03 14:57   ` Jiri Pirko
  2016-03-03 17:30   ` David Miller
  2016-03-04 17:01   ` John Fastabend
  2 siblings, 0 replies; 27+ messages in thread
From: Jiri Pirko @ 2016-03-03 14:57 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, netdev, John Fastabend, Jiri Pirko, Or Gerlitz,
	Saeed Mahameed, Hadar Har-Zion, Rony Efraim

Thu, Mar 03, 2016 at 03:55:51PM CET, amir@vadai.me wrote:
>This patch is based on a patch made by John Fastabend.
>It adds support for offloading cls_flower.
>when NETIF_F_HW_TC is on:
>  flags = 0       => Rule will be processed twice - by hardware, and if
>                     still relevant, by software.
>  flags = SKIP_HW => Rull will be processed by software only
>
>If hardare fail/not capabale to apply the rule, operation will fail.
>
>Suggested-by: John Fastabend <john.r.fastabend@intel.com>
>Signed-off-by: Amir Vadai <amir@vadai.me>

Acked-by: Jiri Pirko <jiri@mellanox.com>

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

* Re: [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public
  2016-03-03 14:55 ` [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public Amir Vadai
@ 2016-03-03 14:57   ` Jiri Pirko
  2016-03-04 16:55   ` John Fastabend
  1 sibling, 0 replies; 27+ messages in thread
From: Jiri Pirko @ 2016-03-03 14:57 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, netdev, John Fastabend, Jiri Pirko, Or Gerlitz,
	Saeed Mahameed, Hadar Har-Zion, Rony Efraim

Thu, Mar 03, 2016 at 03:55:52PM CET, amir@vadai.me wrote:
>Will be used in a following patch to query if a key is being used, and
>what it's value in the target object.
>
>Signed-off-by: Amir Vadai <amir@vadai.me>

Acked-by: Jiri Pirko <jiri@mellanox.com>

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

* Re: [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-03 14:55 ` [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef Amir Vadai
@ 2016-03-03 14:57   ` Jiri Pirko
  2016-03-03 17:45   ` Cong Wang
  2016-03-04 16:54   ` John Fastabend
  2 siblings, 0 replies; 27+ messages in thread
From: Jiri Pirko @ 2016-03-03 14:57 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, netdev, John Fastabend, Jiri Pirko, Or Gerlitz,
	Saeed Mahameed, Hadar Har-Zion, Rony Efraim

Thu, Mar 03, 2016 at 03:55:53PM CET, amir@vadai.me wrote:
>Introduce the macros tc_no_actions and tc_for_each_action to make code
>clearer.
>
>Suggested-by: Jiri Pirko <jiri@mellanox.com>
>Signed-off-by: Amir Vadai <amir@vadai.me>

Acked-by: Jiri Pirko <jiri@mellanox.com>

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

* Re: [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action
  2016-03-03 14:55 ` [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action Amir Vadai
@ 2016-03-03 14:57   ` Jiri Pirko
  2016-03-03 17:48   ` Cong Wang
  1 sibling, 0 replies; 27+ messages in thread
From: Jiri Pirko @ 2016-03-03 14:57 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, netdev, John Fastabend, Jiri Pirko, Or Gerlitz,
	Saeed Mahameed, Hadar Har-Zion, Rony Efraim

Thu, Mar 03, 2016 at 03:55:54PM CET, amir@vadai.me wrote:
>Enable device drivers to query the action if is a mark action and what
>value to use for marking.
>
>Signed-off-by: Amir Vadai <amir@vadai.me>

Acked-by: Jiri Pirko <jiri@mellanox.com>

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

* Re: [PATCH net-next V2 01/10] net/flower: Introduce hardware offload support
  2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
@ 2016-03-03 17:30   ` David Miller
  2016-03-03 19:53     ` Amir Vadai"
  2016-03-04 17:01   ` John Fastabend
  2 siblings, 1 reply; 27+ messages in thread
From: David Miller @ 2016-03-03 17:30 UTC (permalink / raw
  To: amir; +Cc: netdev, john.r.fastabend, jiri, ogerlitz, saeedm, hadarh, ronye

From: Amir Vadai <amir@vadai.me>
Date: Thu,  3 Mar 2016 16:55:51 +0200

> @@ -454,11 +501,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
>  		     u32 handle, struct nlattr **tca,
>  		     unsigned long *arg, bool ovr)
>  {
> +	struct net_device *dev = tp->q->dev_queue->dev;
>  	struct cls_fl_head *head = rtnl_dereference(tp->root);

This variable is not used.

And the compiler warns about this, and because of this I am pretty sure you
aren't looking at the compiler output while testing your builds which is a
big no-no.

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

* Re: [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-03 14:55 ` [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
@ 2016-03-03 17:45   ` Cong Wang
  2016-03-03 19:51     ` Amir Vadai
  2016-03-04 16:54   ` John Fastabend
  2 siblings, 1 reply; 27+ messages in thread
From: Cong Wang @ 2016-03-03 17:45 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, Linux Kernel Network Developers, John Fastabend,
	Jiri Pirko, Or Gerlitz, Saeed Mahameed, Hadar Har-Zion,
	Rony Efraim

On Thu, Mar 3, 2016 at 6:55 AM, Amir Vadai <amir@vadai.me> wrote:
> Introduce the macros tc_no_actions and tc_for_each_action to make code
> clearer.
>
> Suggested-by: Jiri Pirko <jiri@mellanox.com>
> Signed-off-by: Amir Vadai <amir@vadai.me>
> ---
>  include/net/act_api.h        | 21 ++++++++++++++++-----
>  include/net/tc_act/tc_gact.h |  4 ++--
>  2 files changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/include/net/act_api.h b/include/net/act_api.h
> index 342be6c..2a19fe1 100644
> --- a/include/net/act_api.h
> +++ b/include/net/act_api.h
> @@ -78,11 +78,6 @@ static inline void tcf_lastuse_update(struct tcf_t *tm)
>                 tm->lastuse = now;
>  }
>
> -#ifdef CONFIG_NET_CLS_ACT
> -
> -#define ACT_P_CREATED 1
> -#define ACT_P_DELETED 1
> -
>  struct tc_action {
>         void                    *priv;
>         const struct tc_action_ops      *ops;
> @@ -92,6 +87,11 @@ struct tc_action {
>         struct tcf_hashinfo     *hinfo;
>  };

You also expose struct tc_action out of CONFIG_NET_CLS_ACT,
which you never mention in your changelog at all.

So why?

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

* Re: [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action
  2016-03-03 14:55 ` [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
@ 2016-03-03 17:48   ` Cong Wang
  2016-03-03 19:58     ` Amir Vadai
  1 sibling, 1 reply; 27+ messages in thread
From: Cong Wang @ 2016-03-03 17:48 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, Linux Kernel Network Developers, John Fastabend,
	Jiri Pirko, Or Gerlitz, Saeed Mahameed, Hadar Har-Zion,
	Rony Efraim

On Thu, Mar 3, 2016 at 6:55 AM, Amir Vadai <amir@vadai.me> wrote:
> +static inline bool is_tcf_skbedit_mark(const struct tc_action *a)
> +{
> +#ifdef CONFIG_NET_CLS_ACT
> +       if (a->ops && a->ops->type == TCA_ACT_SKBEDIT)
> +               return to_skbedit(a)->flags == SKBEDIT_F_MARK;


You mean to_skbedit(a)->flags & SKBEDIT_F_MARK ?

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

* Re: [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-03 17:45   ` Cong Wang
@ 2016-03-03 19:51     ` Amir Vadai
  2016-03-04 18:20       ` Cong Wang
  0 siblings, 1 reply; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 19:51 UTC (permalink / raw
  To: Cong Wang
  Cc: David S. Miller, Linux Kernel Network Developers, John Fastabend,
	Jiri Pirko, Or Gerlitz, Saeed Mahameed, Hadar Har-Zion,
	Rony Efraim

On Thu, Mar 03, 2016 at 09:45:28AM -0800, Cong Wang wrote:
> On Thu, Mar 3, 2016 at 6:55 AM, Amir Vadai <amir@vadai.me> wrote:
> > Introduce the macros tc_no_actions and tc_for_each_action to make code
> > clearer.
> >
> > Suggested-by: Jiri Pirko <jiri@mellanox.com>
> > Signed-off-by: Amir Vadai <amir@vadai.me>
> > ---
> >  include/net/act_api.h        | 21 ++++++++++++++++-----
> >  include/net/tc_act/tc_gact.h |  4 ++--
> >  2 files changed, 18 insertions(+), 7 deletions(-)
> >
> > diff --git a/include/net/act_api.h b/include/net/act_api.h
> > index 342be6c..2a19fe1 100644
> > --- a/include/net/act_api.h
> > +++ b/include/net/act_api.h
> > @@ -78,11 +78,6 @@ static inline void tcf_lastuse_update(struct tcf_t *tm)
> >                 tm->lastuse = now;
> >  }
> >
> > -#ifdef CONFIG_NET_CLS_ACT
> > -
> > -#define ACT_P_CREATED 1
> > -#define ACT_P_DELETED 1
> > -
> >  struct tc_action {
> >         void                    *priv;
> >         const struct tc_action_ops      *ops;
> > @@ -92,6 +87,11 @@ struct tc_action {
> >         struct tcf_hashinfo     *hinfo;
> >  };
> 
> You also expose struct tc_action out of CONFIG_NET_CLS_ACT,
> which you never mention in your changelog at all.
Yes - it was a mistake not to mention it in the changelog.

> 
> So why?
The struct will not be used, and without exposing it, the compiler will
complain on code like I have in patch 9/10 ("net/mlx5e: Support offload
cls_flower with drop action"):

static int parse_tc_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
			    u32 *action, u32 *flow_tag)
{
	const struct tc_action *a;

	if (tc_no_actions(exts))
		return -EINVAL;

	*flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
	*action = 0;

	tc_for_each_action(a, exts) {

[...]

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

* Re: [PATCH net-next V2 01/10] net/flower: Introduce hardware offload support
  2016-03-03 17:30   ` David Miller
@ 2016-03-03 19:53     ` Amir Vadai"
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai" @ 2016-03-03 19:53 UTC (permalink / raw
  To: David Miller
  Cc: netdev, john.r.fastabend, jiri, ogerlitz, saeedm, hadarh, ronye

On Thu, Mar 03, 2016 at 12:30:33PM -0500, David Miller wrote:
> From: Amir Vadai <amir@vadai.me>
> Date: Thu,  3 Mar 2016 16:55:51 +0200
> 
> > @@ -454,11 +501,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
> >  		     u32 handle, struct nlattr **tca,
> >  		     unsigned long *arg, bool ovr)
> >  {
> > +	struct net_device *dev = tp->q->dev_queue->dev;
> >  	struct cls_fl_head *head = rtnl_dereference(tp->root);
> 
> This variable is not used.
> 
> And the compiler warns about this, and because of this I am pretty sure you
> aren't looking at the compiler output while testing your builds which is a
> big no-no.
My bad. I did a last minute change that left this variable and somehow
missed the warning (though I did compile and test it).
Will fix for v3

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

* Re: [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action
  2016-03-03 17:48   ` Cong Wang
@ 2016-03-03 19:58     ` Amir Vadai
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-03 19:58 UTC (permalink / raw
  To: Cong Wang
  Cc: David S. Miller, Linux Kernel Network Developers, John Fastabend,
	Jiri Pirko, Or Gerlitz, Saeed Mahameed, Hadar Har-Zion,
	Rony Efraim

On Thu, Mar 03, 2016 at 09:48:40AM -0800, Cong Wang wrote:
> On Thu, Mar 3, 2016 at 6:55 AM, Amir Vadai <amir@vadai.me> wrote:
> > +static inline bool is_tcf_skbedit_mark(const struct tc_action *a)
> > +{
> > +#ifdef CONFIG_NET_CLS_ACT
> > +       if (a->ops && a->ops->type == TCA_ACT_SKBEDIT)
> > +               return to_skbedit(a)->flags == SKBEDIT_F_MARK;
> 
> 
> You mean to_skbedit(a)->flags & SKBEDIT_F_MARK ?
I will add a comment in v3 - it is on purpose. The function return true
iff the function is mark - other actions should not be offloaded.

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

* Re: [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-03 14:55 ` [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
  2016-03-03 17:45   ` Cong Wang
@ 2016-03-04 16:54   ` John Fastabend
  2 siblings, 0 replies; 27+ messages in thread
From: John Fastabend @ 2016-03-04 16:54 UTC (permalink / raw
  To: Amir Vadai, David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim

On 16-03-03 06:55 AM, Amir Vadai wrote:
> Introduce the macros tc_no_actions and tc_for_each_action to make code
> clearer.
> 
> Suggested-by: Jiri Pirko <jiri@mellanox.com>
> Signed-off-by: Amir Vadai <amir@vadai.me>
> ---

Acked-by: John Fastabend <john.r.fastabend@intel.com>

This should clean up the driver implementation a bit thanks.

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

* Re: [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public
  2016-03-03 14:55 ` [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
@ 2016-03-04 16:55   ` John Fastabend
  1 sibling, 0 replies; 27+ messages in thread
From: John Fastabend @ 2016-03-04 16:55 UTC (permalink / raw
  To: Amir Vadai, David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim

On 16-03-03 06:55 AM, Amir Vadai wrote:
> Will be used in a following patch to query if a key is being used, and
> what it's value in the target object.
> 
> Signed-off-by: Amir Vadai <amir@vadai.me>
> ---

Acked-by: John Fastabend <john.r.fastabend@intel.com>

Looks like you might roll a v3 feel free to pull these acks forward
as well.

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

* Re: [PATCH net-next V2 01/10] net/flower: Introduce hardware offload support
  2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
  2016-03-03 14:57   ` Jiri Pirko
  2016-03-03 17:30   ` David Miller
@ 2016-03-04 17:01   ` John Fastabend
  2016-03-06  9:00     ` Amir Vadai
  2 siblings, 1 reply; 27+ messages in thread
From: John Fastabend @ 2016-03-04 17:01 UTC (permalink / raw
  To: Amir Vadai, David S. Miller
  Cc: netdev, John Fastabend, Jiri Pirko, Or Gerlitz, Saeed Mahameed,
	Hadar Har-Zion, Rony Efraim

On 16-03-03 06:55 AM, Amir Vadai wrote:
> This patch is based on a patch made by John Fastabend.
> It adds support for offloading cls_flower.
> when NETIF_F_HW_TC is on:
>   flags = 0       => Rule will be processed twice - by hardware, and if
>                      still relevant, by software.
>   flags = SKIP_HW => Rull will be processed by software only
> 
> If hardare fail/not capabale to apply the rule, operation will fail.
> 
> Suggested-by: John Fastabend <john.r.fastabend@intel.com>
> Signed-off-by: Amir Vadai <amir@vadai.me>
> ---

[...]

>  static bool fl_destroy(struct tcf_proto *tp, bool force)
>  {
>  	struct cls_fl_head *head = rtnl_dereference(tp->root);
> @@ -174,6 +220,7 @@ static bool fl_destroy(struct tcf_proto *tp, bool force)
>  		return false;
>  
>  	list_for_each_entry_safe(f, next, &head->filters, list) {
> +		fl_hw_destroy_filter(tp, (u64)f);
>  		list_del_rcu(&f->list);
>  		call_rcu(&f->rcu, fl_destroy_filter);
>  	}
> @@ -454,11 +501,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
>  		     u32 handle, struct nlattr **tca,
>  		     unsigned long *arg, bool ovr)
>  {
> +	struct net_device *dev = tp->q->dev_queue->dev;
>  	struct cls_fl_head *head = rtnl_dereference(tp->root);
>  	struct cls_fl_filter *fold = (struct cls_fl_filter *) *arg;
>  	struct cls_fl_filter *fnew;
>  	struct nlattr *tb[TCA_FLOWER_MAX + 1];
>  	struct fl_flow_mask mask = {};
> +	u32 flags = 0;
>  	int err;
>  
>  	if (!tca[TCA_OPTIONS])
> @@ -486,6 +535,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
>  	}
>  	fnew->handle = handle;
>  
> +	if (tb[TCA_FLOWER_FLAGS])
> +		flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
> +
>  	err = fl_set_parms(net, tp, fnew, &mask, base, tb, tca[TCA_RATE], ovr);
>  	if (err)
>  		goto errout;
> @@ -498,9 +550,22 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
>  				     head->ht_params);
>  	if (err)
>  		goto errout;
> -	if (fold)
> +
> +	err = fl_hw_replace_filter(tp,
> +				   &head->dissector,
> +				   &mask.key,
> +				   &fnew->key,
> +				   &fnew->exts,
> +				   (u64)fnew,
> +				   flags);
> +	if (err)
> +		goto err_hash_remove;
> +

This behaviour is different than how I did u32 in the u32 case I just
let the software case get loaded and do not throw any errors. The
intent was if we required a HW entry we would explicitly state that
with the SKIP_SW (to be implemented) flag. This error path seems
to block the software filter when the hardware fails.

I think it would be best to do the same as u32 here and use the error
path only if SKIP_SW is set. Or if you really want an error path on
SW/HW loads then use another bit in the flag to specify STRICT or
something along those lines.


> +	if (fold) {
>  		rhashtable_remove_fast(&head->ht, &fold->ht_node,
>  				       head->ht_params);
> +		fl_hw_destroy_filter(tp, (u64)fold);
> +	}
>  
>  	*arg = (unsigned long) fnew;
>  
> @@ -514,6 +579,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
>  
>  	return 0;
>  
> +err_hash_remove:
> +	rhashtable_remove_fast(&head->ht, &fnew->ht_node, head->ht_params);
> +
>  errout:
>  	kfree(fnew);
>  	return err;
> @@ -527,6 +595,7 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
>  	rhashtable_remove_fast(&head->ht, &f->ht_node,
>  			       head->ht_params);
>  	list_del_rcu(&f->list);
> +	fl_hw_destroy_filter(tp, (u64)f);
>  	tcf_unbind_filter(tp, &f->res);
>  	call_rcu(&f->rcu, fl_destroy_filter);
>  	return 0;
> 

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

* Re: [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-03 19:51     ` Amir Vadai
@ 2016-03-04 18:20       ` Cong Wang
  2016-03-06  8:54         ` Amir Vadai
  0 siblings, 1 reply; 27+ messages in thread
From: Cong Wang @ 2016-03-04 18:20 UTC (permalink / raw
  To: Amir Vadai
  Cc: David S. Miller, Linux Kernel Network Developers, John Fastabend,
	Jiri Pirko, Or Gerlitz, Saeed Mahameed, Hadar Har-Zion,
	Rony Efraim

On Thu, Mar 3, 2016 at 11:51 AM, Amir Vadai <amir@vadai.me> wrote:
> On Thu, Mar 03, 2016 at 09:45:28AM -0800, Cong Wang wrote:
>>
>> So why?
> The struct will not be used, and without exposing it, the compiler will
> complain on code like I have in patch 9/10 ("net/mlx5e: Support offload
> cls_flower with drop action"):
>
> static int parse_tc_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
>                             u32 *action, u32 *flow_tag)

Why not make this a nop when CONFIG_NET_CLS_ACT is not set?

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

* Re: [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef
  2016-03-04 18:20       ` Cong Wang
@ 2016-03-06  8:54         ` Amir Vadai
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-06  8:54 UTC (permalink / raw
  To: Cong Wang
  Cc: David S. Miller, Linux Kernel Network Developers, John Fastabend,
	Jiri Pirko, Or Gerlitz, Saeed Mahameed, Hadar Har-Zion,
	Rony Efraim

On Fri, Mar 04, 2016 at 10:20:18AM -0800, Cong Wang wrote:
> On Thu, Mar 3, 2016 at 11:51 AM, Amir Vadai <amir@vadai.me> wrote:
> > On Thu, Mar 03, 2016 at 09:45:28AM -0800, Cong Wang wrote:
> >>
> >> So why?
> > The struct will not be used, and without exposing it, the compiler will
> > complain on code like I have in patch 9/10 ("net/mlx5e: Support offload
> > cls_flower with drop action"):
> >
> > static int parse_tc_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
> >                             u32 *action, u32 *flow_tag)
> 
> Why not make this a nop when CONFIG_NET_CLS_ACT is not set?

In V0 I did make it a nop. Jiri has suggested [1] that I will replace
the ifdefs with the macro's tc_for_each_action and is_tcf_gact_shot. And
I do think it looks more elegant.

Why do you think it is a problem to expose truct tc_action?

Thanks for your review,
Amir

[1] - https://patchwork.ozlabs.org/patch/590550/

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

* Re: [PATCH net-next V2 01/10] net/flower: Introduce hardware offload support
  2016-03-04 17:01   ` John Fastabend
@ 2016-03-06  9:00     ` Amir Vadai
  0 siblings, 0 replies; 27+ messages in thread
From: Amir Vadai @ 2016-03-06  9:00 UTC (permalink / raw
  To: John Fastabend
  Cc: David S. Miller, netdev, John Fastabend, Jiri Pirko, Or Gerlitz,
	Saeed Mahameed, Hadar Har-Zion, Rony Efraim

On Fri, Mar 04, 2016 at 09:01:39AM -0800, John Fastabend wrote:
> On 16-03-03 06:55 AM, Amir Vadai wrote:
> > This patch is based on a patch made by John Fastabend.
> > It adds support for offloading cls_flower.
> > when NETIF_F_HW_TC is on:
> >   flags = 0       => Rule will be processed twice - by hardware, and if
> >                      still relevant, by software.
> >   flags = SKIP_HW => Rull will be processed by software only
> > 
> > If hardare fail/not capabale to apply the rule, operation will fail.
> > 
> > Suggested-by: John Fastabend <john.r.fastabend@intel.com>
> > Signed-off-by: Amir Vadai <amir@vadai.me>
> > ---
> 
> [...]
> 
> >  static bool fl_destroy(struct tcf_proto *tp, bool force)
> >  {
> >  	struct cls_fl_head *head = rtnl_dereference(tp->root);
> > @@ -174,6 +220,7 @@ static bool fl_destroy(struct tcf_proto *tp, bool force)
> >  		return false;
> >  
> >  	list_for_each_entry_safe(f, next, &head->filters, list) {
> > +		fl_hw_destroy_filter(tp, (u64)f);
> >  		list_del_rcu(&f->list);
> >  		call_rcu(&f->rcu, fl_destroy_filter);
> >  	}
> > @@ -454,11 +501,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
> >  		     u32 handle, struct nlattr **tca,
> >  		     unsigned long *arg, bool ovr)
> >  {
> > +	struct net_device *dev = tp->q->dev_queue->dev;
> >  	struct cls_fl_head *head = rtnl_dereference(tp->root);
> >  	struct cls_fl_filter *fold = (struct cls_fl_filter *) *arg;
> >  	struct cls_fl_filter *fnew;
> >  	struct nlattr *tb[TCA_FLOWER_MAX + 1];
> >  	struct fl_flow_mask mask = {};
> > +	u32 flags = 0;
> >  	int err;
> >  
> >  	if (!tca[TCA_OPTIONS])
> > @@ -486,6 +535,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
> >  	}
> >  	fnew->handle = handle;
> >  
> > +	if (tb[TCA_FLOWER_FLAGS])
> > +		flags = nla_get_u32(tb[TCA_FLOWER_FLAGS]);
> > +
> >  	err = fl_set_parms(net, tp, fnew, &mask, base, tb, tca[TCA_RATE], ovr);
> >  	if (err)
> >  		goto errout;
> > @@ -498,9 +550,22 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
> >  				     head->ht_params);
> >  	if (err)
> >  		goto errout;
> > -	if (fold)
> > +
> > +	err = fl_hw_replace_filter(tp,
> > +				   &head->dissector,
> > +				   &mask.key,
> > +				   &fnew->key,
> > +				   &fnew->exts,
> > +				   (u64)fnew,
> > +				   flags);
> > +	if (err)
> > +		goto err_hash_remove;
> > +
> 
> This behaviour is different than how I did u32 in the u32 case I just
> let the software case get loaded and do not throw any errors. The
> intent was if we required a HW entry we would explicitly state that
> with the SKIP_SW (to be implemented) flag. This error path seems
> to block the software filter when the hardware fails.
Makes sense.

> 
> I think it would be best to do the same as u32 here and use the error
> path only if SKIP_SW is set. Or if you really want an error path on
> SW/HW loads then use another bit in the flag to specify STRICT or
> something along those lines.
I will do the same as u32. I won't add this STRICT flag, because I don't
have any use case for this mode in which processing is done in both SW
and HW.

> 
> 
> > +	if (fold) {
> >  		rhashtable_remove_fast(&head->ht, &fold->ht_node,
> >  				       head->ht_params);
> > +		fl_hw_destroy_filter(tp, (u64)fold);
> > +	}
> >  
> >  	*arg = (unsigned long) fnew;
> >  
> > @@ -514,6 +579,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
> >  
> >  	return 0;
> >  
> > +err_hash_remove:
> > +	rhashtable_remove_fast(&head->ht, &fnew->ht_node, head->ht_params);
> > +
> >  errout:
> >  	kfree(fnew);
> >  	return err;
> > @@ -527,6 +595,7 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
> >  	rhashtable_remove_fast(&head->ht, &f->ht_node,
> >  			       head->ht_params);
> >  	list_del_rcu(&f->list);
> > +	fl_hw_destroy_filter(tp, (u64)f);
> >  	tcf_unbind_filter(tp, &f->res);
> >  	call_rcu(&f->rcu, fl_destroy_filter);
> >  	return 0;
> > 
> 

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

end of thread, other threads:[~2016-03-06  8:56 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-03 14:55 [PATCH net-next V2 00/10] cls_flower hardware offload support Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 01/10] net/flower: Introduce " Amir Vadai
2016-03-03 14:57   ` Jiri Pirko
2016-03-03 17:30   ` David Miller
2016-03-03 19:53     ` Amir Vadai"
2016-03-04 17:01   ` John Fastabend
2016-03-06  9:00     ` Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 02/10] net/flow_dissector: Make dissector_uses_key() and skb_flow_dissector_target() public Amir Vadai
2016-03-03 14:57   ` Jiri Pirko
2016-03-04 16:55   ` John Fastabend
2016-03-03 14:55 ` [PATCH net-next V2 03/10] net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef Amir Vadai
2016-03-03 14:57   ` Jiri Pirko
2016-03-03 17:45   ` Cong Wang
2016-03-03 19:51     ` Amir Vadai
2016-03-04 18:20       ` Cong Wang
2016-03-06  8:54         ` Amir Vadai
2016-03-04 16:54   ` John Fastabend
2016-03-03 14:55 ` [PATCH net-next V2 04/10] net/act_skbedit: Utility functions for mark action Amir Vadai
2016-03-03 14:57   ` Jiri Pirko
2016-03-03 17:48   ` Cong Wang
2016-03-03 19:58     ` Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 05/10] net/mlx5_core: Set flow steering dest only for forward rules Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 06/10] net/mlx5e: Relax ndo_setup_tc handle restriction Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 07/10] net/mlx5e: Add a new priority for kernel flow tables Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 08/10] net/mlx5e: Introduce tc offload support Amir Vadai
2016-03-03 14:55 ` [PATCH net-next V2 09/10] net/mlx5e: Support offload cls_flower with drop action Amir Vadai
2016-03-03 14:56 ` [PATCH net-next V2 10/10] net/mlx5e: Support offload cls_flower with skbedit mark action Amir Vadai

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.