All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently
@ 2020-11-25 19:35 Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 1/5] mlxsw: spectrum_router: Fix error handling issue Ido Schimmel
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Ido Schimmel @ 2020-11-25 19:35 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, dsahern, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

The device supports an operation that allows the driver to issue one
request to update the adjacency index for all the routes in a given
virtual router (VR) from old index and size to new ones. This is useful
in case the configuration of a certain nexthop group is updated and its
adjacency index changes.

Currently, the driver does not use this operation in an efficient
manner. It iterates over all the routes using the nexthop group and
issues an update request for the VR if it is not the same as the
previous VR.

Instead, this patch set tracks the VRs in which the nexthop group is
used and issues one request for each VR.

Example:

8k IPv6 routes were added in an alternating manner to two VRFs. All the
routes are using the same nexthop object ('nhid 1').

Before:

# perf stat -e devlink:devlink_hwmsg --filter='incoming==0' -- ip nexthop replace id 1 via 2001:db8:1::2 dev swp3

 Performance counter stats for 'ip nexthop replace id 1 via 2001:db8:1::2 dev swp3':

            16,385      devlink:devlink_hwmsg

       4.255933213 seconds time elapsed

       0.000000000 seconds user
       0.666923000 seconds sys

Number of EMAD transactions corresponds to number of routes using the
nexthop group.

After:

# perf stat -e devlink:devlink_hwmsg --filter='incoming==0' -- ip nexthop replace id 1 via 2001:db8:1::2 dev swp3

 Performance counter stats for 'ip nexthop replace id 1 via 2001:db8:1::2 dev swp3':

                 3      devlink:devlink_hwmsg

       0.077655094 seconds time elapsed

       0.000000000 seconds user
       0.076698000 seconds sys

Number of EMAD transactions corresponds to number of VRFs / VRs.

Patch set overview:

Patch #1 is a fix for a bug introduced in previous submission. Detected
by Coverity.

Patches #2 and #3 are preparations.

Patch #4 tracks the VRs a nexthop group is member of.

Patch #5 uses the membership tracking from the previous patch to issue
one update request per each VR.

Ido Schimmel (5):
  mlxsw: spectrum_router: Fix error handling issue
  mlxsw: spectrum_router: Pass virtual router parameters directly
    instead of pointer
  mlxsw: spectrum_router: Rollback virtual router adjacency pointer
    update
  mlxsw: spectrum_router: Track nexthop group virtual router membership
  mlxsw: spectrum_router: Update adjacency index more efficiently

 .../ethernet/mellanox/mlxsw/spectrum_router.c | 203 ++++++++++++++++--
 1 file changed, 186 insertions(+), 17 deletions(-)

-- 
2.28.0


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

* [PATCH net-next 1/5] mlxsw: spectrum_router: Fix error handling issue
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
@ 2020-11-25 19:35 ` Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 2/5] mlxsw: spectrum_router: Pass virtual router parameters directly instead of pointer Ido Schimmel
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ido Schimmel @ 2020-11-25 19:35 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, dsahern, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

Return error to the caller instead of suppressing it.

Fixes: e3ddfb45bacd ("mlxsw: spectrum_router: Allow returning errors from mlxsw_sp_nexthop_group_refresh()")
Addresses-Coverity: ("Error handling issues  (CHECKED_RETURN)")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index d551e9bc373c..118d48d9ff8e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3608,10 +3608,8 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
 	int i, err2, err = 0;
 	u32 old_adj_index;
 
-	if (!nhgi->gateway) {
-		mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp);
-		return 0;
-	}
+	if (!nhgi->gateway)
+		return mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp);
 
 	for (i = 0; i < nhgi->count; i++) {
 		nh = &nhgi->nexthops[i];
-- 
2.28.0


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

* [PATCH net-next 2/5] mlxsw: spectrum_router: Pass virtual router parameters directly instead of pointer
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 1/5] mlxsw: spectrum_router: Fix error handling issue Ido Schimmel
@ 2020-11-25 19:35 ` Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 3/5] mlxsw: spectrum_router: Rollback virtual router adjacency pointer update Ido Schimmel
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ido Schimmel @ 2020-11-25 19:35 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, dsahern, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

mlxsw_sp_adj_index_mass_update_vr() only needs the virtual router's
identifier and protocol, so pass them directly. In a subsequent patch
the caller will not have access to the pointer.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 118d48d9ff8e..b229f28f6209 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3243,7 +3243,8 @@ mlxsw_sp_nexthop_lookup(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int mlxsw_sp_adj_index_mass_update_vr(struct mlxsw_sp *mlxsw_sp,
-					     const struct mlxsw_sp_fib *fib,
+					     enum mlxsw_sp_l3proto proto,
+					     u16 vr_id,
 					     u32 adj_index, u16 ecmp_size,
 					     u32 new_adj_index,
 					     u16 new_ecmp_size)
@@ -3251,8 +3252,8 @@ static int mlxsw_sp_adj_index_mass_update_vr(struct mlxsw_sp *mlxsw_sp,
 	char raleu_pl[MLXSW_REG_RALEU_LEN];
 
 	mlxsw_reg_raleu_pack(raleu_pl,
-			     (enum mlxsw_reg_ralxx_protocol) fib->proto,
-			     fib->vr->id, adj_index, ecmp_size, new_adj_index,
+			     (enum mlxsw_reg_ralxx_protocol) proto, vr_id,
+			     adj_index, ecmp_size, new_adj_index,
 			     new_ecmp_size);
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raleu), raleu_pl);
 }
@@ -3271,7 +3272,8 @@ static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
 		if (fib == fib_entry->fib_node->fib)
 			continue;
 		fib = fib_entry->fib_node->fib;
-		err = mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib,
+		err = mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib->proto,
+							fib->vr->id,
 							old_adj_index,
 							old_ecmp_size,
 							nhgi->adj_index,
-- 
2.28.0


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

* [PATCH net-next 3/5] mlxsw: spectrum_router: Rollback virtual router adjacency pointer update
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 1/5] mlxsw: spectrum_router: Fix error handling issue Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 2/5] mlxsw: spectrum_router: Pass virtual router parameters directly instead of pointer Ido Schimmel
@ 2020-11-25 19:35 ` Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 4/5] mlxsw: spectrum_router: Track nexthop group virtual router membership Ido Schimmel
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ido Schimmel @ 2020-11-25 19:35 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, dsahern, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

In the rare case where the adjacency pointer cannot be updated for a
given virtual router, rollback the operation so that virtual routers
that are already using the new index will use the old one again.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index b229f28f6209..316182d6c1e3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3279,9 +3279,22 @@ static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
 							nhgi->adj_index,
 							nhgi->ecmp_size);
 		if (err)
-			return err;
+			goto err_mass_update_vr;
 	}
 	return 0;
+
+err_mass_update_vr:
+	list_for_each_entry_continue_reverse(fib_entry, &nh_grp->fib_list,
+					     nexthop_group_node) {
+		struct mlxsw_sp_nexthop_group_info *nhgi = nh_grp->nhgi;
+
+		fib = fib_entry->fib_node->fib;
+		mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib->proto,
+						  fib->vr->id, nhgi->adj_index,
+						  nhgi->ecmp_size,
+						  old_adj_index, old_ecmp_size);
+	}
+	return err;
 }
 
 static int __mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
-- 
2.28.0


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

* [PATCH net-next 4/5] mlxsw: spectrum_router: Track nexthop group virtual router membership
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
                   ` (2 preceding siblings ...)
  2020-11-25 19:35 ` [PATCH net-next 3/5] mlxsw: spectrum_router: Rollback virtual router adjacency pointer update Ido Schimmel
@ 2020-11-25 19:35 ` Ido Schimmel
  2020-11-25 19:35 ` [PATCH net-next 5/5] mlxsw: spectrum_router: Update adjacency index more efficiently Ido Schimmel
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ido Schimmel @ 2020-11-25 19:35 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, dsahern, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

For each nexthop group, track in which virtual routers (VRs) the group is
used. This is going to be used by the next patch to perform a more
efficient adjacency index update whenever the group's adjacency index
changes.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_router.c | 164 ++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 316182d6c1e3..9e3dfd2f7f45 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -2889,6 +2889,18 @@ struct mlxsw_sp_nexthop_group_info {
 #define nh_rif	nexthops[0].rif
 };
 
+struct mlxsw_sp_nexthop_group_vr_key {
+	u16 vr_id;
+	enum mlxsw_sp_l3proto proto;
+};
+
+struct mlxsw_sp_nexthop_group_vr_entry {
+	struct list_head list; /* member in vr_list */
+	struct rhash_head ht_node; /* member in vr_ht */
+	refcount_t ref_count;
+	struct mlxsw_sp_nexthop_group_vr_key key;
+};
+
 struct mlxsw_sp_nexthop_group {
 	struct rhash_head ht_node;
 	struct list_head fib_list; /* list of fib entries that use this group */
@@ -2901,6 +2913,8 @@ struct mlxsw_sp_nexthop_group {
 		} obj;
 	};
 	struct mlxsw_sp_nexthop_group_info *nhgi;
+	struct list_head vr_list;
+	struct rhashtable vr_ht;
 	enum mlxsw_sp_nexthop_group_type type;
 	bool can_destroy;
 };
@@ -3017,6 +3031,96 @@ bool mlxsw_sp_nexthop_is_discard(const struct mlxsw_sp_nexthop *nh)
 	return nh->discard;
 }
 
+static const struct rhashtable_params mlxsw_sp_nexthop_group_vr_ht_params = {
+	.key_offset = offsetof(struct mlxsw_sp_nexthop_group_vr_entry, key),
+	.head_offset = offsetof(struct mlxsw_sp_nexthop_group_vr_entry, ht_node),
+	.key_len = sizeof(struct mlxsw_sp_nexthop_group_vr_key),
+	.automatic_shrinking = true,
+};
+
+static struct mlxsw_sp_nexthop_group_vr_entry *
+mlxsw_sp_nexthop_group_vr_entry_lookup(struct mlxsw_sp_nexthop_group *nh_grp,
+				       const struct mlxsw_sp_fib *fib)
+{
+	struct mlxsw_sp_nexthop_group_vr_key key;
+
+	memset(&key, 0, sizeof(key));
+	key.vr_id = fib->vr->id;
+	key.proto = fib->proto;
+	return rhashtable_lookup_fast(&nh_grp->vr_ht, &key,
+				      mlxsw_sp_nexthop_group_vr_ht_params);
+}
+
+static int
+mlxsw_sp_nexthop_group_vr_entry_create(struct mlxsw_sp_nexthop_group *nh_grp,
+				       const struct mlxsw_sp_fib *fib)
+{
+	struct mlxsw_sp_nexthop_group_vr_entry *vr_entry;
+	int err;
+
+	vr_entry = kzalloc(sizeof(*vr_entry), GFP_KERNEL);
+	if (!vr_entry)
+		return -ENOMEM;
+
+	vr_entry->key.vr_id = fib->vr->id;
+	vr_entry->key.proto = fib->proto;
+	refcount_set(&vr_entry->ref_count, 1);
+
+	err = rhashtable_insert_fast(&nh_grp->vr_ht, &vr_entry->ht_node,
+				     mlxsw_sp_nexthop_group_vr_ht_params);
+	if (err)
+		goto err_hashtable_insert;
+
+	list_add(&vr_entry->list, &nh_grp->vr_list);
+
+	return 0;
+
+err_hashtable_insert:
+	kfree(vr_entry);
+	return err;
+}
+
+static void
+mlxsw_sp_nexthop_group_vr_entry_destroy(struct mlxsw_sp_nexthop_group *nh_grp,
+					struct mlxsw_sp_nexthop_group_vr_entry *vr_entry)
+{
+	list_del(&vr_entry->list);
+	rhashtable_remove_fast(&nh_grp->vr_ht, &vr_entry->ht_node,
+			       mlxsw_sp_nexthop_group_vr_ht_params);
+	kfree(vr_entry);
+}
+
+static int
+mlxsw_sp_nexthop_group_vr_link(struct mlxsw_sp_nexthop_group *nh_grp,
+			       const struct mlxsw_sp_fib *fib)
+{
+	struct mlxsw_sp_nexthop_group_vr_entry *vr_entry;
+
+	vr_entry = mlxsw_sp_nexthop_group_vr_entry_lookup(nh_grp, fib);
+	if (vr_entry) {
+		refcount_inc(&vr_entry->ref_count);
+		return 0;
+	}
+
+	return mlxsw_sp_nexthop_group_vr_entry_create(nh_grp, fib);
+}
+
+static void
+mlxsw_sp_nexthop_group_vr_unlink(struct mlxsw_sp_nexthop_group *nh_grp,
+				 const struct mlxsw_sp_fib *fib)
+{
+	struct mlxsw_sp_nexthop_group_vr_entry *vr_entry;
+
+	vr_entry = mlxsw_sp_nexthop_group_vr_entry_lookup(nh_grp, fib);
+	if (WARN_ON_ONCE(!vr_entry))
+		return;
+
+	if (!refcount_dec_and_test(&vr_entry->ref_count))
+		return;
+
+	mlxsw_sp_nexthop_group_vr_entry_destroy(nh_grp, vr_entry);
+}
+
 struct mlxsw_sp_nexthop_group_cmp_arg {
 	enum mlxsw_sp_nexthop_group_type type;
 	union {
@@ -4379,6 +4483,11 @@ mlxsw_sp_nexthop_obj_group_create(struct mlxsw_sp *mlxsw_sp,
 	nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL);
 	if (!nh_grp)
 		return ERR_PTR(-ENOMEM);
+	INIT_LIST_HEAD(&nh_grp->vr_list);
+	err = rhashtable_init(&nh_grp->vr_ht,
+			      &mlxsw_sp_nexthop_group_vr_ht_params);
+	if (err)
+		goto err_nexthop_group_vr_ht_init;
 	INIT_LIST_HEAD(&nh_grp->fib_list);
 	nh_grp->type = MLXSW_SP_NEXTHOP_GROUP_TYPE_OBJ;
 	nh_grp->obj.id = info->id;
@@ -4392,6 +4501,8 @@ mlxsw_sp_nexthop_obj_group_create(struct mlxsw_sp *mlxsw_sp,
 	return nh_grp;
 
 err_nexthop_group_info_init:
+	rhashtable_destroy(&nh_grp->vr_ht);
+err_nexthop_group_vr_ht_init:
 	kfree(nh_grp);
 	return ERR_PTR(err);
 }
@@ -4404,6 +4515,8 @@ mlxsw_sp_nexthop_obj_group_destroy(struct mlxsw_sp *mlxsw_sp,
 		return;
 	mlxsw_sp_nexthop_obj_group_info_fini(mlxsw_sp, nh_grp);
 	WARN_ON_ONCE(!list_empty(&nh_grp->fib_list));
+	WARN_ON_ONCE(!list_empty(&nh_grp->vr_list));
+	rhashtable_destroy(&nh_grp->vr_ht);
 	kfree(nh_grp);
 }
 
@@ -4652,6 +4765,11 @@ mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
 	nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL);
 	if (!nh_grp)
 		return ERR_PTR(-ENOMEM);
+	INIT_LIST_HEAD(&nh_grp->vr_list);
+	err = rhashtable_init(&nh_grp->vr_ht,
+			      &mlxsw_sp_nexthop_group_vr_ht_params);
+	if (err)
+		goto err_nexthop_group_vr_ht_init;
 	INIT_LIST_HEAD(&nh_grp->fib_list);
 	nh_grp->type = MLXSW_SP_NEXTHOP_GROUP_TYPE_IPV4;
 	nh_grp->ipv4.fi = fi;
@@ -4673,6 +4791,8 @@ mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
 	mlxsw_sp_nexthop4_group_info_fini(mlxsw_sp, nh_grp);
 err_nexthop_group_info_init:
 	fib_info_put(fi);
+	rhashtable_destroy(&nh_grp->vr_ht);
+err_nexthop_group_vr_ht_init:
 	kfree(nh_grp);
 	return ERR_PTR(err);
 }
@@ -4686,6 +4806,8 @@ mlxsw_sp_nexthop4_group_destroy(struct mlxsw_sp *mlxsw_sp,
 	mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp);
 	mlxsw_sp_nexthop4_group_info_fini(mlxsw_sp, nh_grp);
 	fib_info_put(nh_grp->ipv4.fi);
+	WARN_ON_ONCE(!list_empty(&nh_grp->vr_list));
+	rhashtable_destroy(&nh_grp->vr_ht);
 	kfree(nh_grp);
 }
 
@@ -5380,6 +5502,11 @@ mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp,
 	if (err)
 		goto err_nexthop4_group_get;
 
+	err = mlxsw_sp_nexthop_group_vr_link(fib_entry->nh_group,
+					     fib_node->fib);
+	if (err)
+		goto err_nexthop_group_vr_link;
+
 	err = mlxsw_sp_fib4_entry_type_set(mlxsw_sp, fen_info, fib_entry);
 	if (err)
 		goto err_fib4_entry_type_set;
@@ -5395,6 +5522,8 @@ mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp,
 	return fib4_entry;
 
 err_fib4_entry_type_set:
+	mlxsw_sp_nexthop_group_vr_unlink(fib_entry->nh_group, fib_node->fib);
+err_nexthop_group_vr_link:
 	mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common);
 err_nexthop4_group_get:
 	mlxsw_sp_fib_entry_priv_put(fib_entry->priv);
@@ -5406,8 +5535,12 @@ mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp,
 static void mlxsw_sp_fib4_entry_destroy(struct mlxsw_sp *mlxsw_sp,
 					struct mlxsw_sp_fib4_entry *fib4_entry)
 {
+	struct mlxsw_sp_fib_node *fib_node = fib4_entry->common.fib_node;
+
 	fib_info_put(fib4_entry->fi);
 	mlxsw_sp_fib4_entry_type_unset(mlxsw_sp, &fib4_entry->common);
+	mlxsw_sp_nexthop_group_vr_unlink(fib4_entry->common.nh_group,
+					 fib_node->fib);
 	mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common);
 	mlxsw_sp_fib_entry_priv_put(fib4_entry->common.priv);
 	kfree(fib4_entry);
@@ -5984,6 +6117,11 @@ mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,
 	nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL);
 	if (!nh_grp)
 		return ERR_PTR(-ENOMEM);
+	INIT_LIST_HEAD(&nh_grp->vr_list);
+	err = rhashtable_init(&nh_grp->vr_ht,
+			      &mlxsw_sp_nexthop_group_vr_ht_params);
+	if (err)
+		goto err_nexthop_group_vr_ht_init;
 	INIT_LIST_HEAD(&nh_grp->fib_list);
 	nh_grp->type = MLXSW_SP_NEXTHOP_GROUP_TYPE_IPV6;
 
@@ -6002,6 +6140,8 @@ mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,
 err_nexthop_group_insert:
 	mlxsw_sp_nexthop6_group_info_fini(mlxsw_sp, nh_grp);
 err_nexthop_group_info_init:
+	rhashtable_destroy(&nh_grp->vr_ht);
+err_nexthop_group_vr_ht_init:
 	kfree(nh_grp);
 	return ERR_PTR(err);
 }
@@ -6014,6 +6154,8 @@ mlxsw_sp_nexthop6_group_destroy(struct mlxsw_sp *mlxsw_sp,
 		return;
 	mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp);
 	mlxsw_sp_nexthop6_group_info_fini(mlxsw_sp, nh_grp);
+	WARN_ON_ONCE(!list_empty(&nh_grp->vr_list));
+	rhashtable_destroy(&nh_grp->vr_ht);
 	kfree(nh_grp);
 }
 
@@ -6073,8 +6215,10 @@ static int mlxsw_sp_nexthop6_group_update(struct mlxsw_sp *mlxsw_sp,
 					  struct mlxsw_sp_fib6_entry *fib6_entry)
 {
 	struct mlxsw_sp_nexthop_group *old_nh_grp = fib6_entry->common.nh_group;
+	struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
 	int err;
 
+	mlxsw_sp_nexthop_group_vr_unlink(old_nh_grp, fib_node->fib);
 	fib6_entry->common.nh_group = NULL;
 	list_del(&fib6_entry->common.nexthop_group_node);
 
@@ -6082,6 +6226,11 @@ static int mlxsw_sp_nexthop6_group_update(struct mlxsw_sp *mlxsw_sp,
 	if (err)
 		goto err_nexthop6_group_get;
 
+	err = mlxsw_sp_nexthop_group_vr_link(fib6_entry->common.nh_group,
+					     fib_node->fib);
+	if (err)
+		goto err_nexthop_group_vr_link;
+
 	/* In case this entry is offloaded, then the adjacency index
 	 * currently associated with it in the device's table is that
 	 * of the old group. Start using the new one instead.
@@ -6097,11 +6246,15 @@ static int mlxsw_sp_nexthop6_group_update(struct mlxsw_sp *mlxsw_sp,
 	return 0;
 
 err_fib_entry_update:
+	mlxsw_sp_nexthop_group_vr_unlink(fib6_entry->common.nh_group,
+					 fib_node->fib);
+err_nexthop_group_vr_link:
 	mlxsw_sp_nexthop6_group_put(mlxsw_sp, &fib6_entry->common);
 err_nexthop6_group_get:
 	list_add_tail(&fib6_entry->common.nexthop_group_node,
 		      &old_nh_grp->fib_list);
 	fib6_entry->common.nh_group = old_nh_grp;
+	mlxsw_sp_nexthop_group_vr_link(old_nh_grp, fib_node->fib);
 	return err;
 }
 
@@ -6233,12 +6386,19 @@ mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
 	if (err)
 		goto err_nexthop6_group_get;
 
+	err = mlxsw_sp_nexthop_group_vr_link(fib_entry->nh_group,
+					     fib_node->fib);
+	if (err)
+		goto err_nexthop_group_vr_link;
+
 	mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, rt_arr[0]);
 
 	fib_entry->fib_node = fib_node;
 
 	return fib6_entry;
 
+err_nexthop_group_vr_link:
+	mlxsw_sp_nexthop6_group_put(mlxsw_sp, fib_entry);
 err_nexthop6_group_get:
 	i = nrt6;
 err_rt6_create:
@@ -6258,6 +6418,10 @@ mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
 static void mlxsw_sp_fib6_entry_destroy(struct mlxsw_sp *mlxsw_sp,
 					struct mlxsw_sp_fib6_entry *fib6_entry)
 {
+	struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
+
+	mlxsw_sp_nexthop_group_vr_unlink(fib6_entry->common.nh_group,
+					 fib_node->fib);
 	mlxsw_sp_nexthop6_group_put(mlxsw_sp, &fib6_entry->common);
 	mlxsw_sp_fib6_entry_rt_destroy_all(fib6_entry);
 	WARN_ON(fib6_entry->nrt6);
-- 
2.28.0


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

* [PATCH net-next 5/5] mlxsw: spectrum_router: Update adjacency index more efficiently
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
                   ` (3 preceding siblings ...)
  2020-11-25 19:35 ` [PATCH net-next 4/5] mlxsw: spectrum_router: Track nexthop group virtual router membership Ido Schimmel
@ 2020-11-25 19:35 ` Ido Schimmel
  2020-11-25 22:53 ` [PATCH net-next 0/5] mlxsw: " David Ahern
  2020-11-28  1:30 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: Ido Schimmel @ 2020-11-25 19:35 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, jiri, dsahern, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@nvidia.com>

The device supports an operation that allows the driver to issue one
request to update the adjacency index for all the routes in a given
virtual router (VR) from old index and size to new ones. This is useful
in case the configuration of a certain nexthop group is updated and its
adjacency index changes.

Currently, the driver does not use this operation in an efficient
manner. It iterates over all the routes using the nexthop group and
issues an update request for the VR if it is not the same as the
previous VR.

Instead, use the VR tracking added in the previous patch to update the
adjacency index once for each VR currently using the nexthop group.

Example:

8k IPv6 routes were added in an alternating manner to two VRFs. All the
routes are using the same nexthop object ('nhid 1').

Before:

# perf stat -e devlink:devlink_hwmsg --filter='incoming==0' -- ip nexthop replace id 1 via 2001:db8:1::2 dev swp3

 Performance counter stats for 'ip nexthop replace id 1 via 2001:db8:1::2 dev swp3':

            16,385      devlink:devlink_hwmsg

       4.255933213 seconds time elapsed

       0.000000000 seconds user
       0.666923000 seconds sys

Number of EMAD transactions corresponds to number of routes using the
nexthop group.

After:

# perf stat -e devlink:devlink_hwmsg --filter='incoming==0' -- ip nexthop replace id 1 via 2001:db8:1::2 dev swp3

 Performance counter stats for 'ip nexthop replace id 1 via 2001:db8:1::2 dev swp3':

                 3      devlink:devlink_hwmsg

       0.077655094 seconds time elapsed

       0.000000000 seconds user
       0.076698000 seconds sys

Number of EMAD transactions corresponds to number of VRFs / VRs.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_router.c | 28 +++++++------------
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 9e3dfd2f7f45..12b5d7fbe1e2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3366,18 +3366,14 @@ static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
 					  struct mlxsw_sp_nexthop_group *nh_grp,
 					  u32 old_adj_index, u16 old_ecmp_size)
 {
-	struct mlxsw_sp_fib_entry *fib_entry;
-	struct mlxsw_sp_fib *fib = NULL;
+	struct mlxsw_sp_nexthop_group_info *nhgi = nh_grp->nhgi;
+	struct mlxsw_sp_nexthop_group_vr_entry *vr_entry;
 	int err;
 
-	list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) {
-		struct mlxsw_sp_nexthop_group_info *nhgi = nh_grp->nhgi;
-
-		if (fib == fib_entry->fib_node->fib)
-			continue;
-		fib = fib_entry->fib_node->fib;
-		err = mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib->proto,
-							fib->vr->id,
+	list_for_each_entry(vr_entry, &nh_grp->vr_list, list) {
+		err = mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp,
+							vr_entry->key.proto,
+							vr_entry->key.vr_id,
 							old_adj_index,
 							old_ecmp_size,
 							nhgi->adj_index,
@@ -3388,16 +3384,12 @@ static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
 	return 0;
 
 err_mass_update_vr:
-	list_for_each_entry_continue_reverse(fib_entry, &nh_grp->fib_list,
-					     nexthop_group_node) {
-		struct mlxsw_sp_nexthop_group_info *nhgi = nh_grp->nhgi;
-
-		fib = fib_entry->fib_node->fib;
-		mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib->proto,
-						  fib->vr->id, nhgi->adj_index,
+	list_for_each_entry_continue_reverse(vr_entry, &nh_grp->vr_list, list)
+		mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, vr_entry->key.proto,
+						  vr_entry->key.vr_id,
+						  nhgi->adj_index,
 						  nhgi->ecmp_size,
 						  old_adj_index, old_ecmp_size);
-	}
 	return err;
 }
 
-- 
2.28.0


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

* Re: [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
                   ` (4 preceding siblings ...)
  2020-11-25 19:35 ` [PATCH net-next 5/5] mlxsw: spectrum_router: Update adjacency index more efficiently Ido Schimmel
@ 2020-11-25 22:53 ` David Ahern
  2020-11-28  1:30 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: David Ahern @ 2020-11-25 22:53 UTC (permalink / raw)
  To: Ido Schimmel, netdev; +Cc: davem, kuba, jiri, mlxsw, Ido Schimmel

On 11/25/20 12:35 PM, Ido Schimmel wrote:
> Example:
> 
> 8k IPv6 routes were added in an alternating manner to two VRFs. All the
> routes are using the same nexthop object ('nhid 1').
> 
> Before:
> 
> # perf stat -e devlink:devlink_hwmsg --filter='incoming==0' -- ip nexthop replace id 1 via 2001:db8:1::2 dev swp3
> 
>  Performance counter stats for 'ip nexthop replace id 1 via 2001:db8:1::2 dev swp3':
> 
>             16,385      devlink:devlink_hwmsg
> 
>        4.255933213 seconds time elapsed
> 
>        0.000000000 seconds user
>        0.666923000 seconds sys
> 
> Number of EMAD transactions corresponds to number of routes using the
> nexthop group.
> 
> After:
> 
> # perf stat -e devlink:devlink_hwmsg --filter='incoming==0' -- ip nexthop replace id 1 via 2001:db8:1::2 dev swp3
> 
>  Performance counter stats for 'ip nexthop replace id 1 via 2001:db8:1::2 dev swp3':
> 
>                  3      devlink:devlink_hwmsg
> 
>        0.077655094 seconds time elapsed
> 
>        0.000000000 seconds user
>        0.076698000 seconds sys
> 
> Number of EMAD transactions corresponds to number of VRFs / VRs.

wow, that is a huge difference - a good example of the efficiencies the
nexthop model allows.


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

* Re: [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently
  2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
                   ` (5 preceding siblings ...)
  2020-11-25 22:53 ` [PATCH net-next 0/5] mlxsw: " David Ahern
@ 2020-11-28  1:30 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2020-11-28  1:30 UTC (permalink / raw)
  To: Ido Schimmel; +Cc: netdev, davem, kuba, jiri, dsahern, mlxsw, idosch

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Wed, 25 Nov 2020 21:35:00 +0200 you wrote:
> From: Ido Schimmel <idosch@nvidia.com>
> 
> The device supports an operation that allows the driver to issue one
> request to update the adjacency index for all the routes in a given
> virtual router (VR) from old index and size to new ones. This is useful
> in case the configuration of a certain nexthop group is updated and its
> adjacency index changes.
> 
> [...]

Here is the summary with links:
  - [net-next,1/5] mlxsw: spectrum_router: Fix error handling issue
    https://git.kernel.org/netdev/net-next/c/1c2c5eb6e108
  - [net-next,2/5] mlxsw: spectrum_router: Pass virtual router parameters directly instead of pointer
    https://git.kernel.org/netdev/net-next/c/40e4413d5dde
  - [net-next,3/5] mlxsw: spectrum_router: Rollback virtual router adjacency pointer update
    https://git.kernel.org/netdev/net-next/c/9a4ab10c74a0
  - [net-next,4/5] mlxsw: spectrum_router: Track nexthop group virtual router membership
    https://git.kernel.org/netdev/net-next/c/d2141a42b96a
  - [net-next,5/5] mlxsw: spectrum_router: Update adjacency index more efficiently
    https://git.kernel.org/netdev/net-next/c/ff47fa13c991

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2020-11-28  2:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-25 19:35 [PATCH net-next 0/5] mlxsw: Update adjacency index more efficiently Ido Schimmel
2020-11-25 19:35 ` [PATCH net-next 1/5] mlxsw: spectrum_router: Fix error handling issue Ido Schimmel
2020-11-25 19:35 ` [PATCH net-next 2/5] mlxsw: spectrum_router: Pass virtual router parameters directly instead of pointer Ido Schimmel
2020-11-25 19:35 ` [PATCH net-next 3/5] mlxsw: spectrum_router: Rollback virtual router adjacency pointer update Ido Schimmel
2020-11-25 19:35 ` [PATCH net-next 4/5] mlxsw: spectrum_router: Track nexthop group virtual router membership Ido Schimmel
2020-11-25 19:35 ` [PATCH net-next 5/5] mlxsw: spectrum_router: Update adjacency index more efficiently Ido Schimmel
2020-11-25 22:53 ` [PATCH net-next 0/5] mlxsw: " David Ahern
2020-11-28  1:30 ` patchwork-bot+netdevbpf

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.