Skip to content

Commit

Permalink
octeontx2-af: Add new devlink param to configure maximum usable NIX b…
Browse files Browse the repository at this point in the history
…lock LFs

On some silicon variants the number of available CAM entries are
less. Reserving one entry for each NIX-LF for default DMAC based pkt
forwarding rules will reduce the number of available CAM entries
further. Hence add configurability via devlink to set maximum number of
NIX-LFs needed which inturn frees up some CAM entries.

Signed-off-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Suman Ghosh authored and David S. Miller committed Dec 17, 2023
1 parent 3a3af3a commit dd78428
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 24 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.h
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,8 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx,
u64 bcast_mcast_val, u64 bcast_mcast_mask);
void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx);
bool npc_is_feature_supported(struct rvu *rvu, u64 features, u8 intf);
int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr);
void npc_mcam_rsrcs_deinit(struct rvu *rvu);

/* CPT APIs */
int rvu_cpt_register_interrupts(struct rvu *rvu);
Expand Down
80 changes: 80 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,7 @@ enum rvu_af_dl_param_id {
RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
};

static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
Expand Down Expand Up @@ -1354,6 +1355,79 @@ static int rvu_af_dl_npc_mcam_high_zone_percent_validate(struct devlink *devlink
return 0;
}

static int rvu_af_dl_nix_maxlf_get(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;

ctx->val.vu16 = (u16)rvu_get_nixlf_count(rvu);

return 0;
}

static int rvu_af_dl_nix_maxlf_set(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;
struct rvu_block *block;
int blkaddr = 0;

npc_mcam_rsrcs_deinit(rvu);
blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
while (blkaddr) {
block = &rvu->hw->block[blkaddr];
block->lf.max = ctx->val.vu16;
blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
}

blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
npc_mcam_rsrcs_init(rvu, blkaddr);

return 0;
}

static int rvu_af_dl_nix_maxlf_validate(struct devlink *devlink, u32 id,
union devlink_param_value val,
struct netlink_ext_ack *extack)
{
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;
u16 max_nix0_lf, max_nix1_lf;
struct npc_mcam *mcam;
u64 cfg;

cfg = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_CONST2);
max_nix0_lf = cfg & 0xFFF;
cfg = rvu_read64(rvu, BLKADDR_NIX1, NIX_AF_CONST2);
max_nix1_lf = cfg & 0xFFF;

/* Do not allow user to modify maximum NIX LFs while mcam entries
* have already been assigned.
*/
mcam = &rvu->hw->mcam;
if (mcam->bmap_fcnt < mcam->bmap_entries) {
NL_SET_ERR_MSG_MOD(extack,
"mcam entries have already been assigned, can't resize");
return -EPERM;
}

if (max_nix0_lf && val.vu16 > max_nix0_lf) {
NL_SET_ERR_MSG_MOD(extack,
"requested nixlf is greater than the max supported nix0_lf");
return -EPERM;
}

if (max_nix1_lf && val.vu16 > max_nix1_lf) {
NL_SET_ERR_MSG_MOD(extack,
"requested nixlf is greater than the max supported nix1_lf");
return -EINVAL;
}

return 0;
}

static const struct devlink_param rvu_af_dl_params[] = {
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
"dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
Expand All @@ -1375,6 +1449,12 @@ static const struct devlink_param rvu_af_dl_param_exact_match[] = {
rvu_af_dl_npc_mcam_high_zone_percent_get,
rvu_af_dl_npc_mcam_high_zone_percent_set,
rvu_af_dl_npc_mcam_high_zone_percent_validate),
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
"nix_maxlf", DEVLINK_PARAM_TYPE_U16,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
rvu_af_dl_nix_maxlf_get,
rvu_af_dl_nix_maxlf_set,
rvu_af_dl_nix_maxlf_validate),
};

/* Devlink switch mode */
Expand Down
75 changes: 51 additions & 24 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1846,7 +1846,21 @@ static void npc_parser_profile_init(struct rvu *rvu, int blkaddr)
npc_program_kpu_profile(rvu, blkaddr, idx, &rvu->kpu.kpu[idx]);
}

static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
void npc_mcam_rsrcs_deinit(struct rvu *rvu)
{
struct npc_mcam *mcam = &rvu->hw->mcam;

kfree(mcam->bmap);
kfree(mcam->bmap_reverse);
kfree(mcam->entry2pfvf_map);
kfree(mcam->cntr2pfvf_map);
kfree(mcam->entry2cntr_map);
kfree(mcam->cntr_refcnt);
kfree(mcam->entry2target_pffunc);
kfree(mcam->counters.bmap);
}

int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
{
int nixlf_count = rvu_get_nixlf_count(rvu);
struct npc_mcam *mcam = &rvu->hw->mcam;
Expand Down Expand Up @@ -1890,24 +1904,23 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
mcam->pf_offset = mcam->nixlf_offset + nixlf_count;

/* Allocate bitmaps for managing MCAM entries */
mcam->bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(mcam->bmap_entries),
sizeof(long), GFP_KERNEL);
mcam->bmap = kmalloc_array(BITS_TO_LONGS(mcam->bmap_entries),
sizeof(long), GFP_KERNEL);
if (!mcam->bmap)
return -ENOMEM;

mcam->bmap_reverse = devm_kcalloc(rvu->dev,
BITS_TO_LONGS(mcam->bmap_entries),
sizeof(long), GFP_KERNEL);
mcam->bmap_reverse = kmalloc_array(BITS_TO_LONGS(mcam->bmap_entries),
sizeof(long), GFP_KERNEL);
if (!mcam->bmap_reverse)
return -ENOMEM;
goto free_bmap;

mcam->bmap_fcnt = mcam->bmap_entries;

/* Alloc memory for saving entry to RVU PFFUNC allocation mapping */
mcam->entry2pfvf_map = devm_kcalloc(rvu->dev, mcam->bmap_entries,
sizeof(u16), GFP_KERNEL);
mcam->entry2pfvf_map = kmalloc_array(mcam->bmap_entries,
sizeof(u16), GFP_KERNEL);
if (!mcam->entry2pfvf_map)
return -ENOMEM;
goto free_bmap_reverse;

/* Reserve 1/8th of MCAM entries at the bottom for low priority
* allocations and another 1/8th at the top for high priority
Expand All @@ -1926,31 +1939,31 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
*/
err = rvu_alloc_bitmap(&mcam->counters);
if (err)
return err;
goto free_entry_map;

mcam->cntr2pfvf_map = devm_kcalloc(rvu->dev, mcam->counters.max,
sizeof(u16), GFP_KERNEL);
mcam->cntr2pfvf_map = kmalloc_array(mcam->counters.max,
sizeof(u16), GFP_KERNEL);
if (!mcam->cntr2pfvf_map)
goto free_mem;
goto free_cntr_bmap;

/* Alloc memory for MCAM entry to counter mapping and for tracking
* counter's reference count.
*/
mcam->entry2cntr_map = devm_kcalloc(rvu->dev, mcam->bmap_entries,
sizeof(u16), GFP_KERNEL);
mcam->entry2cntr_map = kmalloc_array(mcam->bmap_entries,
sizeof(u16), GFP_KERNEL);
if (!mcam->entry2cntr_map)
goto free_mem;
goto free_cntr_map;

mcam->cntr_refcnt = devm_kcalloc(rvu->dev, mcam->counters.max,
sizeof(u16), GFP_KERNEL);
mcam->cntr_refcnt = kmalloc_array(mcam->counters.max,
sizeof(u16), GFP_KERNEL);
if (!mcam->cntr_refcnt)
goto free_mem;
goto free_entry_cntr_map;

/* Alloc memory for saving target device of mcam rule */
mcam->entry2target_pffunc = devm_kcalloc(rvu->dev, mcam->total_entries,
sizeof(u16), GFP_KERNEL);
mcam->entry2target_pffunc = kmalloc_array(mcam->total_entries,
sizeof(u16), GFP_KERNEL);
if (!mcam->entry2target_pffunc)
goto free_mem;
goto free_cntr_refcnt;

for (index = 0; index < mcam->bmap_entries; index++) {
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
Expand All @@ -1964,8 +1977,21 @@ static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)

return 0;

free_mem:
free_cntr_refcnt:
kfree(mcam->cntr_refcnt);
free_entry_cntr_map:
kfree(mcam->entry2cntr_map);
free_cntr_map:
kfree(mcam->cntr2pfvf_map);
free_cntr_bmap:
kfree(mcam->counters.bmap);
free_entry_map:
kfree(mcam->entry2pfvf_map);
free_bmap_reverse:
kfree(mcam->bmap_reverse);
free_bmap:
kfree(mcam->counters.bmap);

return -ENOMEM;
}

Expand Down Expand Up @@ -2173,6 +2199,7 @@ void rvu_npc_freemem(struct rvu *rvu)
struct npc_mcam *mcam = &rvu->hw->mcam;

kfree(pkind->rsrc.bmap);
npc_mcam_rsrcs_deinit(rvu);
kfree(mcam->counters.bmap);
if (rvu->kpu_prfl_addr)
iounmap(rvu->kpu_prfl_addr);
Expand Down

0 comments on commit dd78428

Please sign in to comment.