mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 14:51:51 -04:00
octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback
npc_defrag_alloc_free_slots() allocates MCAM indexes in up to two passes on
bank0 then bank1. On failure it rolls back by freeing entries already
placed in save[].
__npc_subbank_alloc() can return a negative errno while only part of the
indexes are valid. The rollback loop used rc for
npc_mcam_idx_2_subbank_idx() as well, so a successful lookup stored zero in
rc and a later __npc_subbank_free() failure could still end with return 0
when the allocation path had also left rc at zero (for example shortfall
after zero return values from the alloc helpers).
Jump to the rollback path immediately when either __npc_subbank_alloc()
call fails, preserving its errno. If both calls succeed but the total
allocated count is still less than cnt, set rc to -ENOSPC before rollback.
Use a separate err variable for npc_mcam_idx_2_subbank_idx() so a
successful lookup no longer clears a non-zero rc from the allocation phase.
Cc: Dan Carpenter <error27@gmail.com>
Fixes: 645c6e3c19 ("octeontx2-af: npc: cn20k: virtual index support")
Link: https://lore.kernel.org/netdev/adjNJEpILRZATB2N@stanley.mountain/
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Link: https://patch.msgid.link/20260429022722.1110289-4-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
1100af13fd
commit
adb5ff41ef
@@ -2338,6 +2338,7 @@ static int __npc_subbank_alloc(struct rvu *rvu, struct npc_subbank *sb,
|
||||
__npc_subbank_mark_free(rvu, sb);
|
||||
err1:
|
||||
kfree(save);
|
||||
*alloc_cnt = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3515,7 +3516,7 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
|
||||
{
|
||||
int alloc_cnt1, alloc_cnt2;
|
||||
struct npc_subbank *sb;
|
||||
int rc, sb_off, i;
|
||||
int rc, sb_off, i, err;
|
||||
bool deleted;
|
||||
|
||||
sb = &npc_priv.sb[f->idx];
|
||||
@@ -3529,6 +3530,7 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
|
||||
NPC_MCAM_LOWER_PRIO,
|
||||
false, cnt, save, cnt, true,
|
||||
&alloc_cnt1);
|
||||
|
||||
if (alloc_cnt1 < cnt) {
|
||||
rc = __npc_subbank_alloc(rvu, sb,
|
||||
NPC_MCAM_KEY_X2, sb->b1b,
|
||||
@@ -3544,15 +3546,17 @@ static int npc_defrag_alloc_free_slots(struct rvu *rvu,
|
||||
dev_err(rvu->dev,
|
||||
"%s: Failed to alloc cnt=%u alloc_cnt1=%u alloc_cnt2=%u\n",
|
||||
__func__, cnt, alloc_cnt1, alloc_cnt2);
|
||||
rc = -ENOSPC;
|
||||
goto fail_free_alloc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_free_alloc:
|
||||
for (i = 0; i < alloc_cnt1 + alloc_cnt2; i++) {
|
||||
rc = npc_mcam_idx_2_subbank_idx(rvu, save[i],
|
||||
&sb, &sb_off);
|
||||
if (rc) {
|
||||
err = npc_mcam_idx_2_subbank_idx(rvu, save[i],
|
||||
&sb, &sb_off);
|
||||
if (err) {
|
||||
dev_err(rvu->dev,
|
||||
"%s: Error to find subbank for mcam idx=%u\n",
|
||||
__func__, save[i]);
|
||||
|
||||
Reference in New Issue
Block a user