Skip to content

Commit 44c2fbe

Browse files
pmachatakuba-moo
authored andcommitted
mlxsw: spectrum_router: Share nexthop counters in resilient groups
For resilient groups, we can reuse the same counter for all the buckets that share the same nexthop. Keep a reference count per counter, and keep all these counters in a per-next hop group xarray, which serves as a NHID->counter cache. If a counter is already present for a given NHID, just take a reference and use the same counter. Signed-off-by: Petr Machata <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Link: https://lore.kernel.org/r/cdd00084533fc83ac5917562f54642f008205bf3.1709901020.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5a5a98e commit 44c2fbe

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/net_namespace.h>
2020
#include <linux/mutex.h>
2121
#include <linux/genalloc.h>
22+
#include <linux/xarray.h>
2223
#include <net/netevent.h>
2324
#include <net/neighbour.h>
2425
#include <net/arp.h>
@@ -3111,6 +3112,7 @@ struct mlxsw_sp_nexthop_group_info {
31113112
is_resilient:1,
31123113
hw_stats:1;
31133114
struct list_head list; /* member in nh_res_grp_list */
3115+
struct xarray nexthop_counters;
31143116
struct mlxsw_sp_nexthop nexthops[] __counted_by(count);
31153117
};
31163118

@@ -3156,6 +3158,7 @@ struct mlxsw_sp_nexthop_group {
31563158

31573159
struct mlxsw_sp_nexthop_counter {
31583160
unsigned int counter_index;
3161+
refcount_t ref_count;
31593162
};
31603163

31613164
static struct mlxsw_sp_nexthop_counter *
@@ -3172,6 +3175,7 @@ mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp)
31723175
if (err)
31733176
goto err_counter_alloc;
31743177

3178+
refcount_set(&nhct->ref_count, 1);
31753179
return nhct;
31763180

31773181
err_counter_alloc:
@@ -3187,6 +3191,56 @@ mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
31873191
kfree(nhct);
31883192
}
31893193

3194+
static struct mlxsw_sp_nexthop_counter *
3195+
mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp,
3196+
struct mlxsw_sp_nexthop *nh)
3197+
{
3198+
struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp;
3199+
struct mlxsw_sp_nexthop_counter *nhct;
3200+
void *ptr;
3201+
int err;
3202+
3203+
nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id);
3204+
if (nhct) {
3205+
refcount_inc(&nhct->ref_count);
3206+
return nhct;
3207+
}
3208+
3209+
nhct = mlxsw_sp_nexthop_counter_alloc(mlxsw_sp);
3210+
if (IS_ERR(nhct))
3211+
return nhct;
3212+
3213+
ptr = xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct,
3214+
GFP_KERNEL);
3215+
if (IS_ERR(ptr)) {
3216+
err = PTR_ERR(ptr);
3217+
goto err_store;
3218+
}
3219+
3220+
return nhct;
3221+
3222+
err_store:
3223+
mlxsw_sp_nexthop_counter_free(mlxsw_sp, nhct);
3224+
return ERR_PTR(err);
3225+
}
3226+
3227+
static void mlxsw_sp_nexthop_sh_counter_put(struct mlxsw_sp *mlxsw_sp,
3228+
struct mlxsw_sp_nexthop *nh)
3229+
{
3230+
struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp;
3231+
struct mlxsw_sp_nexthop_counter *nhct;
3232+
3233+
nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id);
3234+
if (WARN_ON(!nhct))
3235+
return;
3236+
3237+
if (!refcount_dec_and_test(&nhct->ref_count))
3238+
return;
3239+
3240+
xa_erase(&nh_grp->nhgi->nexthop_counters, nh->id);
3241+
mlxsw_sp_nexthop_counter_free(mlxsw_sp, nhct);
3242+
}
3243+
31903244
int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp,
31913245
struct mlxsw_sp_nexthop *nh)
31923246
{
@@ -3203,7 +3257,10 @@ int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp,
32033257
if (!(nh->nhgi->hw_stats || dpipe_stats))
32043258
return 0;
32053259

3206-
nhct = mlxsw_sp_nexthop_counter_alloc(mlxsw_sp);
3260+
if (nh->id)
3261+
nhct = mlxsw_sp_nexthop_sh_counter_get(mlxsw_sp, nh);
3262+
else
3263+
nhct = mlxsw_sp_nexthop_counter_alloc(mlxsw_sp);
32073264
if (IS_ERR(nhct))
32083265
return PTR_ERR(nhct);
32093266

@@ -3216,7 +3273,11 @@ void mlxsw_sp_nexthop_counter_disable(struct mlxsw_sp *mlxsw_sp,
32163273
{
32173274
if (!nh->counter)
32183275
return;
3219-
mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh->counter);
3276+
3277+
if (nh->id)
3278+
mlxsw_sp_nexthop_sh_counter_put(mlxsw_sp, nh);
3279+
else
3280+
mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh->counter);
32203281
nh->counter = NULL;
32213282
}
32223283

@@ -5145,6 +5206,9 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
51455206
nhgi->is_resilient = is_resilient;
51465207
nhgi->count = nhs;
51475208
nhgi->hw_stats = hw_stats;
5209+
5210+
xa_init_flags(&nhgi->nexthop_counters, XA_FLAGS_ALLOC1);
5211+
51485212
for (i = 0; i < nhgi->count; i++) {
51495213
struct nh_notifier_single_info *nh_obj;
51505214
int weight;
@@ -5227,6 +5291,8 @@ mlxsw_sp_nexthop_obj_group_info_fini(struct mlxsw_sp *mlxsw_sp,
52275291
}
52285292
mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
52295293
WARN_ON_ONCE(nhgi->adj_index_valid);
5294+
WARN_ON(!xa_empty(&nhgi->nexthop_counters));
5295+
xa_destroy(&nhgi->nexthop_counters);
52305296
kfree(nhgi);
52315297
}
52325298

0 commit comments

Comments
 (0)