]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
octeontx2-af: npc: cn20k: Propagate errors in defrag MCAM alloc rollback
authorRatheesh Kannoth <rkannoth@marvell.com>
Wed, 29 Apr 2026 02:27:15 +0000 (07:57 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 1 May 2026 01:50:16 +0000 (18:50 -0700)
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: 645c6e3c1999 ("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>
drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c

index 7170dcf262007163ae6ef0b98d114ae29f72aac0..87da43088b675fbb4e2b96e87b9108c9bcfafdb6 100644 (file)
@@ -2338,6 +2338,7 @@ err2:
                __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]);