* [PATCH v2 net-next] octeontx2-af: add tracepoints for NPC MCAM entry programming
@ 2026-09-23 3:48 Ratheesh Kannoth
2026-09-27 4:46 ` netdev-bot+sashiko
0 siblings, 1 reply; 2+ messages in thread
From: Ratheesh Kannoth @ 2026-09-23 3:48 UTC (permalink / raw)
To: linux-kernel, netdev
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham,
Suman Ghosh, Ratheesh Kannoth
From: Suman Ghosh <sumang@marvell.com>
Add ftrace events for MCAM allocation, CAM keyword writes, action/tag
programming, enable/disable, and entry copies. Emit them from the legacy
and CN20K NPC alloc, config, read, and shift paths so mailbox-driven
rule changes can be correlated with the programmed MCAM state.
---
v1 -> v2: Addressed sashiko comments.
- Assign pcifunc in otx2_npc_mcam_alloc_entries() and print it as 0x%x;
record start_mcam_idx from rsp->entry_list[0] for non-contiguous
allocations.
- Pass absolute actindex to cam/action traces and mask tx_intf to 0x1 on
TX interfaces so emitters agree on mcam_index and tx_intf semantics.
- Add otx2_npc_mcam_copy and emit it from npc_copy_mcam_entry() to cover
MCAM entry shifts; emit cam/action traces from the CN20K config path.
- Drop redundant TP_printk newlines; zero npc_mcam_alloc_entry_req on
stack in alloc-and-write mailbox handlers before tracing kw_type/virt.
https://lore.kernel.org/netdev/20260915025014.928685-1-rkannoth@marvell.com/
Signed-off-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/cn20k/npc.c | 51 +++++---
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 69 +++++++----
.../ethernet/marvell/octeontx2/af/rvu_trace.c | 5 +
.../ethernet/marvell/octeontx2/af/rvu_trace.h | 114 ++++++++++++++++++
4 files changed, 196 insertions(+), 43 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
index 7c829b1da3e5..0b485728f399 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
@@ -15,6 +15,7 @@
#include "cn20k/npc.h"
#include "cn20k/reg.h"
#include "rvu_npc_fs.h"
+#include <rvu_trace.h>
static struct npc_priv_t *npc_priv;
@@ -973,13 +974,15 @@ static void npc_cn20k_config_kw_x2(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, u8 intf,
struct cn20k_mcam_entry *entry,
int bank, u8 kw_type, int kw,
- u8 req_kw_type)
+ u8 req_kw_type, u16 actindex)
{
+ u64 w0_cam0, w0_cam1, w1_cam0, w1_cam1;
+ u64 w2_cam0, w2_cam1, w3_cam0, w3_cam1;
u64 intf_ext = 0, intf_ext_mask = 0;
u8 tx_intf_mask = ~intf & 0x3;
u8 tx_intf = intf, kex_type;
u8 kw_type_mask = ~kw_type;
- u64 cam0, cam1, kex_cfg;
+ u64 kex_cfg;
if (is_npc_intf_tx(intf)) {
/* Last bit must be set and rest don't care
@@ -1018,43 +1021,46 @@ static void npc_cn20k_config_kw_x2(struct rvu *rvu, struct npc_mcam *mcam,
intf_ext_mask);
/* Set the match key */
- npc_cn20k_get_keyword(entry, kw, &cam0, &cam1);
+ npc_cn20k_get_keyword(entry, kw, &w0_cam0, &w0_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index, bank, 1),
- cam1);
+ w0_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W0_EXT(index, bank, 0),
- cam0);
+ w0_cam0);
- npc_cn20k_get_keyword(entry, kw + 1, &cam0, &cam1);
+ npc_cn20k_get_keyword(entry, kw + 1, &w1_cam0, &w1_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index, bank, 1),
- cam1);
+ w1_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W1_EXT(index, bank, 0),
- cam0);
+ w1_cam0);
- npc_cn20k_get_keyword(entry, kw + 2, &cam0, &cam1);
+ npc_cn20k_get_keyword(entry, kw + 2, &w2_cam0, &w2_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index, bank, 1),
- cam1);
+ w2_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W2_EXT(index, bank, 0),
- cam0);
+ w2_cam0);
- npc_cn20k_get_keyword(entry, kw + 3, &cam0, &cam1);
+ npc_cn20k_get_keyword(entry, kw + 3, &w3_cam0, &w3_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 1),
- cam1);
+ w3_cam1);
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 0),
- cam0);
+ w3_cam0);
+
+ trace_otx2_npc_cam(actindex, bank, w0_cam0, w0_cam1, w1_cam0, w1_cam1);
+ trace_otx2_npc_cam(actindex, bank, w2_cam0, w2_cam1, w3_cam0, w3_cam1);
}
static void npc_cn20k_config_kw_x4(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, u8 intf,
struct cn20k_mcam_entry *entry,
- u8 kw_type, u8 req_kw_type)
+ u8 kw_type, u8 req_kw_type, u16 actindex)
{
int kw = 0, bank;
@@ -1062,7 +1068,7 @@ static void npc_cn20k_config_kw_x4(struct rvu *rvu, struct npc_mcam *mcam,
npc_cn20k_config_kw_x2(rvu, mcam, blkaddr,
index, intf,
entry, bank, kw_type,
- kw, req_kw_type);
+ kw, req_kw_type, actindex);
}
int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
@@ -1071,10 +1077,11 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int mcam_idx = index % mcam->banksize;
+ int actbank = npc_get_bank(mcam, index);
int bank = index / mcam->banksize;
u64 bank_cfg = (u64)hw_prio << 24;
+ u8 kw_type, tx_intf = intf;
int kw = 0;
- u8 kw_type;
if (index < 0 || index >= mcam->total_entries)
return -EINVAL;
@@ -1097,7 +1104,7 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
npc_clear_x2_entry(rvu, blkaddr, bank, mcam_idx);
npc_cn20k_config_kw_x2(rvu, mcam, blkaddr,
mcam_idx, intf, entry,
- bank, kw_type, kw, req_kw_type);
+ bank, kw_type, kw, req_kw_type, index);
/* Set 'action' */
rvu_write64(rvu, blkaddr,
NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_idx,
@@ -1128,7 +1135,7 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
npc_cn20k_config_kw_x4(rvu, mcam, blkaddr,
mcam_idx, intf, entry,
- kw_type, req_kw_type);
+ kw_type, req_kw_type, index);
for (bank = 0; bank < mcam->banks_per_entry; bank++) {
/* Set 'action' */
rvu_write64(rvu, blkaddr,
@@ -1157,6 +1164,10 @@ int npc_cn20k_config_mcam_entry(struct rvu *rvu, int blkaddr, int index,
/* TODO: */
/* PF installing VF rule */
+ if (is_npc_intf_tx(intf))
+ tx_intf &= 0x1;
+ trace_otx2_npc_action(index, actbank, tx_intf, (u8)enable,
+ entry->action, entry->vtag_action);
if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable))
return -EINVAL;
@@ -1434,7 +1445,7 @@ int rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry(struct rvu *rvu,
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
struct npc_mcam_free_entry_req free_req = { 0 };
- struct npc_mcam_alloc_entry_req entry_req;
+ struct npc_mcam_alloc_entry_req entry_req = { 0 };
struct npc_mcam_alloc_entry_rsp entry_rsp;
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 entry = NPC_MCAM_ENTRY_INVALID;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index 42a601976db3..fe8625ee4051 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -20,6 +20,7 @@
#include "rvu_npc.h"
#include "cn20k/reg.h"
#include "lmac_common.h"
+#include <rvu_trace.h>
#define RSVD_MCAM_ENTRIES_PER_PF 3 /* Broadcast, Promisc and AllMulticast */
#define RSVD_MCAM_ENTRIES_PER_NIXLF 1 /* Ucast for LFs */
@@ -259,6 +260,7 @@ void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int bank = npc_get_bank(mcam, index);
int actbank = bank;
+ trace_otx2_npc_enable_mcam_entry(index, (u8)enable);
if (is_cn20k(rvu->pdev)) {
if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable))
dev_err(rvu->dev, "Error to %s mcam %u entry\n",
@@ -521,10 +523,10 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
struct mcam_entry *entry, bool enable)
{
int bank = npc_get_bank(mcam, index);
+ u64 w0_cam0, w0_cam1, w1_cam0, w1_cam1;
int kw = 0, actbank, actindex;
u8 tx_intf_mask = ~intf & 0x3;
u8 tx_intf = intf;
- u64 cam0, cam1;
actbank = bank; /* Save bank id, to set action later on */
actindex = index;
@@ -561,17 +563,18 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
tx_intf_mask);
/* Set the match key */
- npc_get_keyword(entry, kw, &cam0, &cam1);
+ npc_get_keyword(entry, kw, &w0_cam0, &w0_cam1);
rvu_write64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 1), cam1);
+ NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 1), w0_cam1);
rvu_write64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 0), cam0);
+ NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 0), w0_cam0);
- npc_get_keyword(entry, kw + 1, &cam0, &cam1);
+ npc_get_keyword(entry, kw + 1, &w1_cam0, &w1_cam1);
rvu_write64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 1), cam1);
+ NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 1), w1_cam1);
rvu_write64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), cam0);
+ NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), w1_cam0);
+ trace_otx2_npc_cam(actindex, bank, w0_cam0, w0_cam1, w1_cam0, w1_cam1);
}
/* PF installing VF rule */
@@ -586,6 +589,10 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
rvu_write64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_TAG_ACT(index, actbank),
entry->vtag_action);
+ if (is_npc_intf_tx(intf))
+ tx_intf &= 0x1;
+ trace_otx2_npc_action(actindex, actbank, tx_intf, (u8)enable,
+ entry->action, entry->vtag_action);
/* Enable the entry */
if (enable)
npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, true);
@@ -596,24 +603,27 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
struct mcam_entry *entry, u8 *intf, u8 *ena)
{
int sbank = npc_get_bank(mcam, src);
+ u64 w0_cam0, w0_cam1, w1_cam0, w1_cam1;
+ u16 actindex = src;
+ u8 tx_intf;
int bank, kw = 0;
- u64 cam0, cam1;
src &= (mcam->banksize - 1);
bank = sbank;
for (; bank < (sbank + mcam->banks_per_entry); bank++, kw = kw + 2) {
- cam1 = rvu_read64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 1));
- cam0 = rvu_read64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 0));
- npc_fill_entryword(entry, kw, cam0, cam1);
+ w0_cam1 = rvu_read64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 1));
+ w0_cam0 = rvu_read64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 0));
+ npc_fill_entryword(entry, kw, w0_cam0, w0_cam1);
- cam1 = rvu_read64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 1));
- cam0 = rvu_read64(rvu, blkaddr,
- NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 0));
- npc_fill_entryword(entry, kw + 1, cam0, cam1);
+ w1_cam1 = rvu_read64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 1));
+ w1_cam0 = rvu_read64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 0));
+ npc_fill_entryword(entry, kw + 1, w1_cam0, w1_cam1);
+ trace_otx2_npc_cam(actindex, bank, w0_cam0, w0_cam1, w1_cam0, w1_cam1);
}
entry->action = rvu_read64(rvu, blkaddr,
@@ -625,18 +635,28 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
NPC_AF_MCAMEX_BANKX_CAMX_INTF(src, sbank, 1)) & 3;
*ena = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CFG(src, sbank)) & 1;
+ tx_intf = *intf;
+ if (is_npc_intf_tx(tx_intf))
+ tx_intf &= 0x1;
+ trace_otx2_npc_action(actindex, sbank, tx_intf, *ena,
+ entry->action, entry->vtag_action);
}
static int npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 src, u16 dest)
{
+ u64 cfg, sreg, dreg;
+ u16 orig_src = src, orig_dest = dest;
int dbank = npc_get_bank(mcam, dest);
int sbank = npc_get_bank(mcam, src);
- u64 cfg, sreg, dreg;
- int bank, i;
+ int bank, i, err;
- if (is_cn20k(rvu->pdev))
- return npc_cn20k_copy_mcam_entry(rvu, blkaddr, src, dest);
+ if (is_cn20k(rvu->pdev)) {
+ err = npc_cn20k_copy_mcam_entry(rvu, blkaddr, src, dest);
+ if (!err)
+ trace_otx2_npc_mcam_copy(orig_src, orig_dest);
+ return err;
+ }
src &= (mcam->banksize - 1);
dest &= (mcam->banksize - 1);
@@ -668,6 +688,7 @@ static int npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
NPC_AF_MCAMEX_BANKX_CFG(src, sbank));
rvu_write64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CFG(dest, dbank), cfg);
+ trace_otx2_npc_mcam_copy(orig_src, orig_dest);
return 0;
}
@@ -3198,6 +3219,7 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
rsp->free_count = -1;
mutex_unlock(&mcam->lock);
+ trace_otx2_npc_mcam_alloc_entries(pcifunc, req, rsp);
return 0;
not_cn20k:
@@ -3384,6 +3406,7 @@ static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
rsp->free_count = mcam->bmap_fcnt;
mutex_unlock(&mcam->lock);
+ trace_otx2_npc_mcam_alloc_entries(pcifunc, req, rsp);
return 0;
}
@@ -4043,7 +4066,7 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
struct npc_mcam_alloc_counter_req cntr_req;
struct npc_mcam_alloc_counter_rsp cntr_rsp;
- struct npc_mcam_alloc_entry_req entry_req;
+ struct npc_mcam_alloc_entry_req entry_req = { 0 };
struct npc_mcam_alloc_entry_rsp entry_rsp;
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 entry = NPC_MCAM_ENTRY_INVALID;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c
index 19e0d16b12f6..42797e7d13ba 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.c
@@ -13,3 +13,8 @@ EXPORT_TRACEPOINT_SYMBOL(otx2_msg_interrupt);
EXPORT_TRACEPOINT_SYMBOL(otx2_msg_process);
EXPORT_TRACEPOINT_SYMBOL(otx2_msg_status);
EXPORT_TRACEPOINT_SYMBOL(otx2_parse_dump);
+EXPORT_TRACEPOINT_SYMBOL(otx2_npc_mcam_alloc_entries);
+EXPORT_TRACEPOINT_SYMBOL(otx2_npc_mcam_copy);
+EXPORT_TRACEPOINT_SYMBOL(otx2_npc_enable_mcam_entry);
+EXPORT_TRACEPOINT_SYMBOL(otx2_npc_cam);
+EXPORT_TRACEPOINT_SYMBOL(otx2_npc_action);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h
index 4cd0fc4b0d20..ea1c5d7f1007 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h
@@ -159,6 +159,120 @@ TRACE_EVENT(otx2_parse_dump,
__entry->w3, __entry->w4, __entry->w5)
);
+TRACE_EVENT(otx2_npc_mcam_alloc_entries,
+ TP_PROTO(u16 pcifunc,
+ struct npc_mcam_alloc_entry_req *req,
+ struct npc_mcam_alloc_entry_rsp *rsp),
+ TP_ARGS(pcifunc, req, rsp),
+ TP_STRUCT__entry(__field(u16, pcifunc)
+ __field(u8, contig)
+ __field(u8, ref_prio)
+ __field(u16, ref_entry)
+ __field(u16, req_count)
+ __field(u8, kw_type)
+ __field(u8, virt)
+ __field(u16, start_mcam_idx)
+ __field(u16, rsp_count)
+ __field(u16, free_count)
+ ),
+ TP_fast_assign(__entry->pcifunc = pcifunc;
+ __entry->contig = req->contig;
+ __entry->ref_prio = req->ref_prio;
+ __entry->ref_entry = req->ref_entry;
+ __entry->req_count = req->count;
+ __entry->kw_type = req->kw_type;
+ __entry->virt = req->virt;
+ __entry->start_mcam_idx = req->contig ? rsp->entry :
+ (rsp->count ? rsp->entry_list[0] :
+ NPC_MCAM_ENTRY_INVALID);
+ __entry->rsp_count = rsp->count;
+ __entry->free_count = rsp->free_count;
+ ),
+ TP_printk("pcifunc:0x%x req_contig:%d req_ref_prio:%d req->ref_entry:%d req->req_count:%d req->kw_type:%d req->virt:%d rsp_start_mcam_idx:%d rsp_count:%d rsp_free_count:%d",
+ __entry->pcifunc, __entry->contig, __entry->ref_prio,
+ __entry->ref_entry, __entry->req_count, __entry->kw_type,
+ __entry->virt, __entry->start_mcam_idx, __entry->rsp_count,
+ __entry->free_count)
+);
+
+TRACE_EVENT(otx2_npc_mcam_copy,
+ TP_PROTO(u16 src, u16 dest),
+ TP_ARGS(src, dest),
+ TP_STRUCT__entry(__field(u16, src)
+ __field(u16, dest)
+ ),
+ TP_fast_assign(__entry->src = src;
+ __entry->dest = dest;
+ ),
+ TP_printk("src:%d dest:%d", __entry->src, __entry->dest)
+);
+
+TRACE_EVENT(otx2_npc_enable_mcam_entry,
+ TP_PROTO(u16 index, u8 enable),
+ TP_ARGS(index, enable),
+ TP_STRUCT__entry(__field(u16, mcam_index)
+ __field(u8, ena)
+ ),
+ TP_fast_assign(__entry->mcam_index = index;
+ __entry->ena = enable;
+ ),
+ TP_printk("mcam_index:%d enable:%d", __entry->mcam_index, __entry->ena)
+);
+
+TRACE_EVENT(otx2_npc_cam,
+ TP_PROTO(u16 index, u8 bank,
+ u64 w0_cam0,
+ u64 w0_cam1,
+ u64 w1_cam0,
+ u64 w1_cam1),
+ TP_ARGS(index, bank,
+ w0_cam0, w0_cam1,
+ w1_cam0, w1_cam1),
+ TP_STRUCT__entry(__field(u16, mcam_index)
+ __field(u8, bank)
+ __field(u64, w0_cam0)
+ __field(u64, w0_cam1)
+ __field(u64, w1_cam0)
+ __field(u64, w1_cam1)
+ ),
+ TP_fast_assign(__entry->mcam_index = index;
+ __entry->bank = bank;
+ __entry->w0_cam0 = w0_cam0;
+ __entry->w0_cam1 = w0_cam1;
+ __entry->w1_cam0 = w1_cam0;
+ __entry->w1_cam1 = w1_cam1;
+ ),
+ TP_printk("mcam_index:%d bank:%d w0_cam0:0x%llx w0_cam1:0x%llx w1_cam0:0x%llx w1_cam1:0x%llx",
+ __entry->mcam_index, __entry->bank, __entry->w0_cam0, __entry->w0_cam1,
+ __entry->w1_cam0, __entry->w1_cam1)
+);
+
+TRACE_EVENT(otx2_npc_action,
+ TP_PROTO(u16 index, u8 bank,
+ u8 tx_intf, u8 enable,
+ u64 act, u64 vtag_act),
+ TP_ARGS(index, bank,
+ tx_intf, enable,
+ act, vtag_act),
+ TP_STRUCT__entry(__field(u16, mcam_index)
+ __field(u8, bank)
+ __field(u8, tx_intf)
+ __field(u8, enable)
+ __field(u64, act)
+ __field(u64, vtag_act)
+ ),
+ TP_fast_assign(__entry->mcam_index = index;
+ __entry->bank = bank;
+ __entry->tx_intf = tx_intf;
+ __entry->enable = enable;
+ __entry->act = act;
+ __entry->vtag_act = vtag_act;
+ ),
+ TP_printk("mcam_index:%d bank:%d tx_intf:%d enable:%d action:0x%llx vtag_action:0x%llx",
+ __entry->mcam_index, __entry->bank, __entry->tx_intf,
+ __entry->enable, __entry->act, __entry->vtag_act)
+);
+
#endif /* __RVU_TRACE_H */
#undef TRACE_INCLUDE_PATH
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH v2 net-next] octeontx2-af: add tracepoints for NPC MCAM entry programming
2026-09-23 3:48 [PATCH v2 net-next] octeontx2-af: add tracepoints for NPC MCAM entry programming Ratheesh Kannoth
@ 2026-09-27 4:46 ` netdev-bot+sashiko
0 siblings, 0 replies; 2+ messages in thread
From: netdev-bot+sashiko @ 2026-09-27 4:46 UTC (permalink / raw)
To: rkannoth
Cc: linux-kernel, netdev, andrew+netdev, davem, edumazet, kuba,
pabeni, sgoutham, sumang
Thank you for your contribution! Sashiko AI review found 5 potential
issue(s) to consider.
Critical: 0 · High: 1 · Medium: 1 · Low: 3
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [High] In rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry()
(drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c), the patch…
- [Medium] The commit message says the events are emitted from 'the
legacy and CN20K NPC alloc, config, read, and shift paths'.
- [Low] The otx2_npc_cam event (rvu_trace.h) defines and prints its
payload as w0_cam0/w0_cam1/w1_cam0/w1_cam1 and has no word-offset…
- [Low] In the submitted patch, the 'v1 -> v2' changelog begins with a
'---' separator, and both Signed-off-by tags (Suman Ghosh, Ratheesh…
- [Low] On CN20K, npc_cn20k_ref_idx_alloc() replaces the physical indices
in the returned mcam_idx list with virtual indices ('Return vidx to…
--
octeontx2-af: add tracepoints for NPC MCAM entry programming
This commit adds five ftrace events to the octeontx2 AF driver:
otx2_npc_mcam_alloc_entries, otx2_npc_mcam_copy,
otx2_npc_enable_mcam_entry, otx2_npc_cam and otx2_npc_action. They are
emitted from the legacy and CN20K NPC MCAM alloc, config, read, enable
and copy paths. The commit also zero-initializes the
npc_mcam_alloc_entry_req used by the two alloc-and-write mailbox handlers.
> Add ftrace events for MCAM allocation, CAM keyword writes, action/tag
> programming, enable/disable, and entry copies. Emit them from the legacy
> and CN20K NPC alloc, config, read, and shift paths so mailbox-driven
> rule changes can be correlated with the programmed MCAM state.
[Severity: Medium]
Is the CN20K coverage described here complete?
The copy and enable events are emitted only from the generic wrappers
npc_copy_mcam_entry() and npc_enable_mcam_entry() in rvu_npc.c. The
cam/action read events come only from the legacy npc_read_mcam_entry().
Several CN20K paths call the raw helpers directly.
npc_defrag_move_vdx_to_free() in cn20k/npc.c:
if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, old_midx, false)) {
...
if (npc_cn20k_copy_mcam_entry(rvu, blkaddr, old_midx, new_midx)) {
...
if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, new_midx, true)) {
A defrag move therefore leaves no otx2_npc_mcam_copy or
otx2_npc_enable_mcam_entry record. The trace still shows the rule at
old_midx, but the hardware now holds it at new_midx.
npc_cn20k_config_mcam_entry() does its disable-before-update and its
final enable through npc_cn20k_enable_mcam_entry(). So it emits no
enable/disable events, unlike the legacy npc_config_mcam_entry().
npc_cn20k_dft_rules_free() disables default entries through
npc_cn20k_enable_mcam_entry() without a trace.
npc_cn20k_read_mcam_entry() is not instrumented at all. Its callers are
rvu_mbox_handler_npc_cn20k_mcam_read_entry(),
rvu_mbox_handler_npc_cn20k_read_base_steer_rule() and
npc_update_dmac_value().
The v2 changelog also says otx2_npc_mcam_copy was added "to cover MCAM
entry shifts". Should these CN20K paths be traced too, or should the
commit message be narrowed?
[Severity: Low]
This isn't a bug, but the applied commit has no Signed-off-by tags.
In the submitted patch, the "v1 -> v2" changelog begins with a "---"
separator. Both Signed-off-by lines (Suman Ghosh, Ratheesh Kannoth) come
after it, so git am drops them along with the changelog.
Could the Signed-off-by lines go above the first "---", with the version
changelog after it?
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> index 7c829b1da3e52..0b485728f3990 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c
[ ... ]
> @@ -1018,43 +1021,46 @@ static void npc_cn20k_config_kw_x2(struct rvu *rvu, struct npc_mcam *mcam,
[ ... ]
> - npc_cn20k_get_keyword(entry, kw + 3, &cam0, &cam1);
> + npc_cn20k_get_keyword(entry, kw + 3, &w3_cam0, &w3_cam1);
> rvu_write64(rvu, blkaddr,
> NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 1),
> - cam1);
> + w3_cam1);
> rvu_write64(rvu, blkaddr,
> NPC_AF_CN20K_MCAMEX_BANKX_CAMX_W3_EXT(index, bank, 0),
> - cam0);
> + w3_cam0);
> +
> + trace_otx2_npc_cam(actindex, bank, w0_cam0, w0_cam1, w1_cam0, w1_cam1);
> + trace_otx2_npc_cam(actindex, bank, w2_cam0, w2_cam1, w3_cam0, w3_cam1);
[Severity: Low]
The otx2_npc_cam event labels its payload as w0_cam0/w0_cam1/w1_cam0/
w1_cam1 and has no word-offset field. Won't the second call here print
the W2/W3 CAM values under the "w0_cam0 ... w1_cam1" labels, with the
same mcam_index and bank as the first record?
For X4 entries, npc_cn20k_config_kw_x4() emits four of these records per
entry. The only way to tell the W0/W1 records from the W2/W3 records is
emission order.
Would a word index field, or a separate event for W2/W3, make these
records unambiguous?
[ ... ]
> @@ -1434,7 +1445,7 @@ int rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry(struct rvu *rvu,
> {
> struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
> struct npc_mcam_free_entry_req free_req = { 0 };
> - struct npc_mcam_alloc_entry_req entry_req;
> + struct npc_mcam_alloc_entry_req entry_req = { 0 };
[Severity: High]
With entry_req now zeroed, can NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY ever
succeed on CN20K?
The handler sets hdr.pcifunc, contig, ref_prio, ref_entry, count and
virt, but never entry_req.kw_type. So kw_type is always 0, which is
NPC_MCAM_KEY_X1 / NPC_MCAM_KEY_DYN.
rvu_mbox_handler_npc_mcam_alloc_entry() passes req through unchanged,
and npc_mcam_alloc_entries() rejects it on CN20K:
rvu_mbox_handler_npc_cn20k_mcam_alloc_and_write_entry()
rvu_mbox_handler_npc_mcam_alloc_entry()
npc_mcam_alloc_entries()
/* Only x2 or x4 key types are accepted */
if (req->kw_type != NPC_MCAM_KEY_X2 && req->kw_type != NPC_MCAM_KEY_X4)
return NPC_MCAM_INVALID_REQ;
Before this patch, kw_type was uninitialized stack, so the outcome
depended on whatever happened to be there. Now every request fails with
NPC_MCAM_INVALID_REQ before any entry is allocated or programmed.
The missing kw_type assignment is older than this patch. However, the
v2 change to zero the struct is what makes the failure deterministic.
Should entry_req.kw_type be set here instead, for example from
req->req_kw_type or from the profile key type?
The legacy rvu_mbox_handler_npc_mcam_alloc_and_write_entry() in
rvu_npc.c got the same "= { 0 }" change and also never sets kw_type. It
would fail the same way if reached on CN20K silicon.
[ ... ]
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h
> index 4cd0fc4b0d203..ea1c5d7f10076 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_trace.h
> @@ -159,6 +159,120 @@ TRACE_EVENT(otx2_parse_dump,
> __entry->w3, __entry->w4, __entry->w5)
> );
>
> +TRACE_EVENT(otx2_npc_mcam_alloc_entries,
[ ... ]
> + TP_fast_assign(__entry->pcifunc = pcifunc;
> + __entry->contig = req->contig;
> + __entry->ref_prio = req->ref_prio;
> + __entry->ref_entry = req->ref_entry;
> + __entry->req_count = req->count;
> + __entry->kw_type = req->kw_type;
> + __entry->virt = req->virt;
> + __entry->start_mcam_idx = req->contig ? rsp->entry :
> + (rsp->count ? rsp->entry_list[0] :
> + NPC_MCAM_ENTRY_INVALID);
[Severity: Low]
On CN20K, can rsp->entry_list[0] be a virtual index here rather than a
physical MCAM index?
npc_cn20k_ref_idx_alloc() returns vidx values when defrag_candidate
(!ref_valid && !contig && virt) is true:
/* Return vidx to caller */
mcam_idx[i] = vidx;
npc_mcam_alloc_entries() converts these with npc_cn20k_vidx2idx() for
its own bookkeeping, but it passes the unconverted rsp to
trace_otx2_npc_mcam_alloc_entries(). In that case rsp_start_mcam_idx
holds a vidx.
Meanwhile otx2_npc_cam, otx2_npc_action, otx2_npc_mcam_copy and
otx2_npc_enable_mcam_entry all record physical indices. No event records
the vidx to physical mapping.
Could the event record the physical index, or both, so the alloc record
can be matched to the later programming records?
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260923034858.1764461-1-rkannoth%40marvell.com
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-27 4:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 3:48 [PATCH v2 net-next] octeontx2-af: add tracepoints for NPC MCAM entry programming Ratheesh Kannoth
2026-09-27 4:46 ` netdev-bot+sashiko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®