@@ -65,15 +65,24 @@ sfc_mae_assign_entity_mport(struct sfc_adapter *sa,
static int
sfc_mae_counter_registry_init(struct sfc_mae_counter_registry *registry,
- uint32_t nb_counters_max)
+ uint32_t nb_action_counters_max)
{
- return sfc_mae_counters_init(®istry->counters, nb_counters_max);
+ int ret;
+
+ ret = sfc_mae_counters_init(®istry->action_counters,
+ nb_action_counters_max);
+ if (ret != 0)
+ return ret;
+
+ registry->action_counters.type = EFX_COUNTER_TYPE_ACTION;
+
+ return 0;
}
static void
sfc_mae_counter_registry_fini(struct sfc_mae_counter_registry *registry)
{
- sfc_mae_counters_fini(®istry->counters);
+ sfc_mae_counters_fini(®istry->action_counters);
}
struct rte_flow *
@@ -153,10 +162,10 @@ sfc_mae_attach(struct sfc_adapter *sa)
sfc_log_init(sa, "init MAE counter record registry");
rc = sfc_mae_counter_registry_init(&mae->counter_registry,
- limits.eml_max_n_counters);
+ limits.eml_max_n_action_counters);
if (rc != 0) {
- sfc_err(sa, "failed to init MAE counters registry for %u entries: %s",
- limits.eml_max_n_counters, rte_strerror(rc));
+ sfc_err(sa, "failed to init record registry for %u AR counters: %s",
+ limits.eml_max_n_action_counters, rte_strerror(rc));
goto fail_counter_registry_init;
}
}
@@ -833,6 +842,9 @@ sfc_mae_counter_add(struct sfc_adapter *sa,
if (counter_tmp != NULL) {
counter->rte_id_valid = counter_tmp->rte_id_valid;
counter->rte_id = counter_tmp->rte_id;
+ counter->type = counter_tmp->type;
+ } else {
+ counter->type = EFX_COUNTER_TYPE_ACTION;
}
counter->fw_rsrc.counter_id.id = EFX_MAE_RSRC_ID_INVALID;
@@ -864,8 +876,8 @@ sfc_mae_counter_del(struct sfc_adapter *sa, struct sfc_mae_counter *counter)
if (counter->fw_rsrc.counter_id.id != EFX_MAE_RSRC_ID_INVALID ||
counter->fw_rsrc.refcnt != 0) {
- sfc_err(sa, "deleting counter=%p abandons its FW resource: COUNTER_ID=0x%08x, refcnt=%u",
- counter, counter->fw_rsrc.counter_id.id,
+ sfc_err(sa, "deleting counter=%p abandons its FW resource: COUNTER_ID=0x%x-#%u, refcnt=%u",
+ counter, counter->type, counter->fw_rsrc.counter_id.id,
counter->fw_rsrc.refcnt);
}
@@ -916,8 +928,8 @@ sfc_mae_counter_enable(struct sfc_adapter *sa, struct sfc_mae_counter *counter,
}
if (fw_rsrc->refcnt == 0) {
- sfc_dbg(sa, "enabled counter=%p: COUNTER_ID=0x%08x",
- counter, fw_rsrc->counter_id.id);
+ sfc_dbg(sa, "enabled counter=%p: COUNTER_ID=0x%x-#%u",
+ counter, counter->type, fw_rsrc->counter_id.id);
}
++(fw_rsrc->refcnt);
@@ -940,8 +952,8 @@ sfc_mae_counter_disable(struct sfc_adapter *sa, struct sfc_mae_counter *counter)
if (fw_rsrc->counter_id.id == EFX_MAE_RSRC_ID_INVALID ||
fw_rsrc->refcnt == 0) {
- sfc_err(sa, "failed to disable counter=%p: already disabled; COUNTER_ID=0x%08x, refcnt=%u",
- counter, fw_rsrc->counter_id.id, fw_rsrc->refcnt);
+ sfc_err(sa, "failed to disable counter=%p: already disabled; COUNTER_ID=0x%x-#%u, refcnt=%u",
+ counter, counter->type, fw_rsrc->counter_id.id, fw_rsrc->refcnt);
return;
}
@@ -950,11 +962,11 @@ sfc_mae_counter_disable(struct sfc_adapter *sa, struct sfc_mae_counter *counter)
rc = sfc_mae_counter_fw_rsrc_disable(sa, counter);
if (rc == 0) {
- sfc_dbg(sa, "disabled counter=%p with COUNTER_ID=0x%08x",
- counter, counter_id);
+ sfc_dbg(sa, "disabled counter=%p with COUNTER_ID=0x%x-#%u",
+ counter, counter->type, counter_id);
} else {
- sfc_err(sa, "failed to disable counter=%p with COUNTER_ID=0x%08x: %s",
- counter, counter_id, strerror(rc));
+ sfc_err(sa, "failed to disable counter=%p with COUNTER_ID=0x%x-#%u: %s",
+ counter, counter->type, counter_id, strerror(rc));
}
fw_rsrc->counter_id.id = EFX_MAE_RSRC_ID_INVALID;
@@ -3952,6 +3964,7 @@ sfc_mae_rule_parse_action_mark(struct sfc_adapter *sa,
static int
sfc_mae_rule_parse_action_count(struct sfc_adapter *sa,
const struct rte_flow_action_count *conf,
+ efx_counter_type_t mae_counter_type,
struct sfc_mae_counter **counterp,
efx_mae_actions_t *spec)
{
@@ -3991,6 +4004,8 @@ sfc_mae_rule_parse_action_count(struct sfc_adapter *sa,
counter_tmp.rte_id = conf->id;
}
+ counter_tmp.type = mae_counter_type;
+
return sfc_mae_counter_add(sa, &counter_tmp, counterp);
return 0;
@@ -4215,6 +4230,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
{
struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae;
const struct sfc_mae_outer_rule *outer_rule = spec_mae->outer_rule;
+ efx_counter_type_t mae_counter_type = EFX_COUNTER_TYPE_ACTION;
const uint64_t rx_metadata = sa->negotiated_rx_metadata;
struct sfc_mae_counter **counterp = &ctx->counter;
efx_mae_actions_t *spec = ctx->spec;
@@ -4307,6 +4323,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_COUNT,
bundle->actions_mask);
rc = sfc_mae_rule_parse_action_count(sa, action->conf,
+ mae_counter_type,
counterp, spec_ptr);
break;
case RTE_FLOW_ACTION_TYPE_INDIRECT:
@@ -4885,8 +4902,7 @@ sfc_mae_query_counter(struct sfc_adapter *sa,
if (conf == NULL ||
(counter->rte_id_valid && conf->id == counter->rte_id)) {
- rc = sfc_mae_counter_get(&sa->mae.counter_registry.counters,
- counter, data);
+ rc = sfc_mae_counter_get(sa, counter, data);
if (rc != 0) {
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, action,
@@ -5000,6 +5016,7 @@ sfc_mae_indir_action_create(struct sfc_adapter *sa,
switch (action->type) {
case RTE_FLOW_ACTION_TYPE_COUNT:
ret = sfc_mae_rule_parse_action_count(sa, action->conf,
+ EFX_COUNTER_TYPE_ACTION,
&handle->counter, NULL);
if (ret == 0)
handle->counter->indirect = true;
@@ -5063,8 +5080,7 @@ sfc_mae_indir_action_query(struct sfc_adapter *sa,
if (handle->counter->fw_rsrc.refcnt == 0)
goto fail_not_in_use;
- ret = sfc_mae_counter_get(&sa->mae.counter_registry.counters,
- handle->counter, data);
+ ret = sfc_mae_counter_get(sa, handle->counter, data);
if (ret != 0)
goto fail_counter_get;
@@ -86,6 +86,7 @@ struct sfc_mae_counter {
struct sfc_mae_fw_rsrc fw_rsrc;
bool indirect;
+ efx_counter_type_t type;
};
TAILQ_HEAD(sfc_mae_counters, sfc_mae_counter);
@@ -157,6 +158,8 @@ struct sfc_mae_counter_records {
struct sfc_mae_counters_xstats xstats;
/** Count of all MAE counters */
unsigned int n_mae_counters;
+ /** Counter type, for logging */
+ efx_counter_type_t type;
};
/** Options for MAE counter polling mode */
@@ -168,8 +171,8 @@ enum sfc_mae_counter_polling_mode {
struct sfc_mae_counter_registry {
/* Common counter information */
- /** Counters collection */
- struct sfc_mae_counter_records counters;
+ /** Action rule counter record collection */
+ struct sfc_mae_counter_records action_counters;
/* Information used by counter update service */
/** Callback to get packets from RxQ */
@@ -80,19 +80,28 @@ sfc_mae_counter_fw_rsrc_enable(struct sfc_adapter *sa,
struct sfc_mae_counter *counterp)
{
struct sfc_mae_counter_registry *reg = &sa->mae.counter_registry;
- struct sfc_mae_counter_records *counters = ®->counters;
+ struct sfc_mae_counter_records *counters;
struct sfc_mae_counter_record *p;
efx_counter_t mae_counter;
uint32_t generation_count;
uint32_t unused;
int rc;
+ switch (counterp->type) {
+ case EFX_COUNTER_TYPE_ACTION:
+ counters = ®->action_counters;
+ break;
+ default:
+ rc = EINVAL;
+ goto fail_counter_type_check;
+ }
+
/*
* The actual count of counters allocated is ignored since a failure
* to allocate a single counter is indicated by non-zero return code.
*/
- rc = efx_mae_counters_alloc(sa->nic, 1, &unused, &mae_counter,
- &generation_count);
+ rc = efx_mae_counters_alloc_type(sa->nic, counterp->type, 1, &unused,
+ &mae_counter, &generation_count);
if (rc != 0) {
sfc_err(sa, "failed to alloc MAE counter: %s",
rte_strerror(rc));
@@ -132,16 +141,18 @@ sfc_mae_counter_fw_rsrc_enable(struct sfc_adapter *sa,
*/
__atomic_store_n(&p->inuse, true, __ATOMIC_RELEASE);
- sfc_info(sa, "enabled MAE counter #%u with reset pkts=%" PRIu64
- " bytes=%" PRIu64, mae_counter.id,
+ sfc_info(sa, "enabled MAE counter 0x%x-#%u with reset pkts=%" PRIu64
+ " bytes=%" PRIu64, counterp->type, mae_counter.id,
p->reset.pkts, p->reset.bytes);
return 0;
fail_counter_id_range:
- (void)efx_mae_counters_free(sa->nic, 1, &unused, &mae_counter, NULL);
+ (void)efx_mae_counters_free_type(sa->nic, counterp->type, 1, &unused,
+ &mae_counter, NULL);
fail_mae_counter_alloc:
+fail_counter_type_check:
sfc_log_init(sa, "failed: %s", rte_strerror(rc));
return rc;
}
@@ -151,12 +162,20 @@ sfc_mae_counter_fw_rsrc_disable(struct sfc_adapter *sa,
struct sfc_mae_counter *counter)
{
struct sfc_mae_counter_registry *reg = &sa->mae.counter_registry;
- struct sfc_mae_counter_records *counters = ®->counters;
efx_counter_t *mae_counter = &counter->fw_rsrc.counter_id;
+ struct sfc_mae_counter_records *counters;
struct sfc_mae_counter_record *p;
uint32_t unused;
int rc;
+ switch (counter->type) {
+ case EFX_COUNTER_TYPE_ACTION:
+ counters = ®->action_counters;
+ break;
+ default:
+ return EINVAL;
+ }
+
SFC_ASSERT(mae_counter->id < counters->n_mae_counters);
/*
* The flag is set at the very end of add operation and reset
@@ -166,13 +185,14 @@ sfc_mae_counter_fw_rsrc_disable(struct sfc_adapter *sa,
p = &counters->mae_counters[mae_counter->id];
__atomic_store_n(&p->inuse, false, __ATOMIC_RELEASE);
- rc = efx_mae_counters_free(sa->nic, 1, &unused, mae_counter, NULL);
+ rc = efx_mae_counters_free_type(sa->nic, counter->type, 1, &unused,
+ mae_counter, NULL);
if (rc != 0)
- sfc_err(sa, "failed to free MAE counter %u: %s",
- mae_counter->id, rte_strerror(rc));
+ sfc_err(sa, "failed to free MAE counter 0x%x-#%u: %s",
+ counter->type, mae_counter->id, rte_strerror(rc));
- sfc_info(sa, "disabled MAE counter #%u with reset pkts=%" PRIu64
- " bytes=%" PRIu64, mae_counter->id,
+ sfc_info(sa, "disabled MAE counter 0x%x-#%u with reset pkts=%" PRIu64
+ " bytes=%" PRIu64, counter->type, mae_counter->id,
p->reset.pkts, p->reset.bytes);
/*
@@ -243,8 +263,8 @@ sfc_mae_counter_increment(struct sfc_adapter *sa,
__ATOMIC_RELAXED);
}
- sfc_info(sa, "update MAE counter #%u: pkts+%" PRIu64 "=%" PRIu64
- ", bytes+%" PRIu64 "=%" PRIu64, mae_counter_id,
+ sfc_info(sa, "update MAE counter 0x%x-#%u: pkts+%" PRIu64 "=%" PRIu64
+ ", bytes+%" PRIu64 "=%" PRIu64, counters->type, mae_counter_id,
pkts, cnt_val.pkts, bytes, cnt_val.bytes);
}
@@ -253,6 +273,7 @@ sfc_mae_parse_counter_packet(struct sfc_adapter *sa,
struct sfc_mae_counter_registry *counter_registry,
const struct rte_mbuf *m)
{
+ struct sfc_mae_counter_records *counters;
uint32_t generation_count;
const efx_xword_t *hdr;
const efx_oword_t *counters_data;
@@ -293,7 +314,12 @@ sfc_mae_parse_counter_packet(struct sfc_adapter *sa,
}
id = EFX_XWORD_FIELD(*hdr, ERF_SC_PACKETISER_HEADER_IDENTIFIER);
- if (unlikely(id != ERF_SC_PACKETISER_HEADER_IDENTIFIER_AR)) {
+
+ switch (id) {
+ case ERF_SC_PACKETISER_HEADER_IDENTIFIER_AR:
+ counters = &counter_registry->action_counters;
+ break;
+ default:
sfc_err(sa, "unexpected MAE counters source identifier %u", id);
return;
}
@@ -367,7 +393,7 @@ sfc_mae_parse_counter_packet(struct sfc_adapter *sa,
EFX_OWORD_FIELD32(counters_data[i],
ERF_SC_PACKETISER_PAYLOAD_BYTE_COUNT_HI);
sfc_mae_counter_increment(sa,
- &counter_registry->counters,
+ counters,
EFX_OWORD_FIELD32(counters_data[i],
ERF_SC_PACKETISER_PAYLOAD_COUNTER_INDEX),
generation_count,
@@ -941,14 +967,25 @@ sfc_mae_counter_start(struct sfc_adapter *sa)
}
int
-sfc_mae_counter_get(struct sfc_mae_counter_records *counters,
+sfc_mae_counter_get(struct sfc_adapter *sa,
const struct sfc_mae_counter *counter,
struct rte_flow_query_count *data)
{
struct sfc_ft_ctx *ft_ctx = counter->ft_ctx;
+ struct sfc_mae_counter_records *counters;
uint64_t non_reset_tunnel_hit_counter;
struct sfc_mae_counter_record *p;
union sfc_pkts_bytes value;
+ bool need_byte_count;
+
+ switch (counter->type) {
+ case EFX_COUNTER_TYPE_ACTION:
+ counters = &sa->mae.counter_registry.action_counters;
+ need_byte_count = true;
+ break;
+ default:
+ return EINVAL;
+ }
SFC_ASSERT(counter->fw_rsrc.counter_id.id < counters->n_mae_counters);
p = &counters->mae_counters[counter->fw_rsrc.counter_id.id];
@@ -968,7 +1005,7 @@ sfc_mae_counter_get(struct sfc_mae_counter_records *counters,
data->hits += ft_ctx->switch_hit_counter;
non_reset_tunnel_hit_counter = data->hits;
data->hits -= ft_ctx->reset_tunnel_hit_counter;
- } else {
+ } else if (need_byte_count) {
data->bytes_set = 1;
data->bytes = value.bytes - p->reset.bytes;
}
@@ -979,7 +1016,9 @@ sfc_mae_counter_get(struct sfc_mae_counter_records *counters,
non_reset_tunnel_hit_counter;
} else {
p->reset.pkts = value.pkts;
- p->reset.bytes = value.bytes;
+
+ if (need_byte_count)
+ p->reset.bytes = value.bytes;
}
}
@@ -45,7 +45,7 @@ int sfc_mae_counter_fw_rsrc_enable(struct sfc_adapter *sa,
struct sfc_mae_counter *counterp);
int sfc_mae_counter_fw_rsrc_disable(struct sfc_adapter *sa,
struct sfc_mae_counter *counter);
-int sfc_mae_counter_get(struct sfc_mae_counter_records *counters,
+int sfc_mae_counter_get(struct sfc_adapter *sa,
const struct sfc_mae_counter *counter,
struct rte_flow_query_count *data);