netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes
@ 2018-06-15 13:23 Ido Schimmel
  2018-06-15 13:23 ` [PATCH net 1/4] ipv6: Only emit append events for appended routes Ido Schimmel
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Ido Schimmel @ 2018-06-15 13:23 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, petrm, dsahern, mlxsw, Ido Schimmel

Hi,

The first three patches fix a mismatch between the new IPv6 behavior
introduced in commit f34436a43092 ("net/ipv6: Simplify route replace and
appending into multipath route") and mlxsw. The patches allow the driver
to support multipathing in IPv6 overlays with GRE tunnel devices. A
selftest will be submitted when net-next opens.

The last patch fixes a reference count problem of the port_vlan struct.
I plan to simplify the code in net-next, so that reference counting is
not necessary anymore.

Ido Schimmel (3):
  ipv6: Only emit append events for appended routes
  mlxsw: spectrum_router: Allow appending to dev-only routes
  mlxsw: spectrum_router: Align with new route replace logic

Petr Machata (1):
  mlxsw: spectrum_switchdev: Fix port_vlan refcounting

 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 48 +++++++++++-----------
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   |  4 +-
 net/ipv6/ip6_fib.c                                 |  5 +--
 3 files changed, 29 insertions(+), 28 deletions(-)

-- 
2.14.4

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

* [PATCH net 1/4] ipv6: Only emit append events for appended routes
  2018-06-15 13:23 [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes Ido Schimmel
@ 2018-06-15 13:23 ` Ido Schimmel
  2018-06-15 14:21   ` David Ahern
  2018-06-15 13:23 ` [PATCH net 2/4] mlxsw: spectrum_router: Allow appending to dev-only routes Ido Schimmel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Ido Schimmel @ 2018-06-15 13:23 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, petrm, dsahern, mlxsw, Ido Schimmel

Current code will emit an append event in the FIB notification chain for
any route added with NLM_F_APPEND set, even if the route was not
appended to any existing route.

This is inconsistent with IPv4 where such an event is only emitted when
the new route is appended after an existing one.

Align IPv6 behavior with IPv4, thereby allowing listeners to more easily
handle these events.

Fixes: f34436a43092 ("net/ipv6: Simplify route replace and appending into multipath route")
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 net/ipv6/ip6_fib.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 7aa4c41a3bd9..39d1d487eca2 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -934,6 +934,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 {
 	struct fib6_info *leaf = rcu_dereference_protected(fn->leaf,
 				    lockdep_is_held(&rt->fib6_table->tb6_lock));
+	enum fib_event_type event = FIB_EVENT_ENTRY_ADD;
 	struct fib6_info *iter = NULL, *match = NULL;
 	struct fib6_info __rcu **ins;
 	int replace = (info->nlh &&
@@ -1013,6 +1014,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 				       "Can not append to a REJECT route");
 			return -EINVAL;
 		}
+		event = FIB_EVENT_ENTRY_APPEND;
 		rt->fib6_nsiblings = match->fib6_nsiblings;
 		list_add_tail(&rt->fib6_siblings, &match->fib6_siblings);
 		match->fib6_nsiblings++;
@@ -1034,15 +1036,12 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
 	 *	insert node
 	 */
 	if (!replace) {
-		enum fib_event_type event;
-
 		if (!add)
 			pr_warn("NLM_F_CREATE should be set when creating new route\n");
 
 add:
 		nlflags |= NLM_F_CREATE;
 
-		event = append ? FIB_EVENT_ENTRY_APPEND : FIB_EVENT_ENTRY_ADD;
 		err = call_fib6_entry_notifiers(info->nl_net, event, rt,
 						extack);
 		if (err)
-- 
2.14.4

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

* [PATCH net 2/4] mlxsw: spectrum_router: Allow appending to dev-only routes
  2018-06-15 13:23 [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes Ido Schimmel
  2018-06-15 13:23 ` [PATCH net 1/4] ipv6: Only emit append events for appended routes Ido Schimmel
@ 2018-06-15 13:23 ` Ido Schimmel
  2018-06-15 13:23 ` [PATCH net 3/4] mlxsw: spectrum_router: Align with new route replace logic Ido Schimmel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2018-06-15 13:23 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, petrm, dsahern, mlxsw, Ido Schimmel

Commit f34436a43092 ("net/ipv6: Simplify route replace and appending
into multipath route") changed the IPv6 route append logic so that
dev-only routes can be appended and not only gatewayed routes.

Align mlxsw with the new behaviour.

Fixes: f34436a43092 ("net/ipv6: Simplify route replace and appending into multipath route")
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 27 +++++++++++++++-------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 77b2adb29341..c8956ab224ea 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -4771,11 +4771,11 @@ mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
 
 static struct mlxsw_sp_fib6_entry *
 mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
-				 const struct fib6_info *nrt, bool replace)
+				 const struct fib6_info *nrt, bool append)
 {
 	struct mlxsw_sp_fib6_entry *fib6_entry;
 
-	if (!mlxsw_sp_fib6_rt_can_mp(nrt) || replace)
+	if (!append)
 		return NULL;
 
 	list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) {
@@ -4790,8 +4790,7 @@ mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
 			break;
 		if (rt->fib6_metric < nrt->fib6_metric)
 			continue;
-		if (rt->fib6_metric == nrt->fib6_metric &&
-		    mlxsw_sp_fib6_rt_can_mp(rt))
+		if (rt->fib6_metric == nrt->fib6_metric)
 			return fib6_entry;
 		if (rt->fib6_metric > nrt->fib6_metric)
 			break;
@@ -5316,7 +5315,8 @@ static void mlxsw_sp_fib6_entry_replace(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
-				    struct fib6_info *rt, bool replace)
+				    struct fib6_info *rt, bool replace,
+				    bool append)
 {
 	struct mlxsw_sp_fib6_entry *fib6_entry;
 	struct mlxsw_sp_fib_node *fib_node;
@@ -5342,7 +5342,7 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 	/* Before creating a new entry, try to append route to an existing
 	 * multipath entry.
 	 */
-	fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, replace);
+	fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, append);
 	if (fib6_entry) {
 		err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt);
 		if (err)
@@ -5350,6 +5350,14 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 		return 0;
 	}
 
+	/* We received an append event, yet did not find any route to
+	 * append to.
+	 */
+	if (WARN_ON(append)) {
+		err = -EINVAL;
+		goto err_fib6_entry_append;
+	}
+
 	fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt);
 	if (IS_ERR(fib6_entry)) {
 		err = PTR_ERR(fib6_entry);
@@ -5367,6 +5375,7 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 err_fib6_node_entry_link:
 	mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
 err_fib6_entry_create:
+err_fib6_entry_append:
 err_fib6_entry_nexthop_add:
 	mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
 	return err;
@@ -5717,7 +5726,7 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 	struct mlxsw_sp_fib_event_work *fib_work =
 		container_of(work, struct mlxsw_sp_fib_event_work, work);
 	struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
-	bool replace;
+	bool replace, append;
 	int err;
 
 	rtnl_lock();
@@ -5728,8 +5737,10 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 	case FIB_EVENT_ENTRY_APPEND: /* fall through */
 	case FIB_EVENT_ENTRY_ADD:
 		replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
+		append = fib_work->event == FIB_EVENT_ENTRY_APPEND;
 		err = mlxsw_sp_router_fib6_add(mlxsw_sp,
-					       fib_work->fen6_info.rt, replace);
+					       fib_work->fen6_info.rt, replace,
+					       append);
 		if (err)
 			mlxsw_sp_router_fib_abort(mlxsw_sp);
 		mlxsw_sp_rt6_release(fib_work->fen6_info.rt);
-- 
2.14.4

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

* [PATCH net 3/4] mlxsw: spectrum_router: Align with new route replace logic
  2018-06-15 13:23 [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes Ido Schimmel
  2018-06-15 13:23 ` [PATCH net 1/4] ipv6: Only emit append events for appended routes Ido Schimmel
  2018-06-15 13:23 ` [PATCH net 2/4] mlxsw: spectrum_router: Allow appending to dev-only routes Ido Schimmel
@ 2018-06-15 13:23 ` Ido Schimmel
  2018-06-15 13:23 ` [PATCH net 4/4] mlxsw: spectrum_switchdev: Fix port_vlan refcounting Ido Schimmel
  2018-06-15 16:11 ` [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes David Miller
  4 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2018-06-15 13:23 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, petrm, dsahern, mlxsw, Ido Schimmel

Commit f34436a43092 ("net/ipv6: Simplify route replace and appending
into multipath route") changed the IPv6 route replace logic so that the
first matching route (i.e., same metric) is replaced.

Have mlxsw replace the first matching route as well.

Fixes: f34436a43092 ("net/ipv6: Simplify route replace and appending into multipath route")
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c   | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index c8956ab224ea..6aaaf3d9ba31 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -4756,12 +4756,6 @@ static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
 	kfree(mlxsw_sp_rt6);
 }
 
-static bool mlxsw_sp_fib6_rt_can_mp(const struct fib6_info *rt)
-{
-	/* RTF_CACHE routes are ignored */
-	return (rt->fib6_flags & (RTF_GATEWAY | RTF_ADDRCONF)) == RTF_GATEWAY;
-}
-
 static struct fib6_info *
 mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
 {
@@ -5169,7 +5163,7 @@ static struct mlxsw_sp_fib6_entry *
 mlxsw_sp_fib6_node_entry_find(const struct mlxsw_sp_fib_node *fib_node,
 			      const struct fib6_info *nrt, bool replace)
 {
-	struct mlxsw_sp_fib6_entry *fib6_entry, *fallback = NULL;
+	struct mlxsw_sp_fib6_entry *fib6_entry;
 
 	list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) {
 		struct fib6_info *rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
@@ -5178,18 +5172,13 @@ mlxsw_sp_fib6_node_entry_find(const struct mlxsw_sp_fib_node *fib_node,
 			continue;
 		if (rt->fib6_table->tb6_id != nrt->fib6_table->tb6_id)
 			break;
-		if (replace && rt->fib6_metric == nrt->fib6_metric) {
-			if (mlxsw_sp_fib6_rt_can_mp(rt) ==
-			    mlxsw_sp_fib6_rt_can_mp(nrt))
-				return fib6_entry;
-			if (mlxsw_sp_fib6_rt_can_mp(nrt))
-				fallback = fallback ?: fib6_entry;
-		}
+		if (replace && rt->fib6_metric == nrt->fib6_metric)
+			return fib6_entry;
 		if (rt->fib6_metric > nrt->fib6_metric)
-			return fallback ?: fib6_entry;
+			return fib6_entry;
 	}
 
-	return fallback;
+	return NULL;
 }
 
 static int
-- 
2.14.4

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

* [PATCH net 4/4] mlxsw: spectrum_switchdev: Fix port_vlan refcounting
  2018-06-15 13:23 [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes Ido Schimmel
                   ` (2 preceding siblings ...)
  2018-06-15 13:23 ` [PATCH net 3/4] mlxsw: spectrum_router: Align with new route replace logic Ido Schimmel
@ 2018-06-15 13:23 ` Ido Schimmel
  2018-06-15 16:11 ` [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes David Miller
  4 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2018-06-15 13:23 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, petrm, dsahern, mlxsw, Ido Schimmel

From: Petr Machata <petrm@mellanox.com>

Switchdev notifications for addition of SWITCHDEV_OBJ_ID_PORT_VLAN are
distributed not only on clean addition, but also when flags on an
existing VLAN are changed. mlxsw_sp_bridge_port_vlan_add() calls
mlxsw_sp_port_vlan_get() to get at the port_vlan in question, which
implicitly references the object. This then leads to discrepancies in
reference counting when the VLAN is removed. spectrum.c warns about the
problem when the module is removed:

[13578.493090] WARNING: CPU: 0 PID: 2454 at drivers/net/ethernet/mellanox/mlxsw/spectrum.c:2973 mlxsw_sp_port_remove+0xfd/0x110 [mlxsw_spectrum]
[...]
[13578.627106] Call Trace:
[13578.629617]  mlxsw_sp_fini+0x2a/0xe0 [mlxsw_spectrum]
[13578.634748]  mlxsw_core_bus_device_unregister+0x3e/0x130 [mlxsw_core]
[13578.641290]  mlxsw_pci_remove+0x13/0x40 [mlxsw_pci]
[13578.646238]  pci_device_remove+0x31/0xb0
[13578.650244]  device_release_driver_internal+0x14f/0x220
[13578.655562]  driver_detach+0x32/0x70
[13578.659183]  bus_remove_driver+0x47/0xa0
[13578.663134]  pci_unregister_driver+0x1e/0x80
[13578.667486]  mlxsw_sp_module_exit+0xc/0x3fa [mlxsw_spectrum]
[13578.673207]  __x64_sys_delete_module+0x13b/0x1e0
[13578.677888]  ? exit_to_usermode_loop+0x78/0x80
[13578.682374]  do_syscall_64+0x39/0xe0
[13578.685976]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fix by putting the port_vlan when mlxsw_sp_port_vlan_bridge_join()
determines it's a flag-only change.

Fixes: b3529af6bb0d ("spectrum: Reference count VLAN entries")
Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index e97652c40d13..eea5666a86b2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1018,8 +1018,10 @@ mlxsw_sp_port_vlan_bridge_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
 	int err;
 
 	/* No need to continue if only VLAN flags were changed */
-	if (mlxsw_sp_port_vlan->bridge_port)
+	if (mlxsw_sp_port_vlan->bridge_port) {
+		mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan);
 		return 0;
+	}
 
 	err = mlxsw_sp_port_vlan_fid_join(mlxsw_sp_port_vlan, bridge_port);
 	if (err)
-- 
2.14.4

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

* Re: [PATCH net 1/4] ipv6: Only emit append events for appended routes
  2018-06-15 13:23 ` [PATCH net 1/4] ipv6: Only emit append events for appended routes Ido Schimmel
@ 2018-06-15 14:21   ` David Ahern
  0 siblings, 0 replies; 7+ messages in thread
From: David Ahern @ 2018-06-15 14:21 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, jiri, petrm, mlxsw

On 6/15/18 7:23 AM, Ido Schimmel wrote:
> Current code will emit an append event in the FIB notification chain for
> any route added with NLM_F_APPEND set, even if the route was not
> appended to any existing route.
> 
> This is inconsistent with IPv4 where such an event is only emitted when
> the new route is appended after an existing one.
> 
> Align IPv6 behavior with IPv4, thereby allowing listeners to more easily
> handle these events.
> 
> Fixes: f34436a43092 ("net/ipv6: Simplify route replace and appending into multipath route")
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/ipv6/ip6_fib.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 

Acked-by: David Ahern <dsahern@gmail.com>

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

* Re: [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes
  2018-06-15 13:23 [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes Ido Schimmel
                   ` (3 preceding siblings ...)
  2018-06-15 13:23 ` [PATCH net 4/4] mlxsw: spectrum_switchdev: Fix port_vlan refcounting Ido Schimmel
@ 2018-06-15 16:11 ` David Miller
  4 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2018-06-15 16:11 UTC (permalink / raw)
  To: idosch; +Cc: netdev, jiri, petrm, dsahern, mlxsw

From: Ido Schimmel <idosch@mellanox.com>
Date: Fri, 15 Jun 2018 16:23:34 +0300

> The first three patches fix a mismatch between the new IPv6 behavior
> introduced in commit f34436a43092 ("net/ipv6: Simplify route replace and
> appending into multipath route") and mlxsw. The patches allow the driver
> to support multipathing in IPv6 overlays with GRE tunnel devices. A
> selftest will be submitted when net-next opens.
> 
> The last patch fixes a reference count problem of the port_vlan struct.
> I plan to simplify the code in net-next, so that reference counting is
> not necessary anymore.

Series applied, thanks Ido.

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

end of thread, other threads:[~2018-06-15 16:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-15 13:23 [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes Ido Schimmel
2018-06-15 13:23 ` [PATCH net 1/4] ipv6: Only emit append events for appended routes Ido Schimmel
2018-06-15 14:21   ` David Ahern
2018-06-15 13:23 ` [PATCH net 2/4] mlxsw: spectrum_router: Allow appending to dev-only routes Ido Schimmel
2018-06-15 13:23 ` [PATCH net 3/4] mlxsw: spectrum_router: Align with new route replace logic Ido Schimmel
2018-06-15 13:23 ` [PATCH net 4/4] mlxsw: spectrum_switchdev: Fix port_vlan refcounting Ido Schimmel
2018-06-15 16:11 ` [PATCH net 0/4] mlxsw: IPv6 and reference counting fixes David Miller

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