Merge branch 'knobs-for-npc-default-rule-counters'

Linu Cherian says:

====================
Knobs for NPC default rule counters

Patch 1 introduce _rvu_mcam_remove/add_counter_from/to_rule
by refactoring existing code

Patch 2 adds a devlink param to enable/disable counters for default
rules. Once enabled, counters can

Patch 3 adds documentation for devlink params

v4: https://lore.kernel.org/20241029035739.1981839-1-lcherian@marvell.com
====================

Link: https://patch.msgid.link/20241105125620.2114301-1-lcherian@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2024-11-11 14:16:00 -08:00
5 changed files with 190 additions and 39 deletions

View File

@@ -40,6 +40,27 @@ The ``octeontx2 AF`` driver implements the following driver-specific parameters.
- runtime
- Use to set the quantum which hardware uses for scheduling among transmit queues.
Hardware uses weighted DWRR algorithm to schedule among all transmit queues.
* - ``npc_mcam_high_zone_percent``
- u8
- runtime
- Use to set the number of high priority zone entries in NPC MCAM that can be allocated
by a user, out of the three priority zone categories high, mid and low.
* - ``npc_def_rule_cntr``
- bool
- runtime
- Use to enable or disable hit counters for the default rules in NPC MCAM.
Its not guaranteed that counters gets enabled and mapped to all the default rules,
since the counters are scarce and driver follows a best effort approach.
The default rule serves as the primary packet steering rule for a specific PF or VF,
based on its DMAC address which is installed by AF driver as part of its initialization.
Sample command to read hit counters for default rule from debugfs is as follows,
cat /sys/kernel/debug/cn10k/npc/mcam_rules
* - ``nix_maxlf``
- u16
- runtime
- Use to set the maximum number of LFs in NIX hardware block. This would be useful
to increase the availability of default resources allocated to enabled LFs like
MCAM entries for example.
The ``octeontx2 PF`` driver implements the following driver-specific parameters.

View File

@@ -525,6 +525,7 @@ struct rvu {
struct mutex alias_lock; /* Serialize bar2 alias access */
int vfs; /* Number of VFs attached to RVU */
u16 vf_devid; /* VF devices id */
bool def_rule_cntr_en;
int nix_blkaddr[MAX_NIX_BLKS];
/* Mbox */
@@ -960,7 +961,11 @@ void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
int group, int alg_idx, int mcam_index);
void __rvu_mcam_remove_counter_from_rule(struct rvu *rvu, u16 pcifunc,
struct rvu_npc_mcam_rule *rule);
void __rvu_mcam_add_counter_to_rule(struct rvu *rvu, u16 pcifunc,
struct rvu_npc_mcam_rule *rule,
struct npc_install_flow_rsp *rsp);
void rvu_npc_get_mcam_entry_alloc_info(struct rvu *rvu, u16 pcifunc,
int blkaddr, int *alloc_cnt,
int *enable_cnt);
@@ -985,6 +990,7 @@ void npc_set_mcam_action(struct rvu *rvu, struct npc_mcam *mcam,
void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 src, struct mcam_entry *entry,
u8 *intf, u8 *ena);
int npc_config_cntr_default_entries(struct rvu *rvu, bool enable);
bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc);
bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature);
u32 rvu_cgx_get_fifolen(struct rvu *rvu);

View File

@@ -1238,6 +1238,7 @@ enum rvu_af_dl_param_id {
RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
RVU_AF_DEVLINK_PARAM_ID_NPC_DEF_RULE_CNTR_ENABLE,
RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
};
@@ -1358,6 +1359,32 @@ static int rvu_af_dl_npc_mcam_high_zone_percent_validate(struct devlink *devlink
return 0;
}
static int rvu_af_dl_npc_def_rule_cntr_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.vbool = rvu->def_rule_cntr_en;
return 0;
}
static int rvu_af_dl_npc_def_rule_cntr_set(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx,
struct netlink_ext_ack *extack)
{
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;
int err;
err = npc_config_cntr_default_entries(rvu, ctx->val.vbool);
if (!err)
rvu->def_rule_cntr_en = ctx->val.vbool;
return err;
}
static int rvu_af_dl_nix_maxlf_get(struct devlink *devlink, u32 id,
struct devlink_param_gset_ctx *ctx)
{
@@ -1444,6 +1471,11 @@ static const struct devlink_param rvu_af_dl_params[] = {
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_NPC_DEF_RULE_CNTR_ENABLE,
"npc_def_rule_cntr", DEVLINK_PARAM_TYPE_BOOL,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
rvu_af_dl_npc_def_rule_cntr_get,
rvu_af_dl_npc_def_rule_cntr_set, NULL),
DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
"nix_maxlf", DEVLINK_PARAM_TYPE_U16,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),

View File

@@ -2691,6 +2691,49 @@ void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx)
npc_mcam_set_bit(mcam, entry_idx);
}
int npc_config_cntr_default_entries(struct rvu *rvu, bool enable)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
struct npc_install_flow_rsp rsp;
struct rvu_npc_mcam_rule *rule;
int blkaddr;
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
if (blkaddr < 0)
return -EINVAL;
mutex_lock(&mcam->lock);
list_for_each_entry(rule, &mcam->mcam_rules, list) {
if (!is_mcam_entry_enabled(rvu, mcam, blkaddr, rule->entry))
continue;
if (!rule->default_rule)
continue;
if (enable && !rule->has_cntr) { /* Alloc and map new counter */
__rvu_mcam_add_counter_to_rule(rvu, rule->owner,
rule, &rsp);
if (rsp.counter < 0) {
dev_err(rvu->dev,
"%s: Failed to allocate cntr for default rule (err=%d)\n",
__func__, rsp.counter);
break;
}
npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr,
rule->entry, rsp.counter);
/* Reset counter before use */
rvu_write64(rvu, blkaddr,
NPC_AF_MATCH_STATX(rule->cntr), 0x0);
}
/* Free and unmap counter */
if (!enable && rule->has_cntr)
__rvu_mcam_remove_counter_from_rule(rvu, rule->owner,
rule);
}
mutex_unlock(&mcam->lock);
return 0;
}
int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu,
struct npc_mcam_alloc_entry_req *req,
struct npc_mcam_alloc_entry_rsp *rsp)
@@ -2975,9 +3018,9 @@ int rvu_mbox_handler_npc_mcam_shift_entry(struct rvu *rvu,
return rc;
}
int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu,
struct npc_mcam_alloc_counter_req *req,
struct npc_mcam_alloc_counter_rsp *rsp)
static int __npc_mcam_alloc_counter(struct rvu *rvu,
struct npc_mcam_alloc_counter_req *req,
struct npc_mcam_alloc_counter_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 pcifunc = req->hdr.pcifunc;
@@ -2998,11 +3041,9 @@ int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu,
if (!req->contig && req->count > NPC_MAX_NONCONTIG_COUNTERS)
return NPC_MCAM_INVALID_REQ;
mutex_lock(&mcam->lock);
/* Check if unused counters are available or not */
if (!rvu_rsrc_free_count(&mcam->counters)) {
mutex_unlock(&mcam->lock);
return NPC_MCAM_ALLOC_FAILED;
}
@@ -3035,12 +3076,27 @@ int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu,
}
}
mutex_unlock(&mcam->lock);
return 0;
}
int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,
struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp)
int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu,
struct npc_mcam_alloc_counter_req *req,
struct npc_mcam_alloc_counter_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int err;
mutex_lock(&mcam->lock);
err = __npc_mcam_alloc_counter(rvu, req, rsp);
mutex_unlock(&mcam->lock);
return err;
}
static int __npc_mcam_free_counter(struct rvu *rvu,
struct npc_mcam_oper_counter_req *req,
struct msg_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
u16 index, entry = 0;
@@ -3050,10 +3106,8 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,
if (blkaddr < 0)
return NPC_MCAM_INVALID_REQ;
mutex_lock(&mcam->lock);
err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
if (err) {
mutex_unlock(&mcam->lock);
return err;
}
@@ -3077,10 +3131,66 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,
index, req->cntr);
}
mutex_unlock(&mcam->lock);
return 0;
}
int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,
struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
int err;
mutex_lock(&mcam->lock);
err = __npc_mcam_free_counter(rvu, req, rsp);
mutex_unlock(&mcam->lock);
return err;
}
void __rvu_mcam_remove_counter_from_rule(struct rvu *rvu, u16 pcifunc,
struct rvu_npc_mcam_rule *rule)
{
struct npc_mcam_oper_counter_req free_req = { 0 };
struct msg_rsp free_rsp;
if (!rule->has_cntr)
return;
free_req.hdr.pcifunc = pcifunc;
free_req.cntr = rule->cntr;
__npc_mcam_free_counter(rvu, &free_req, &free_rsp);
rule->has_cntr = false;
}
void __rvu_mcam_add_counter_to_rule(struct rvu *rvu, u16 pcifunc,
struct rvu_npc_mcam_rule *rule,
struct npc_install_flow_rsp *rsp)
{
struct npc_mcam_alloc_counter_req cntr_req = { 0 };
struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 };
int err;
cntr_req.hdr.pcifunc = pcifunc;
cntr_req.contig = true;
cntr_req.count = 1;
/* we try to allocate a counter to track the stats of this
* rule. If counter could not be allocated then proceed
* without counter because counters are limited than entries.
*/
err = __npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp);
if (!err && cntr_rsp.count) {
rule->cntr = cntr_rsp.cntr;
rule->has_cntr = true;
rsp->counter = rule->cntr;
} else {
rsp->counter = err;
}
}
int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
struct npc_mcam_unmap_counter_req *req, struct msg_rsp *rsp)
{

View File

@@ -1081,44 +1081,26 @@ static void rvu_mcam_add_rule(struct npc_mcam *mcam,
static void rvu_mcam_remove_counter_from_rule(struct rvu *rvu, u16 pcifunc,
struct rvu_npc_mcam_rule *rule)
{
struct npc_mcam_oper_counter_req free_req = { 0 };
struct msg_rsp free_rsp;
struct npc_mcam *mcam = &rvu->hw->mcam;
if (!rule->has_cntr)
return;
mutex_lock(&mcam->lock);
free_req.hdr.pcifunc = pcifunc;
free_req.cntr = rule->cntr;
__rvu_mcam_remove_counter_from_rule(rvu, pcifunc, rule);
rvu_mbox_handler_npc_mcam_free_counter(rvu, &free_req, &free_rsp);
rule->has_cntr = false;
mutex_unlock(&mcam->lock);
}
static void rvu_mcam_add_counter_to_rule(struct rvu *rvu, u16 pcifunc,
struct rvu_npc_mcam_rule *rule,
struct npc_install_flow_rsp *rsp)
{
struct npc_mcam_alloc_counter_req cntr_req = { 0 };
struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 };
int err;
struct npc_mcam *mcam = &rvu->hw->mcam;
cntr_req.hdr.pcifunc = pcifunc;
cntr_req.contig = true;
cntr_req.count = 1;
mutex_lock(&mcam->lock);
/* we try to allocate a counter to track the stats of this
* rule. If counter could not be allocated then proceed
* without counter because counters are limited than entries.
*/
err = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req,
&cntr_rsp);
if (!err && cntr_rsp.count) {
rule->cntr = cntr_rsp.cntr;
rule->has_cntr = true;
rsp->counter = rule->cntr;
} else {
rsp->counter = err;
}
__rvu_mcam_add_counter_to_rule(rvu, pcifunc, rule, rsp);
mutex_unlock(&mcam->lock);
}
static int npc_mcast_update_action_index(struct rvu *rvu, struct npc_install_flow_req *req,