mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free
npc_cn20k_dft_rules_free() used the NPC MCAM mbox "free all" path, which
does not match how cn20k tracks default-rule MCAM slots indexes.
Resolve the default-rule indices, then for each valid slot clear the bitmap
entry, drop the PF/VF map, disable the MCAM line, clear the target
function, and npc_cn20k_idx_free(). Remove any matching software mcam_rules
nodes. On hard failure from idx_free, WARN and stop so the box stays up for
analysis.
In npc_mcam_free_all_entries(), prefetch the same default-rule indices and,
on cn20k, skip bitmap clear and idx_free when the scanned entry is one of
those reserved defaults (they are released by npc_cn20k_dft_rules_free).
Fixes: 09d3b7a140 ("octeontx2-af: npc: cn20k: Allocate default MCAM indexes")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Link: https://patch.msgid.link/20260429022722.1110289-10-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
afb474bd4f
commit
013717353c
|
|
@ -4178,11 +4178,11 @@ static bool npc_is_cgx_or_lbk(struct rvu *rvu, u16 pcifunc)
|
||||||
|
|
||||||
void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc)
|
void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc)
|
||||||
{
|
{
|
||||||
struct npc_mcam_free_entry_req free_req = { 0 };
|
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||||
|
u16 ptr[4] = {[0 ... 3] = USHRT_MAX};
|
||||||
|
struct rvu_npc_mcam_rule *rule, *tmp;
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
struct msg_rsp rsp;
|
int blkaddr, rc, i;
|
||||||
u16 ptr[4];
|
|
||||||
int rc, i;
|
|
||||||
void *map;
|
void *map;
|
||||||
|
|
||||||
if (!npc_priv.init_done)
|
if (!npc_priv.init_done)
|
||||||
|
|
@ -4240,14 +4240,43 @@ void npc_cn20k_dft_rules_free(struct rvu *rvu, u16 pcifunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
free_rules:
|
free_rules:
|
||||||
|
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
|
||||||
|
if (blkaddr < 0)
|
||||||
|
return;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (ptr[i] == USHRT_MAX)
|
||||||
|
continue;
|
||||||
|
|
||||||
free_req.hdr.pcifunc = pcifunc;
|
mutex_lock(&mcam->lock);
|
||||||
free_req.all = 1;
|
npc_mcam_clear_bit(mcam, ptr[i]);
|
||||||
rc = rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp);
|
mcam->entry2pfvf_map[ptr[i]] = NPC_MCAM_INVALID_MAP;
|
||||||
if (rc)
|
npc_cn20k_enable_mcam_entry(rvu, blkaddr, ptr[i], false);
|
||||||
dev_err(rvu->dev,
|
mcam->entry2target_pffunc[ptr[i]] = 0x0;
|
||||||
"%s: Error deleting default entries (pcifunc=%#x\n",
|
mutex_unlock(&mcam->lock);
|
||||||
__func__, pcifunc);
|
|
||||||
|
rc = npc_cn20k_idx_free(rvu, &ptr[i], 1);
|
||||||
|
if (rc) {
|
||||||
|
/* Non recoverable error. Let us WARN and return. Keep system alive to
|
||||||
|
* enable debugging
|
||||||
|
*/
|
||||||
|
WARN(1, "%s Error deleting default entries (pcifunc=%#x) mcam_idx=%u\n",
|
||||||
|
__func__, pcifunc, ptr[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&mcam->lock);
|
||||||
|
list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (ptr[i] != rule->entry)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
list_del(&rule->list);
|
||||||
|
kfree(rule);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&mcam->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc)
|
int npc_cn20k_dft_rules_alloc(struct rvu *rvu, u16 pcifunc)
|
||||||
|
|
|
||||||
|
|
@ -2521,33 +2521,58 @@ void npc_mcam_clear_bit(struct npc_mcam *mcam, u16 index)
|
||||||
static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
|
static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
|
||||||
int blkaddr, u16 pcifunc)
|
int blkaddr, u16 pcifunc)
|
||||||
{
|
{
|
||||||
|
u16 dft_idxs[NPC_DFT_RULE_MAX_ID] = {[0 ... NPC_DFT_RULE_MAX_ID - 1] = USHRT_MAX};
|
||||||
|
bool cn20k_dft_rl;
|
||||||
u16 index, cntr;
|
u16 index, cntr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
npc_cn20k_dft_rules_idx_get(rvu, pcifunc,
|
||||||
|
&dft_idxs[NPC_DFT_RULE_BCAST_ID],
|
||||||
|
&dft_idxs[NPC_DFT_RULE_MCAST_ID],
|
||||||
|
&dft_idxs[NPC_DFT_RULE_PROMISC_ID],
|
||||||
|
&dft_idxs[NPC_DFT_RULE_UCAST_ID]);
|
||||||
|
|
||||||
/* Scan all MCAM entries and free the ones mapped to 'pcifunc' */
|
/* Scan all MCAM entries and free the ones mapped to 'pcifunc' */
|
||||||
for (index = 0; index < mcam->bmap_entries; index++) {
|
for (index = 0; index < mcam->bmap_entries; index++) {
|
||||||
if (mcam->entry2pfvf_map[index] == pcifunc) {
|
if (mcam->entry2pfvf_map[index] != pcifunc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cn20k_dft_rl = false;
|
||||||
|
|
||||||
|
if (is_cn20k(rvu->pdev)) {
|
||||||
|
if (dft_idxs[NPC_DFT_RULE_BCAST_ID] == index ||
|
||||||
|
dft_idxs[NPC_DFT_RULE_MCAST_ID] == index ||
|
||||||
|
dft_idxs[NPC_DFT_RULE_PROMISC_ID] == index ||
|
||||||
|
dft_idxs[NPC_DFT_RULE_UCAST_ID] == index) {
|
||||||
|
cn20k_dft_rl = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable the entry */
|
||||||
|
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
|
||||||
|
|
||||||
|
if (!cn20k_dft_rl) {
|
||||||
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
|
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
|
||||||
/* Free the entry in bitmap */
|
/* Free the entry in bitmap */
|
||||||
npc_mcam_clear_bit(mcam, index);
|
npc_mcam_clear_bit(mcam, index);
|
||||||
/* Disable the entry */
|
|
||||||
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
|
|
||||||
|
|
||||||
/* Update entry2counter mapping */
|
|
||||||
cntr = mcam->entry2cntr_map[index];
|
|
||||||
if (cntr != NPC_MCAM_INVALID_MAP)
|
|
||||||
npc_unmap_mcam_entry_and_cntr(rvu, mcam,
|
|
||||||
blkaddr, index,
|
|
||||||
cntr);
|
|
||||||
mcam->entry2target_pffunc[index] = 0x0;
|
mcam->entry2target_pffunc[index] = 0x0;
|
||||||
if (is_cn20k(rvu->pdev)) {
|
|
||||||
rc = npc_cn20k_idx_free(rvu, &index, 1);
|
|
||||||
if (rc)
|
|
||||||
dev_err(rvu->dev,
|
|
||||||
"Failed to free mcam idx=%u pcifunc=%#x\n",
|
|
||||||
index, pcifunc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update entry2counter mapping */
|
||||||
|
cntr = mcam->entry2cntr_map[index];
|
||||||
|
if (cntr != NPC_MCAM_INVALID_MAP)
|
||||||
|
npc_unmap_mcam_entry_and_cntr(rvu, mcam,
|
||||||
|
blkaddr, index,
|
||||||
|
cntr);
|
||||||
|
|
||||||
|
if (!is_cn20k(rvu->pdev) || cn20k_dft_rl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rc = npc_cn20k_idx_free(rvu, &index, 1);
|
||||||
|
if (rc)
|
||||||
|
dev_err(rvu->dev,
|
||||||
|
"Failed to free mcam idx=%u pcifunc=%#x\n",
|
||||||
|
index, pcifunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user