Skip to content

Commit 428168f

Browse files
committed
Merge branch 'mlxsw-trap-adjacency'
Ido Schimmel says: ==================== mlxsw: Alter trap adjacency entry allocation scheme In commit 0c3cbbf ("mlxsw: Add specific trap for packets routed via invalid nexthops"), mlxsw started allocating a new adjacency entry during driver initialization, to trap packets routed via invalid nexthops. This behavior was later altered in commit 983db61 ("mlxsw: spectrum_router: Allocate discard adjacency entry when needed") to only allocate the entry upon the first route that requires it. The motivation for the change is explained in the commit message. The problem with the current behavior is that the entry shows up as a "leak" in a new BPF resource monitoring tool [1]. This is caused by the asymmetry of the allocation/free scheme. While the entry is allocated upon the first route that requires it, it is only freed during de-initialization of the driver. Instead, this patchset tracks the number of active nexthop groups and allocates the adjacency entry upon the creation of the first group. The entry is freed when the number of active groups reaches zero. Patch #1 adds the new entry. Patch #2 converts mlxsw to start using the new entry and removes the old one. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 8bea96e + e3a3aae commit 428168f

File tree

2 files changed

+81
-52
lines changed

2 files changed

+81
-52
lines changed

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

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4376,6 +4376,66 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
43764376
}
43774377
}
43784378

4379+
static int mlxsw_sp_adj_trap_entry_init(struct mlxsw_sp *mlxsw_sp)
4380+
{
4381+
enum mlxsw_reg_ratr_trap_action trap_action;
4382+
char ratr_pl[MLXSW_REG_RATR_LEN];
4383+
int err;
4384+
4385+
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
4386+
&mlxsw_sp->router->adj_trap_index);
4387+
if (err)
4388+
return err;
4389+
4390+
trap_action = MLXSW_REG_RATR_TRAP_ACTION_TRAP;
4391+
mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, true,
4392+
MLXSW_REG_RATR_TYPE_ETHERNET,
4393+
mlxsw_sp->router->adj_trap_index,
4394+
mlxsw_sp->router->lb_rif_index);
4395+
mlxsw_reg_ratr_trap_action_set(ratr_pl, trap_action);
4396+
mlxsw_reg_ratr_trap_id_set(ratr_pl, MLXSW_TRAP_ID_RTR_EGRESS0);
4397+
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
4398+
if (err)
4399+
goto err_ratr_write;
4400+
4401+
return 0;
4402+
4403+
err_ratr_write:
4404+
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
4405+
mlxsw_sp->router->adj_trap_index);
4406+
return err;
4407+
}
4408+
4409+
static void mlxsw_sp_adj_trap_entry_fini(struct mlxsw_sp *mlxsw_sp)
4410+
{
4411+
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
4412+
mlxsw_sp->router->adj_trap_index);
4413+
}
4414+
4415+
static int mlxsw_sp_nexthop_group_inc(struct mlxsw_sp *mlxsw_sp)
4416+
{
4417+
int err;
4418+
4419+
if (refcount_inc_not_zero(&mlxsw_sp->router->num_groups))
4420+
return 0;
4421+
4422+
err = mlxsw_sp_adj_trap_entry_init(mlxsw_sp);
4423+
if (err)
4424+
return err;
4425+
4426+
refcount_set(&mlxsw_sp->router->num_groups, 1);
4427+
4428+
return 0;
4429+
}
4430+
4431+
static void mlxsw_sp_nexthop_group_dec(struct mlxsw_sp *mlxsw_sp)
4432+
{
4433+
if (!refcount_dec_and_test(&mlxsw_sp->router->num_groups))
4434+
return;
4435+
4436+
mlxsw_sp_adj_trap_entry_fini(mlxsw_sp);
4437+
}
4438+
43794439
static void
43804440
mlxsw_sp_nh_grp_activity_get(struct mlxsw_sp *mlxsw_sp,
43814441
const struct mlxsw_sp_nexthop_group *nh_grp,
@@ -4790,6 +4850,9 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
47904850
if (err)
47914851
goto err_nexthop_obj_init;
47924852
}
4853+
err = mlxsw_sp_nexthop_group_inc(mlxsw_sp);
4854+
if (err)
4855+
goto err_group_inc;
47934856
err = mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
47944857
if (err) {
47954858
NL_SET_ERR_MSG_MOD(info->extack, "Failed to write adjacency entries to the device");
@@ -4808,6 +4871,8 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
48084871
return 0;
48094872

48104873
err_group_refresh:
4874+
mlxsw_sp_nexthop_group_dec(mlxsw_sp);
4875+
err_group_inc:
48114876
i = nhgi->count;
48124877
err_nexthop_obj_init:
48134878
for (i--; i >= 0; i--) {
@@ -4832,6 +4897,7 @@ mlxsw_sp_nexthop_obj_group_info_fini(struct mlxsw_sp *mlxsw_sp,
48324897
cancel_delayed_work(&router->nh_grp_activity_dw);
48334898
}
48344899

4900+
mlxsw_sp_nexthop_group_dec(mlxsw_sp);
48354901
for (i = nhgi->count - 1; i >= 0; i--) {
48364902
struct mlxsw_sp_nexthop *nh = &nhgi->nexthops[i];
48374903

@@ -5223,13 +5289,18 @@ mlxsw_sp_nexthop4_group_info_init(struct mlxsw_sp *mlxsw_sp,
52235289
if (err)
52245290
goto err_nexthop4_init;
52255291
}
5292+
err = mlxsw_sp_nexthop_group_inc(mlxsw_sp);
5293+
if (err)
5294+
goto err_group_inc;
52265295
err = mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
52275296
if (err)
52285297
goto err_group_refresh;
52295298

52305299
return 0;
52315300

52325301
err_group_refresh:
5302+
mlxsw_sp_nexthop_group_dec(mlxsw_sp);
5303+
err_group_inc:
52335304
i = nhgi->count;
52345305
err_nexthop4_init:
52355306
for (i--; i >= 0; i--) {
@@ -5247,6 +5318,7 @@ mlxsw_sp_nexthop4_group_info_fini(struct mlxsw_sp *mlxsw_sp,
52475318
struct mlxsw_sp_nexthop_group_info *nhgi = nh_grp->nhgi;
52485319
int i;
52495320

5321+
mlxsw_sp_nexthop_group_dec(mlxsw_sp);
52505322
for (i = nhgi->count - 1; i >= 0; i--) {
52515323
struct mlxsw_sp_nexthop *nh = &nhgi->nexthops[i];
52525324

@@ -5725,41 +5797,6 @@ static int mlxsw_sp_fib_entry_commit(struct mlxsw_sp *mlxsw_sp,
57255797
return err;
57265798
}
57275799

5728-
static int mlxsw_sp_adj_discard_write(struct mlxsw_sp *mlxsw_sp)
5729-
{
5730-
enum mlxsw_reg_ratr_trap_action trap_action;
5731-
char ratr_pl[MLXSW_REG_RATR_LEN];
5732-
int err;
5733-
5734-
if (mlxsw_sp->router->adj_discard_index_valid)
5735-
return 0;
5736-
5737-
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
5738-
&mlxsw_sp->router->adj_discard_index);
5739-
if (err)
5740-
return err;
5741-
5742-
trap_action = MLXSW_REG_RATR_TRAP_ACTION_TRAP;
5743-
mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, true,
5744-
MLXSW_REG_RATR_TYPE_ETHERNET,
5745-
mlxsw_sp->router->adj_discard_index,
5746-
mlxsw_sp->router->lb_rif_index);
5747-
mlxsw_reg_ratr_trap_action_set(ratr_pl, trap_action);
5748-
mlxsw_reg_ratr_trap_id_set(ratr_pl, MLXSW_TRAP_ID_RTR_EGRESS0);
5749-
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
5750-
if (err)
5751-
goto err_ratr_write;
5752-
5753-
mlxsw_sp->router->adj_discard_index_valid = true;
5754-
5755-
return 0;
5756-
5757-
err_ratr_write:
5758-
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
5759-
mlxsw_sp->router->adj_discard_index);
5760-
return err;
5761-
}
5762-
57635800
static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
57645801
struct mlxsw_sp_fib_entry_op_ctx *op_ctx,
57655802
struct mlxsw_sp_fib_entry *fib_entry,
@@ -5772,7 +5809,6 @@ static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
57725809
u16 trap_id = 0;
57735810
u32 adjacency_index = 0;
57745811
u16 ecmp_size = 0;
5775-
int err;
57765812

57775813
/* In case the nexthop group adjacency index is valid, use it
57785814
* with provided ECMP size. Otherwise, setup trap and pass
@@ -5783,11 +5819,8 @@ static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
57835819
adjacency_index = nhgi->adj_index;
57845820
ecmp_size = nhgi->ecmp_size;
57855821
} else if (!nhgi->adj_index_valid && nhgi->count && nhgi->nh_rif) {
5786-
err = mlxsw_sp_adj_discard_write(mlxsw_sp);
5787-
if (err)
5788-
return err;
57895822
trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
5790-
adjacency_index = mlxsw_sp->router->adj_discard_index;
5823+
adjacency_index = mlxsw_sp->router->adj_trap_index;
57915824
ecmp_size = 1;
57925825
} else {
57935826
trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
@@ -6641,13 +6674,18 @@ mlxsw_sp_nexthop6_group_info_init(struct mlxsw_sp *mlxsw_sp,
66416674
mlxsw_sp_rt6 = list_next_entry(mlxsw_sp_rt6, list);
66426675
}
66436676
nh_grp->nhgi = nhgi;
6677+
err = mlxsw_sp_nexthop_group_inc(mlxsw_sp);
6678+
if (err)
6679+
goto err_group_inc;
66446680
err = mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
66456681
if (err)
66466682
goto err_group_refresh;
66476683

66486684
return 0;
66496685

66506686
err_group_refresh:
6687+
mlxsw_sp_nexthop_group_dec(mlxsw_sp);
6688+
err_group_inc:
66516689
i = nhgi->count;
66526690
err_nexthop6_init:
66536691
for (i--; i >= 0; i--) {
@@ -6665,6 +6703,7 @@ mlxsw_sp_nexthop6_group_info_fini(struct mlxsw_sp *mlxsw_sp,
66656703
struct mlxsw_sp_nexthop_group_info *nhgi = nh_grp->nhgi;
66666704
int i;
66676705

6706+
mlxsw_sp_nexthop_group_dec(mlxsw_sp);
66686707
for (i = nhgi->count - 1; i >= 0; i--) {
66696708
struct mlxsw_sp_nexthop *nh = &nhgi->nexthops[i];
66706709

@@ -7340,16 +7379,6 @@ static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp)
73407379
continue;
73417380
mlxsw_sp_vr_fib_flush(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
73427381
}
7343-
7344-
/* After flushing all the routes, it is not possible anyone is still
7345-
* using the adjacency index that is discarding packets, so free it in
7346-
* case it was allocated.
7347-
*/
7348-
if (!mlxsw_sp->router->adj_discard_index_valid)
7349-
return;
7350-
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
7351-
mlxsw_sp->router->adj_discard_index);
7352-
mlxsw_sp->router->adj_discard_index_valid = false;
73537382
}
73547383

73557384
struct mlxsw_sp_fib6_event {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ struct mlxsw_sp_router {
6565
struct notifier_block inet6addr_nb;
6666
const struct mlxsw_sp_rif_ops **rif_ops_arr;
6767
const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
68-
u32 adj_discard_index;
69-
bool adj_discard_index_valid;
7068
struct mlxsw_sp_router_nve_decap nve_decap_config;
7169
struct mutex lock; /* Protects shared router resources */
7270
struct work_struct fib_event_work;
@@ -82,6 +80,8 @@ struct mlxsw_sp_router {
8280
struct delayed_work nh_grp_activity_dw;
8381
struct list_head nh_res_grp_list;
8482
bool inc_parsing_depth;
83+
refcount_t num_groups;
84+
u32 adj_trap_index;
8585
};
8686

8787
struct mlxsw_sp_fib_entry_priv {

0 commit comments

Comments
 (0)