All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev
@ 2017-10-10  7:30 Jiri Pirko
  2017-10-10  7:30 ` [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net Jiri Pirko
                   ` (5 more replies)
  0 siblings, 6 replies; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10  7:30 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Introduction of cls_flower->egress_dev was a workaround. Turned out
to be a bit ugly hack. So replace it with more generic and reusable
infrastructure.

This is a dependency of shared block introduction that will be send as
a follow-up patchsets group.

Jiri Pirko (4):
  net: sched: make tc_action_ops->get_dev return dev and avoid passing
    net
  net: sched: introduce per-egress action device callbacks
  net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev
    infra
  net: sched: remove unused tcf_exts_get_dev helper and
    cls_flower->egress_dev

 drivers/net/ethernet/mellanox/mlx5/core/en.h      |   3 +
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c |   4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c  |  31 ++--
 include/net/act_api.h                             |  37 +++-
 include/net/pkt_cls.h                             |   6 +-
 include/net/tc_act/tc_mirred.h                    |   1 +
 net/sched/act_api.c                               | 203 ++++++++++++++++++++++
 net/sched/act_mirred.c                            |  13 +-
 net/sched/cls_api.c                               |  35 ++--
 net/sched/cls_flower.c                            |  63 +++----
 10 files changed, 331 insertions(+), 65 deletions(-)

-- 
2.9.5

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

* [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net
  2017-10-10  7:30 [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Jiri Pirko
@ 2017-10-10  7:30 ` Jiri Pirko
  2017-10-10 17:44   ` Cong Wang
  2017-10-10  7:30 ` [patch net-next 2/4] net: sched: introduce per-egress action device callbacks Jiri Pirko
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10  7:30 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Return dev directly, NULL if not possible. That is enough.

Makes no sense to pass struct net * to get_dev op, as there is only one
net possible, the one the action was created in. So just store it in
mirred priv and use directly.

Rename the mirred op callback function.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/act_api.h          |  3 +--
 include/net/tc_act/tc_mirred.h |  1 +
 net/sched/act_mirred.c         | 13 +++++--------
 net/sched/cls_api.c            |  6 ++----
 4 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index b944e0e..900168a 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -93,8 +93,7 @@ struct tc_action_ops {
 	int     (*walk)(struct net *, struct sk_buff *,
 			struct netlink_callback *, int, const struct tc_action_ops *);
 	void	(*stats_update)(struct tc_action *, u64, u32, u64);
-	int	(*get_dev)(const struct tc_action *a, struct net *net,
-			   struct net_device **mirred_dev);
+	struct net_device *(*get_dev)(const struct tc_action *a);
 };
 
 struct tc_action_net {
diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
index 604bc31..21a6565 100644
--- a/include/net/tc_act/tc_mirred.h
+++ b/include/net/tc_act/tc_mirred.h
@@ -10,6 +10,7 @@ struct tcf_mirred {
 	int			tcfm_ifindex;
 	bool			tcfm_mac_header_xmit;
 	struct net_device __rcu	*tcfm_dev;
+	struct net		*net;
 	struct list_head	tcfm_list;
 };
 #define to_mirred(a) ((struct tcf_mirred *)a)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 416627c..8b3e5938 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -140,6 +140,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
 	m->tcfm_eaction = parm->eaction;
 	if (dev != NULL) {
 		m->tcfm_ifindex = parm->ifindex;
+		m->net = net;
 		if (ret != ACT_P_CREATED)
 			dev_put(rcu_dereference_protected(m->tcfm_dev, 1));
 		dev_hold(dev);
@@ -313,15 +314,11 @@ static struct notifier_block mirred_device_notifier = {
 	.notifier_call = mirred_device_event,
 };
 
-static int tcf_mirred_device(const struct tc_action *a, struct net *net,
-			     struct net_device **mirred_dev)
+static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
 {
-	int ifindex = tcf_mirred_ifindex(a);
+	struct tcf_mirred *m = to_mirred(a);
 
-	*mirred_dev = __dev_get_by_index(net, ifindex);
-	if (!*mirred_dev)
-		return -EINVAL;
-	return 0;
+	return __dev_get_by_index(m->net, m->tcfm_ifindex);
 }
 
 static struct tc_action_ops act_mirred_ops = {
@@ -336,7 +333,7 @@ static struct tc_action_ops act_mirred_ops = {
 	.walk		=	tcf_mirred_walker,
 	.lookup		=	tcf_mirred_search,
 	.size		=	sizeof(struct tcf_mirred),
-	.get_dev	=	tcf_mirred_device,
+	.get_dev	=	tcf_mirred_get_dev,
 };
 
 static __net_init int mirred_init_net(struct net *net)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 0b2219a..450873b 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1016,10 +1016,8 @@ int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
 
 	tcf_exts_to_list(exts, &actions);
 	list_for_each_entry(a, &actions, list) {
-		if (a->ops->get_dev) {
-			a->ops->get_dev(a, dev_net(dev), hw_dev);
-			break;
-		}
+		if (a->ops->get_dev)
+			*hw_dev = a->ops->get_dev(a);
 	}
 	if (*hw_dev)
 		return 0;
-- 
2.9.5

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

* [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
  2017-10-10  7:30 [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Jiri Pirko
  2017-10-10  7:30 ` [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net Jiri Pirko
@ 2017-10-10  7:30 ` Jiri Pirko
  2017-10-10 13:31   ` David Laight
  2017-10-10  7:30 ` [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra Jiri Pirko
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10  7:30 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Introduce infrastructure that allows drivers to register callbacks that
are called whenever tc would offload inserted rule and specified device
acts as tc action egress device.

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

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 900168a..f5e8c90 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -174,4 +174,38 @@ static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
 #endif
 }
 
+typedef int tc_setup_cb_t(enum tc_setup_type type,
+			  void *type_data, void *cb_priv);
+
+#ifdef CONFIG_NET_CLS_ACT
+int tc_setup_cb_egdev_register(const struct net_device *dev,
+			       tc_setup_cb_t *cb, void *cb_priv);
+void tc_setup_cb_egdev_unregister(const struct net_device *dev,
+				  tc_setup_cb_t *cb, void *cb_priv);
+int tc_setup_cb_egdev_call(const struct net_device *dev,
+			   enum tc_setup_type type, void *type_data,
+			   bool err_stop);
+#else
+static inline
+int tc_setup_cb_egdev_register(const struct net_device *dev,
+			       tc_setup_cb_t *cb, void *cb_priv)
+{
+	return 0;
+}
+
+static inline
+void tc_setup_cb_egdev_unregister(const struct net_device *dev,
+				  tc_setup_cb_t *cb, void *cb_priv)
+{
+}
+
+static inline
+int tc_setup_cb_egdev_call(const struct net_device *dev,
+			   enum tc_setup_type type, void *type_data,
+			   bool err_stop)
+{
+	return 0;
+}
+#endif
+
 #endif
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index e80edd8..6f8149c 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -206,6 +206,8 @@ 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,
 		     struct net_device **hw_dev);
+int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
+			   void *type_data, bool err_stop);
 
 /**
  * struct tcf_pkt_info - packet information
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index da6fa82..92a9efb 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -21,6 +21,8 @@
 #include <linux/kmod.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/rhashtable.h>
+#include <linux/list.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/sch_generic.h>
@@ -1249,8 +1251,209 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
+struct tcf_action_net {
+	struct rhashtable egdev_ht;
+};
+
+static unsigned int tcf_action_net_id;
+
+struct tcf_action_egdev_cb {
+	struct list_head list;
+	tc_setup_cb_t *cb;
+	void *cb_priv;
+};
+
+struct tcf_action_egdev {
+	struct rhash_head ht_node;
+	const struct net_device *dev;
+	unsigned int refcnt;
+	struct list_head cb_list;
+};
+
+static const struct rhashtable_params tcf_action_egdev_ht_params = {
+	.key_offset = offsetof(struct tcf_action_egdev, dev),
+	.head_offset = offsetof(struct tcf_action_egdev, ht_node),
+	.key_len = sizeof(const struct net_device *),
+};
+
+static struct tcf_action_egdev *
+tcf_action_egdev_lookup(const struct net_device *dev)
+{
+	struct net *net = dev_net(dev);
+	struct tcf_action_net *tan = net_generic(net, tcf_action_net_id);
+
+	return rhashtable_lookup_fast(&tan->egdev_ht, &dev,
+				      tcf_action_egdev_ht_params);
+}
+
+static struct tcf_action_egdev *
+tcf_action_egdev_get(const struct net_device *dev)
+{
+	struct tcf_action_egdev *egdev;
+	struct tcf_action_net *tan;
+
+	egdev = tcf_action_egdev_lookup(dev);
+	if (egdev)
+		goto inc_ref;
+
+	egdev = kzalloc(sizeof(*egdev), GFP_KERNEL);
+	if (!egdev)
+		return NULL;
+	INIT_LIST_HEAD(&egdev->cb_list);
+	tan = net_generic(dev_net(dev), tcf_action_net_id);
+	rhashtable_insert_fast(&tan->egdev_ht, &egdev->ht_node,
+			       tcf_action_egdev_ht_params);
+
+inc_ref:
+	egdev->refcnt++;
+	return egdev;
+}
+
+static void tcf_action_egdev_put(struct tcf_action_egdev *egdev)
+{
+	struct tcf_action_net *tan;
+
+	if (--egdev->refcnt)
+		return;
+	tan = net_generic(dev_net(egdev->dev), tcf_action_net_id);
+	rhashtable_remove_fast(&tan->egdev_ht, &egdev->ht_node,
+			       tcf_action_egdev_ht_params);
+	kfree(egdev);
+}
+
+static struct tcf_action_egdev_cb *
+tcf_action_egdev_cb_lookup(struct tcf_action_egdev *egdev,
+			   tc_setup_cb_t *cb, void *cb_priv)
+{
+	struct tcf_action_egdev_cb *egdev_cb;
+
+	list_for_each_entry(egdev_cb, &egdev->cb_list, list)
+		if (egdev_cb->cb == cb && egdev_cb->cb_priv == cb_priv)
+			return egdev_cb;
+	return NULL;
+}
+
+static int tcf_action_egdev_cb_call(struct tcf_action_egdev *egdev,
+				    enum tc_setup_type type,
+				    void *type_data, bool err_stop)
+{
+	struct tcf_action_egdev_cb *egdev_cb;
+	int ok_count = 0;
+	int err;
+
+	list_for_each_entry(egdev_cb, &egdev->cb_list, list) {
+		err = egdev_cb->cb(type, type_data, egdev_cb->cb_priv);
+		if (err) {
+			if (err_stop)
+				return err;
+		} else {
+			ok_count++;
+		}
+	}
+	return ok_count;
+}
+
+static int tcf_action_egdev_cb_add(struct tcf_action_egdev *egdev,
+				   tc_setup_cb_t *cb, void *cb_priv)
+{
+	struct tcf_action_egdev_cb *egdev_cb;
+
+	egdev_cb = tcf_action_egdev_cb_lookup(egdev, cb, cb_priv);
+	if (WARN_ON(egdev_cb))
+		return -EEXIST;
+	egdev_cb = kzalloc(sizeof(*egdev_cb), GFP_KERNEL);
+	if (!egdev_cb)
+		return -ENOMEM;
+	egdev_cb->cb = cb;
+	egdev_cb->cb_priv = cb_priv;
+	list_add(&egdev_cb->list, &egdev->cb_list);
+	return 0;
+}
+
+static void tcf_action_egdev_cb_del(struct tcf_action_egdev *egdev,
+				    tc_setup_cb_t *cb, void *cb_priv)
+{
+	struct tcf_action_egdev_cb *egdev_cb;
+
+	egdev_cb = tcf_action_egdev_cb_lookup(egdev, cb, cb_priv);
+	if (WARN_ON(!egdev_cb))
+		return;
+	list_del(&egdev_cb->list);
+	kfree(egdev_cb);
+}
+
+int tc_setup_cb_egdev_register(const struct net_device *dev,
+			       tc_setup_cb_t *cb, void *cb_priv)
+{
+	struct tcf_action_egdev *egdev = tcf_action_egdev_get(dev);
+	int err;
+
+	if (!egdev)
+		return -ENOMEM;
+	err = tcf_action_egdev_cb_add(egdev, cb, cb_priv);
+	if (err)
+		goto err_cb_add;
+	return 0;
+
+err_cb_add:
+	tcf_action_egdev_put(egdev);
+	return err;
+}
+EXPORT_SYMBOL_GPL(tc_setup_cb_egdev_register);
+
+void tc_setup_cb_egdev_unregister(const struct net_device *dev,
+				  tc_setup_cb_t *cb, void *cb_priv)
+{
+	struct tcf_action_egdev *egdev = tcf_action_egdev_lookup(dev);
+
+	if (WARN_ON(!egdev))
+		return;
+	tcf_action_egdev_cb_del(egdev, cb, cb_priv);
+	tcf_action_egdev_put(egdev);
+}
+EXPORT_SYMBOL_GPL(tc_setup_cb_egdev_unregister);
+
+int tc_setup_cb_egdev_call(const struct net_device *dev,
+			   enum tc_setup_type type, void *type_data,
+			   bool err_stop)
+{
+	struct tcf_action_egdev *egdev = tcf_action_egdev_lookup(dev);
+
+	if (!egdev)
+		return 0;
+	return tcf_action_egdev_cb_call(egdev, type, type_data, err_stop);
+}
+EXPORT_SYMBOL_GPL(tc_setup_cb_egdev_call);
+
+static __net_init int tcf_action_net_init(struct net *net)
+{
+	struct tcf_action_net *tan = net_generic(net, tcf_action_net_id);
+
+	return rhashtable_init(&tan->egdev_ht, &tcf_action_egdev_ht_params);
+}
+
+static void __net_exit tcf_action_net_exit(struct net *net)
+{
+	struct tcf_action_net *tan = net_generic(net, tcf_action_net_id);
+
+	rhashtable_destroy(&tan->egdev_ht);
+}
+
+static struct pernet_operations tcf_action_net_ops = {
+	.init = tcf_action_net_init,
+	.exit = tcf_action_net_exit,
+	.id = &tcf_action_net_id,
+	.size = sizeof(struct tcf_action_net),
+};
+
 static int __init tc_action_init(void)
 {
+	int err;
+
+	err = register_pernet_subsys(&tcf_action_net_ops);
+	if (err)
+		return err;
+
 	rtnl_register(PF_UNSPEC, RTM_NEWACTION, tc_ctl_action, NULL, 0);
 	rtnl_register(PF_UNSPEC, RTM_DELACTION, tc_ctl_action, NULL, 0);
 	rtnl_register(PF_UNSPEC, RTM_GETACTION, tc_ctl_action, tc_dump_action,
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 450873b..99f9432 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1026,6 +1026,36 @@ int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
 }
 EXPORT_SYMBOL(tcf_exts_get_dev);
 
+int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
+			   void *type_data, bool err_stop)
+{
+	int ok_count = 0;
+#ifdef CONFIG_NET_CLS_ACT
+	const struct tc_action *a;
+	struct net_device *dev;
+	LIST_HEAD(actions);
+	int ret;
+
+	if (!tcf_exts_has_actions(exts))
+		return 0;
+
+	tcf_exts_to_list(exts, &actions);
+	list_for_each_entry(a, &actions, list) {
+		if (!a->ops->get_dev)
+			continue;
+		dev = a->ops->get_dev(a);
+		if (!dev || !tc_can_offload(dev))
+			continue;
+		ret = tc_setup_cb_egdev_call(dev, type, type_data, err_stop);
+		if (ret < 0)
+			return ret;
+		ok_count += ret;
+	}
+#endif
+	return ok_count;
+}
+EXPORT_SYMBOL(tcf_exts_egdev_cb_call);
+
 static int __init tc_filter_init(void)
 {
 	rtnl_register(PF_UNSPEC, RTM_NEWTFILTER, tc_ctl_tfilter, NULL, 0);
-- 
2.9.5

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

* [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra
  2017-10-10  7:30 [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Jiri Pirko
  2017-10-10  7:30 ` [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net Jiri Pirko
  2017-10-10  7:30 ` [patch net-next 2/4] net: sched: introduce per-egress action device callbacks Jiri Pirko
@ 2017-10-10  7:30 ` Jiri Pirko
  2017-10-10 20:04   ` Or Gerlitz
  2017-10-10 20:08   ` Or Gerlitz
  2017-10-10  7:30 ` [patch net-next 4/4] net: sched: remove unused tcf_exts_get_dev helper and cls_flower->egress_dev Jiri Pirko
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10  7:30 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

The only user of cls_flower->egress_dev is mlx5. So do the conversion
there alongside with the code originating the call in cls_flower
function fl_hw_replace_filter to the newly introduced egress device
callback infrastucture.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h      |  3 ++
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c |  4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c  | 31 +++++++----
 include/net/pkt_cls.h                             |  5 +-
 net/sched/cls_api.c                               | 13 +++--
 net/sched/cls_flower.c                            | 63 ++++++++++++-----------
 6 files changed, 73 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index cc13d3d..5ec6d3e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1081,6 +1081,9 @@ int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
 int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
 			       struct ethtool_flash *flash);
 
+int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
+		   void *type_data);
+
 /* mlx5e generic netdev management API */
 struct net_device*
 mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cc11bbb..2a32102 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3108,8 +3108,8 @@ static int mlx5e_setup_tc_cls_flower(struct net_device *dev,
 }
 #endif
 
-static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
-			  void *type_data)
+int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
+		   void *type_data)
 {
 	switch (type) {
 #ifdef CONFIG_MLX5_ESWITCH
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 45e03c4..765fc74 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -34,6 +34,7 @@
 #include <linux/mlx5/fs.h>
 #include <net/switchdev.h>
 #include <net/pkt_cls.h>
+#include <net/act_api.h>
 #include <net/netevent.h>
 #include <net/arp.h>
 
@@ -667,14 +668,6 @@ mlx5e_rep_setup_tc_cls_flower(struct net_device *dev,
 	    cls_flower->common.chain_index)
 		return -EOPNOTSUPP;
 
-	if (cls_flower->egress_dev) {
-		struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
-
-		dev = mlx5_eswitch_get_uplink_netdev(esw);
-		return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER,
-						     cls_flower);
-	}
-
 	switch (cls_flower->command) {
 	case TC_CLSFLOWER_REPLACE:
 		return mlx5e_configure_flower(priv, cls_flower);
@@ -698,6 +691,14 @@ static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
 	}
 }
 
+static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
+				 void *cb_priv)
+{
+	struct net_device *dev = cb_priv;
+
+	return mlx5e_setup_tc(dev, type, type_data);
+}
+
 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
 {
 	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
@@ -1017,15 +1018,24 @@ mlx5e_vport_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
 		goto err_detach_netdev;
 	}
 
+	err = tc_setup_cb_egdev_register(netdev, mlx5e_rep_setup_tc_cb,
+					 mlx5_eswitch_get_uplink_netdev(esw));
+	if (err)
+		goto err_neigh_cleanup;
+
 	err = register_netdev(netdev);
 	if (err) {
 		pr_warn("Failed to register representor netdev for vport %d\n",
 			rep->vport);
-		goto err_neigh_cleanup;
+		goto err_egdev_cleanup;
 	}
 
 	return 0;
 
+err_egdev_cleanup:
+	tc_setup_cb_egdev_unregister(netdev, mlx5e_rep_setup_tc_cb,
+				     mlx5_eswitch_get_uplink_netdev(esw));
+
 err_neigh_cleanup:
 	mlx5e_rep_neigh_cleanup(rpriv);
 
@@ -1047,7 +1057,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
 	void *ppriv = priv->ppriv;
 
 	unregister_netdev(rep->netdev);
-
+	tc_setup_cb_egdev_unregister(netdev, mlx5e_rep_setup_tc_cb,
+				     mlx5_eswitch_get_uplink_netdev(esw));
 	mlx5e_rep_neigh_cleanup(rpriv);
 	mlx5e_detach_netdev(priv);
 	mlx5e_destroy_netdev(priv);
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 6f8149c..c0bdf5c 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -206,8 +206,6 @@ 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,
 		     struct net_device **hw_dev);
-int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
-			   void *type_data, bool err_stop);
 
 /**
  * struct tcf_pkt_info - packet information
@@ -407,6 +405,9 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
 }
 #endif /* CONFIG_NET_CLS_IND */
 
+int tc_setup_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
+		     void *type_data, bool err_stop);
+
 struct tc_cls_common_offload {
 	u32 chain_index;
 	__be16 protocol;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 99f9432..51994a2 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1026,8 +1026,9 @@ int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
 }
 EXPORT_SYMBOL(tcf_exts_get_dev);
 
-int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
-			   void *type_data, bool err_stop)
+static int tc_exts_setup_cb_egdev_call(struct tcf_exts *exts,
+				       enum tc_setup_type type,
+				       void *type_data, bool err_stop)
 {
 	int ok_count = 0;
 #ifdef CONFIG_NET_CLS_ACT
@@ -1054,7 +1055,13 @@ int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
 #endif
 	return ok_count;
 }
-EXPORT_SYMBOL(tcf_exts_egdev_cb_call);
+
+int tc_setup_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
+		     void *type_data, bool err_stop)
+{
+	return tc_exts_setup_cb_egdev_call(exts, type, type_data, err_stop);
+}
+EXPORT_SYMBOL(tc_setup_cb_call);
 
 static int __init tc_filter_init(void)
 {
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index db831ac..5b7bb96 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -88,7 +88,6 @@ struct cls_fl_filter {
 	u32 handle;
 	u32 flags;
 	struct rcu_head	rcu;
-	struct net_device *hw_dev;
 };
 
 static unsigned short int fl_mask_range(const struct fl_flow_mask *mask)
@@ -201,16 +200,17 @@ static void fl_destroy_filter(struct rcu_head *head)
 static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f)
 {
 	struct tc_cls_flower_offload cls_flower = {};
-	struct net_device *dev = f->hw_dev;
-
-	if (!tc_can_offload(dev))
-		return;
+	struct net_device *dev = tp->q->dev_queue->dev;
 
 	tc_cls_common_offload_init(&cls_flower.common, tp);
 	cls_flower.command = TC_CLSFLOWER_DESTROY;
 	cls_flower.cookie = (unsigned long) f;
 
-	dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER, &cls_flower);
+	if (tc_can_offload(dev))
+		dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER,
+					      &cls_flower);
+	tc_setup_cb_call(&f->exts, TC_SETUP_CLSFLOWER,
+			 &cls_flower, false);
 }
 
 static int fl_hw_replace_filter(struct tcf_proto *tp,
@@ -220,20 +220,9 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
 {
 	struct net_device *dev = tp->q->dev_queue->dev;
 	struct tc_cls_flower_offload cls_flower = {};
+	bool skip_sw = tc_skip_sw(f->flags);
 	int err;
 
-	if (!tc_can_offload(dev)) {
-		if (tcf_exts_get_dev(dev, &f->exts, &f->hw_dev) ||
-		    (f->hw_dev && !tc_can_offload(f->hw_dev))) {
-			f->hw_dev = dev;
-			return tc_skip_sw(f->flags) ? -EINVAL : 0;
-		}
-		dev = f->hw_dev;
-		cls_flower.egress_dev = true;
-	} else {
-		f->hw_dev = dev;
-	}
-
 	tc_cls_common_offload_init(&cls_flower.common, tp);
 	cls_flower.command = TC_CLSFLOWER_REPLACE;
 	cls_flower.cookie = (unsigned long) f;
@@ -242,31 +231,47 @@ static int fl_hw_replace_filter(struct tcf_proto *tp,
 	cls_flower.key = &f->mkey;
 	cls_flower.exts = &f->exts;
 
-	err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER,
-					    &cls_flower);
-	if (!err)
-		f->flags |= TCA_CLS_FLAGS_IN_HW;
+	if (tc_can_offload(dev)) {
+		err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER,
+						    &cls_flower);
+		if (err) {
+			if (skip_sw)
+				return err;
+		} else {
+			f->flags |= TCA_CLS_FLAGS_IN_HW;
+		}
+	}
 
-	if (tc_skip_sw(f->flags))
+	err = tc_setup_cb_call(&f->exts, TC_SETUP_CLSFLOWER,
+			       &cls_flower, skip_sw);
+	if (err < 0) {
+		fl_hw_destroy_filter(tp, f);
 		return err;
+	} else if (err > 0) {
+		f->flags |= TCA_CLS_FLAGS_IN_HW;
+	}
+
+	if (skip_sw && !(f->flags & TCA_CLS_FLAGS_IN_HW))
+		return -EINVAL;
+
 	return 0;
 }
 
 static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f)
 {
 	struct tc_cls_flower_offload cls_flower = {};
-	struct net_device *dev = f->hw_dev;
-
-	if (!tc_can_offload(dev))
-		return;
+	struct net_device *dev = tp->q->dev_queue->dev;
 
 	tc_cls_common_offload_init(&cls_flower.common, tp);
 	cls_flower.command = TC_CLSFLOWER_STATS;
 	cls_flower.cookie = (unsigned long) f;
 	cls_flower.exts = &f->exts;
 
-	dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER,
-				      &cls_flower);
+	if (tc_can_offload(dev))
+		dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER,
+					      &cls_flower);
+	tc_setup_cb_call(&f->exts, TC_SETUP_CLSFLOWER,
+			 &cls_flower, false);
 }
 
 static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f)
-- 
2.9.5

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

* [patch net-next 4/4] net: sched: remove unused tcf_exts_get_dev helper and cls_flower->egress_dev
  2017-10-10  7:30 [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Jiri Pirko
                   ` (2 preceding siblings ...)
  2017-10-10  7:30 ` [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra Jiri Pirko
@ 2017-10-10  7:30 ` Jiri Pirko
  2017-10-10 17:25 ` [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Or Gerlitz
       [not found] ` <CAJ3xEMgPdcVrogHZmEnH+vP3E53zvEcFN8+wyuEqSs6utHQVRg@mail.gmail.com>
  5 siblings, 0 replies; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10  7:30 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

The helper and the struct field ares no longer used by any code,
so remove them.

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

diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index c0bdf5c..f526374 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -204,8 +204,6 @@ void tcf_exts_destroy(struct tcf_exts *exts);
 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,
-		     struct net_device **hw_dev);
 
 /**
  * struct tcf_pkt_info - packet information
@@ -517,7 +515,6 @@ struct tc_cls_flower_offload {
 	struct fl_flow_key *mask;
 	struct fl_flow_key *key;
 	struct tcf_exts *exts;
-	bool egress_dev;
 };
 
 enum tc_matchall_command {
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 51994a2..2977b8a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1004,28 +1004,6 @@ int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts)
 }
 EXPORT_SYMBOL(tcf_exts_dump_stats);
 
-int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
-		     struct net_device **hw_dev)
-{
-#ifdef CONFIG_NET_CLS_ACT
-	const struct tc_action *a;
-	LIST_HEAD(actions);
-
-	if (!tcf_exts_has_actions(exts))
-		return -EINVAL;
-
-	tcf_exts_to_list(exts, &actions);
-	list_for_each_entry(a, &actions, list) {
-		if (a->ops->get_dev)
-			*hw_dev = a->ops->get_dev(a);
-	}
-	if (*hw_dev)
-		return 0;
-#endif
-	return -EOPNOTSUPP;
-}
-EXPORT_SYMBOL(tcf_exts_get_dev);
-
 static int tc_exts_setup_cb_egdev_call(struct tcf_exts *exts,
 				       enum tc_setup_type type,
 				       void *type_data, bool err_stop)
-- 
2.9.5

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

* RE: [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
  2017-10-10  7:30 ` [patch net-next 2/4] net: sched: introduce per-egress action device callbacks Jiri Pirko
@ 2017-10-10 13:31   ` David Laight
  2017-10-10 14:31     ` Jiri Pirko
  0 siblings, 1 reply; 22+ messages in thread
From: David Laight @ 2017-10-10 13:31 UTC (permalink / raw)
  To: 'Jiri Pirko', netdev
  Cc: davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko
> Sent: 10 October 2017 08:30
> Introduce infrastructure that allows drivers to register callbacks that
> are called whenever tc would offload inserted rule and specified device
> acts as tc action egress device.

How does a driver safely unregister a callback?
(to avoid a race with the callback being called.)

Usually this requires a callback in the context that makes the
notification callbacks indicating that no more such callbacks
will be made.

	David

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

* Re: [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
  2017-10-10 13:31   ` David Laight
@ 2017-10-10 14:31     ` Jiri Pirko
  2017-10-10 15:12       ` David Laight
  0 siblings, 1 reply; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10 14:31 UTC (permalink / raw)
  To: David Laight
  Cc: netdev, davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

Tue, Oct 10, 2017 at 03:31:59PM CEST, David.Laight@ACULAB.COM wrote:
>From: Jiri Pirko
>> Sent: 10 October 2017 08:30
>> Introduce infrastructure that allows drivers to register callbacks that
>> are called whenever tc would offload inserted rule and specified device
>> acts as tc action egress device.
>
>How does a driver safely unregister a callback?
>(to avoid a race with the callback being called.)
>
>Usually this requires a callback in the context that makes the
>notification callbacks indicating that no more such callbacks
>will be made.

rtnl is your answer. It is being held during register/unregister/cb

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

* RE: [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
  2017-10-10 14:31     ` Jiri Pirko
@ 2017-10-10 15:12       ` David Laight
  2017-10-10 15:39         ` Jiri Pirko
  0 siblings, 1 reply; 22+ messages in thread
From: David Laight @ 2017-10-10 15:12 UTC (permalink / raw)
  To: 'Jiri Pirko'
  Cc: netdev, davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

From: Jiri Pirko
> Sent: 10 October 2017 15:32
> To: David Laight
> Cc: netdev@vger.kernel.org; davem@davemloft.net; jhs@mojatatu.com; xiyou.wangcong@gmail.com;
> saeedm@mellanox.com; matanb@mellanox.com; leonro@mellanox.com; mlxsw@mellanox.com
> Subject: Re: [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
> 
> Tue, Oct 10, 2017 at 03:31:59PM CEST, David.Laight@ACULAB.COM wrote:
> >From: Jiri Pirko
> >> Sent: 10 October 2017 08:30
> >> Introduce infrastructure that allows drivers to register callbacks that
> >> are called whenever tc would offload inserted rule and specified device
> >> acts as tc action egress device.
> >
> >How does a driver safely unregister a callback?
> >(to avoid a race with the callback being called.)
> >
> >Usually this requires a callback in the context that makes the
> >notification callbacks indicating that no more such callbacks
> >will be made.
> 
> rtnl is your answer. It is being held during register/unregister/cb

Do you mean 'acquired during register/unregister' and 'held across the
callback' ?

So the unregister sleeps (or spins?) until any callbacks complete?
So the driver mustn't hold any locks (etc) across the unregister that
it acquires in the callback.
That ought to be noted somewhere.

	David

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

* Re: [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
  2017-10-10 15:12       ` David Laight
@ 2017-10-10 15:39         ` Jiri Pirko
  0 siblings, 0 replies; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10 15:39 UTC (permalink / raw)
  To: David Laight
  Cc: netdev, davem, jhs, xiyou.wangcong, saeedm, matanb, leonro, mlxsw

Tue, Oct 10, 2017 at 05:12:34PM CEST, David.Laight@ACULAB.COM wrote:
>From: Jiri Pirko
>> Sent: 10 October 2017 15:32
>> To: David Laight
>> Cc: netdev@vger.kernel.org; davem@davemloft.net; jhs@mojatatu.com; xiyou.wangcong@gmail.com;
>> saeedm@mellanox.com; matanb@mellanox.com; leonro@mellanox.com; mlxsw@mellanox.com
>> Subject: Re: [patch net-next 2/4] net: sched: introduce per-egress action device callbacks
>> 
>> Tue, Oct 10, 2017 at 03:31:59PM CEST, David.Laight@ACULAB.COM wrote:
>> >From: Jiri Pirko
>> >> Sent: 10 October 2017 08:30
>> >> Introduce infrastructure that allows drivers to register callbacks that
>> >> are called whenever tc would offload inserted rule and specified device
>> >> acts as tc action egress device.
>> >
>> >How does a driver safely unregister a callback?
>> >(to avoid a race with the callback being called.)
>> >
>> >Usually this requires a callback in the context that makes the
>> >notification callbacks indicating that no more such callbacks
>> >will be made.
>> 
>> rtnl is your answer. It is being held during register/unregister/cb
>
>Do you mean 'acquired during register/unregister' and 'held across the
>callback' ?
>
>So the unregister sleeps (or spins?) until any callbacks complete?
>So the driver mustn't hold any locks (etc) across the unregister that
>it acquires in the callback.
>That ought to be noted somewhere.

You actually have a point. I don't take rtnl for reg/unreg as I suppose
to. Will fix.


>
>	David
>

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

* Re: [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev
  2017-10-10  7:30 [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Jiri Pirko
                   ` (3 preceding siblings ...)
  2017-10-10  7:30 ` [patch net-next 4/4] net: sched: remove unused tcf_exts_get_dev helper and cls_flower->egress_dev Jiri Pirko
@ 2017-10-10 17:25 ` Or Gerlitz
       [not found] ` <CAJ3xEMgPdcVrogHZmEnH+vP3E53zvEcFN8+wyuEqSs6utHQVRg@mail.gmail.com>
  5 siblings, 0 replies; 22+ messages in thread
From: Or Gerlitz @ 2017-10-10 17:25 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Linux Netdev List, David Miller, Jamal Hadi Salim, Cong Wang,
	Saeed Mahameed, Matan Barak, Leon Romanovsky, mlxsw

On Tue, Oct 10, 2017 at 10:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>
>
>  drivers/net/ethernet/mellanox/mlx5/core/en.h      |   3 +
>  drivers/net/ethernet/mellanox/mlx5/core/en_main.c |   4 +-
>  drivers/net/ethernet/mellanox/mlx5/core/en_rep.c  |  31 ++--



Jiri,

FWIW, as I reported to you earlier, I was playing with tc encap/decap
rules on 4.14-rc+ (net) before
applying any patch of this series, and something is messy w.r.t to
decap rules. I don't see
them removed at all when user space attempts to do so. It might
(probably) mlx5 bug, which
we will have to fix for net and later rebase net-next over net. We
have short WW here so
I will not be able to do RCA this week.

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

* Re: [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net
  2017-10-10  7:30 ` [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net Jiri Pirko
@ 2017-10-10 17:44   ` Cong Wang
  2017-10-10 21:19     ` Jiri Pirko
  0 siblings, 1 reply; 22+ messages in thread
From: Cong Wang @ 2017-10-10 17:44 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Saeed Mahameed, matanb, leonro, mlxsw

On Tue, Oct 10, 2017 at 12:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> -static int tcf_mirred_device(const struct tc_action *a, struct net *net,
> -                            struct net_device **mirred_dev)
> +static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
>  {
> -       int ifindex = tcf_mirred_ifindex(a);
> +       struct tcf_mirred *m = to_mirred(a);
>
> -       *mirred_dev = __dev_get_by_index(net, ifindex);
> -       if (!*mirred_dev)
> -               return -EINVAL;
> -       return 0;
> +       return __dev_get_by_index(m->net, m->tcfm_ifindex);

Hmm, why not just return m->tcfm_dev?

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

* Re: [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra
  2017-10-10  7:30 ` [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra Jiri Pirko
@ 2017-10-10 20:04   ` Or Gerlitz
  2017-10-10 20:08   ` Or Gerlitz
  1 sibling, 0 replies; 22+ messages in thread
From: Or Gerlitz @ 2017-10-10 20:04 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Linux Netdev List, David Miller, Jamal Hadi Salim, Cong Wang,
	Saeed Mahameed, Matan Barak, Leon Romanovsky, mlxsw

On Tue, Oct 10, 2017 at 10:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:

> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -206,8 +206,6 @@ 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,
>                      struct net_device **hw_dev);
> -int tcf_exts_egdev_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
> -                          void *type_data, bool err_stop);

but this (and another 1-2 hunks below) were set by upstream patch of
this series, did you do that add/del on purpose? is that for
bisection? if not why?

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

* Re: [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra
  2017-10-10  7:30 ` [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra Jiri Pirko
  2017-10-10 20:04   ` Or Gerlitz
@ 2017-10-10 20:08   ` Or Gerlitz
  2017-10-10 21:16     ` Jiri Pirko
  1 sibling, 1 reply; 22+ messages in thread
From: Or Gerlitz @ 2017-10-10 20:08 UTC (permalink / raw)
  To: Jiri Pirko, Simon Horman
  Cc: Linux Netdev List, David Miller, Jamal Hadi Salim, Cong Wang,
	Saeed Mahameed, mlxsw

On Tue, Oct 10, 2017 at 10:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> The only user of cls_flower->egress_dev is mlx5.

but nfp supports decap action offload too and from the flower code
stand point, I guess they are both the same, right? how does it work
there?

Or.

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

* Re: [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev
       [not found] ` <CAJ3xEMgPdcVrogHZmEnH+vP3E53zvEcFN8+wyuEqSs6utHQVRg@mail.gmail.com>
@ 2017-10-10 21:13   ` Jiri Pirko
  2017-10-10 21:46     ` Or Gerlitz
  0 siblings, 1 reply; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10 21:13 UTC (permalink / raw)
  To: Or Gerlitz
  Cc: Saeed Mahameed, Linux Netdev List, David Miller,
	Jamal Hadi Salim, Cong Wang, mlxsw

Tue, Oct 10, 2017 at 07:24:21PM CEST, gerlitz.or@gmail.com wrote:
>Jiri,
>
>FWIW, as I reported to you earlier, I was playing with tc encap/decap rules
>on 4.14-rc+ (net) before
>applying any patch of this series, and something is messy w.r.t to decap
>rules. I don't see
>them removed at all when user space attempts to do so. It might (probably)
>mlx5 bug, which
>we will have to fix for net and later rebase net-next over net. We have
>short WW here so
>I will not be able to do RCA this week.

Or, as I replied to you earlier, the issue you describe is totally
unrelated to this patchset as you see the issue with the current net-next.
Not sure why you add this comment here.

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

* Re: [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra
  2017-10-10 20:08   ` Or Gerlitz
@ 2017-10-10 21:16     ` Jiri Pirko
  2017-10-10 21:47       ` Or Gerlitz
  0 siblings, 1 reply; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10 21:16 UTC (permalink / raw)
  To: Or Gerlitz
  Cc: Simon Horman, Linux Netdev List, David Miller, Jamal Hadi Salim,
	Cong Wang, Saeed Mahameed, mlxsw

Tue, Oct 10, 2017 at 10:08:23PM CEST, gerlitz.or@gmail.com wrote:
>On Tue, Oct 10, 2017 at 10:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> The only user of cls_flower->egress_dev is mlx5.
>
>but nfp supports decap action offload too and from the flower code
>stand point, I guess they are both the same, right? how does it work
>there?

Apparently they don't use cls_flower->egress_dev.

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

* Re: [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net
  2017-10-10 17:44   ` Cong Wang
@ 2017-10-10 21:19     ` Jiri Pirko
  2017-10-11 16:34       ` Cong Wang
  0 siblings, 1 reply; 22+ messages in thread
From: Jiri Pirko @ 2017-10-10 21:19 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Saeed Mahameed, matanb, leonro, mlxsw

Tue, Oct 10, 2017 at 07:44:53PM CEST, xiyou.wangcong@gmail.com wrote:
>On Tue, Oct 10, 2017 at 12:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> -static int tcf_mirred_device(const struct tc_action *a, struct net *net,
>> -                            struct net_device **mirred_dev)
>> +static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
>>  {
>> -       int ifindex = tcf_mirred_ifindex(a);
>> +       struct tcf_mirred *m = to_mirred(a);
>>
>> -       *mirred_dev = __dev_get_by_index(net, ifindex);
>> -       if (!*mirred_dev)
>> -               return -EINVAL;
>> -       return 0;
>> +       return __dev_get_by_index(m->net, m->tcfm_ifindex);
>
>Hmm, why not just return m->tcfm_dev?

I just follow the existing code. The change you suggest should be a
separate follow-up patch.

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

* Re: [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev
  2017-10-10 21:13   ` Jiri Pirko
@ 2017-10-10 21:46     ` Or Gerlitz
  2017-10-11  6:44       ` Jiri Pirko
  0 siblings, 1 reply; 22+ messages in thread
From: Or Gerlitz @ 2017-10-10 21:46 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Saeed Mahameed, Linux Netdev List, David Miller,
	Jamal Hadi Salim, Cong Wang, mlxsw

On Wed, Oct 11, 2017 at 12:13 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> Tue, Oct 10, 2017 at 07:24:21PM CEST, gerlitz.or@gmail.com wrote:

> Or, as I replied to you earlier, the issue you describe is totally
> unrelated to this patchset as you see the issue with the current net-next.

Jiri, the point I wanted to make that if indeed there's a bug in mlx5
or flower, we will have to fix it for 4.14 and then these bits would
have to be rebased when net-next is re-planted over net, I put "FWIW"
before that, so maybe it doesn't W so much, we'll see.

Or.

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

* Re: [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra
  2017-10-10 21:16     ` Jiri Pirko
@ 2017-10-10 21:47       ` Or Gerlitz
  2017-10-11  8:36         ` Or Gerlitz
  0 siblings, 1 reply; 22+ messages in thread
From: Or Gerlitz @ 2017-10-10 21:47 UTC (permalink / raw)
  To: Jiri Pirko, John Hurley
  Cc: Simon Horman, Linux Netdev List, David Miller, Jamal Hadi Salim,
	Cong Wang, Saeed Mahameed, mlxsw

On Wed, Oct 11, 2017 at 12:16 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> Tue, Oct 10, 2017 at 10:08:23PM CEST, gerlitz.or@gmail.com wrote:
>>On Tue, Oct 10, 2017 at 10:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>> The only user of cls_flower->egress_dev is mlx5.
>>
>>but nfp supports decap action offload too and from the flower code
>>stand point, I guess they are both the same, right? how does it work
>>there?
>
> Apparently they don't use cls_flower->egress_dev.

John, can you elaborate on that, how do you manage to get away from
that practice?

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

* Re: [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev
  2017-10-10 21:46     ` Or Gerlitz
@ 2017-10-11  6:44       ` Jiri Pirko
  0 siblings, 0 replies; 22+ messages in thread
From: Jiri Pirko @ 2017-10-11  6:44 UTC (permalink / raw)
  To: Or Gerlitz
  Cc: Saeed Mahameed, Linux Netdev List, David Miller,
	Jamal Hadi Salim, Cong Wang, mlxsw

Tue, Oct 10, 2017 at 11:46:22PM CEST, gerlitz.or@gmail.com wrote:
>On Wed, Oct 11, 2017 at 12:13 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Tue, Oct 10, 2017 at 07:24:21PM CEST, gerlitz.or@gmail.com wrote:
>
>> Or, as I replied to you earlier, the issue you describe is totally
>> unrelated to this patchset as you see the issue with the current net-next.
>
>Jiri, the point I wanted to make that if indeed there's a bug in mlx5
>or flower, we will have to fix it for 4.14 and then these bits would
>have to be rebased when net-next is re-planted over net, I put "FWIW"
>before that, so maybe it doesn't W so much, we'll see.

The fix is still unrelated to this patchset.

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

* Re: [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra
  2017-10-10 21:47       ` Or Gerlitz
@ 2017-10-11  8:36         ` Or Gerlitz
  0 siblings, 0 replies; 22+ messages in thread
From: Or Gerlitz @ 2017-10-11  8:36 UTC (permalink / raw)
  To: Jiri Pirko, John Hurley, Simon Horman, Jakub Kicinski
  Cc: Linux Netdev List, David Miller, Jamal Hadi Salim, Cong Wang,
	Saeed Mahameed, mlxsw, Roi Dayan, Paul Blakey, Shani Michaeli

On Wed, Oct 11, 2017 at 12:47 AM, Or Gerlitz <gerlitz.or@gmail.com> wrote:
> On Wed, Oct 11, 2017 at 12:16 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Tue, Oct 10, 2017 at 10:08:23PM CEST, gerlitz.or@gmail.com wrote:
>>>On Tue, Oct 10, 2017 at 10:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>>> The only user of cls_flower->egress_dev is mlx5.
>>>
>>>but nfp supports decap action offload too and from the flower code
>>>stand point, I guess they are both the same, right? how does it work there?

>> Apparently they don't use cls_flower->egress_dev.

> John, can you elaborate on that, how do you manage to get away from
> that practice?

Looking on this a little more, it's clearly obvious that both
fl_hw_update_stats and
fl_hw_destroy_filter never set egress_dev on the local variable which
is set down
to the driver through the ndo.

For cases such as decap flow set on virtual SW tunnel device where f->hw_dev is
the egress port, mlx5 fails to internally locate the  driver rule
object and we return -EINVAL
on both cases and hence deletion or stats will not take place.

I verified that in black box manner for both cases of deletion (the
specific filer or the
whole ingress qdisc) and for the stats.

We have per ingress port rules table on the driver and maybe nfp
doesn't and hence
why they  didn't fell on that, not sure, I copied the folks here.

Commit a6e1693129 "net/sched: cls_flower: Set the filter Hardware
device for all use-cases"
tries to fix something and does mention the stats and destroy cases,
but I don't see how
it helps for that :(

I will keep looking next week (starting holiday here now) and try to
get a fix for net and stable.

Or.

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

* Re: [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net
  2017-10-10 21:19     ` Jiri Pirko
@ 2017-10-11 16:34       ` Cong Wang
  2017-10-11 20:43         ` Jiri Pirko
  0 siblings, 1 reply; 22+ messages in thread
From: Cong Wang @ 2017-10-11 16:34 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Saeed Mahameed, matanb, leonro, mlxsw

On Tue, Oct 10, 2017 at 2:19 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Tue, Oct 10, 2017 at 07:44:53PM CEST, xiyou.wangcong@gmail.com wrote:
>>On Tue, Oct 10, 2017 at 12:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>> -static int tcf_mirred_device(const struct tc_action *a, struct net *net,
>>> -                            struct net_device **mirred_dev)
>>> +static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
>>>  {
>>> -       int ifindex = tcf_mirred_ifindex(a);
>>> +       struct tcf_mirred *m = to_mirred(a);
>>>
>>> -       *mirred_dev = __dev_get_by_index(net, ifindex);
>>> -       if (!*mirred_dev)
>>> -               return -EINVAL;
>>> -       return 0;
>>> +       return __dev_get_by_index(m->net, m->tcfm_ifindex);
>>
>>Hmm, why not just return m->tcfm_dev?
>
> I just follow the existing code. The change you suggest should be a
> separate follow-up patch.

Why?

Your goal is "make tc_action_ops->get_dev return dev and avoid passing net",
using m->tcfm_dev is simpler and could save you from adding a net pointer
to struct tcf_mirred too.

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

* Re: [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net
  2017-10-11 16:34       ` Cong Wang
@ 2017-10-11 20:43         ` Jiri Pirko
  0 siblings, 0 replies; 22+ messages in thread
From: Jiri Pirko @ 2017-10-11 20:43 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Saeed Mahameed, matanb, leonro, mlxsw

Wed, Oct 11, 2017 at 06:34:51PM CEST, xiyou.wangcong@gmail.com wrote:
>On Tue, Oct 10, 2017 at 2:19 PM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Tue, Oct 10, 2017 at 07:44:53PM CEST, xiyou.wangcong@gmail.com wrote:
>>>On Tue, Oct 10, 2017 at 12:30 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>>> -static int tcf_mirred_device(const struct tc_action *a, struct net *net,
>>>> -                            struct net_device **mirred_dev)
>>>> +static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
>>>>  {
>>>> -       int ifindex = tcf_mirred_ifindex(a);
>>>> +       struct tcf_mirred *m = to_mirred(a);
>>>>
>>>> -       *mirred_dev = __dev_get_by_index(net, ifindex);
>>>> -       if (!*mirred_dev)
>>>> -               return -EINVAL;
>>>> -       return 0;
>>>> +       return __dev_get_by_index(m->net, m->tcfm_ifindex);
>>>
>>>Hmm, why not just return m->tcfm_dev?
>>
>> I just follow the existing code. The change you suggest should be a
>> separate follow-up patch.
>
>Why?

I try to do small contained changes per patch. The resulting code is
doing the same thing as the original, therefore reducing possible bug
appearance. 

>
>Your goal is "make tc_action_ops->get_dev return dev and avoid passing net",
>using m->tcfm_dev is simpler and could save you from adding a net pointer
>to struct tcf_mirred too.

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

end of thread, other threads:[~2017-10-11 20:43 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-10  7:30 [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Jiri Pirko
2017-10-10  7:30 ` [patch net-next 1/4] net: sched: make tc_action_ops->get_dev return dev and avoid passing net Jiri Pirko
2017-10-10 17:44   ` Cong Wang
2017-10-10 21:19     ` Jiri Pirko
2017-10-11 16:34       ` Cong Wang
2017-10-11 20:43         ` Jiri Pirko
2017-10-10  7:30 ` [patch net-next 2/4] net: sched: introduce per-egress action device callbacks Jiri Pirko
2017-10-10 13:31   ` David Laight
2017-10-10 14:31     ` Jiri Pirko
2017-10-10 15:12       ` David Laight
2017-10-10 15:39         ` Jiri Pirko
2017-10-10  7:30 ` [patch net-next 3/4] net: sched: convert cls_flower->egress_dev users to tc_setup_cb_egdev infra Jiri Pirko
2017-10-10 20:04   ` Or Gerlitz
2017-10-10 20:08   ` Or Gerlitz
2017-10-10 21:16     ` Jiri Pirko
2017-10-10 21:47       ` Or Gerlitz
2017-10-11  8:36         ` Or Gerlitz
2017-10-10  7:30 ` [patch net-next 4/4] net: sched: remove unused tcf_exts_get_dev helper and cls_flower->egress_dev Jiri Pirko
2017-10-10 17:25 ` [patch net-next 0/4] net: sched: get rid of cls_flower->egress_dev Or Gerlitz
     [not found] ` <CAJ3xEMgPdcVrogHZmEnH+vP3E53zvEcFN8+wyuEqSs6utHQVRg@mail.gmail.com>
2017-10-10 21:13   ` Jiri Pirko
2017-10-10 21:46     ` Or Gerlitz
2017-10-11  6:44       ` Jiri Pirko

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.