@@ -205,6 +205,7 @@ sfc_mae_attach(struct sfc_adapter *sa)
TAILQ_INIT(&mae->outer_rules);
TAILQ_INIT(&mae->mac_addrs);
TAILQ_INIT(&mae->encap_headers);
+ TAILQ_INIT(&mae->counters);
TAILQ_INIT(&mae->action_sets);
TAILQ_INIT(&mae->action_rules);
@@ -816,72 +817,155 @@ sfc_mae_encap_header_disable(struct sfc_adapter *sa,
}
static int
-sfc_mae_counters_enable(struct sfc_adapter *sa,
- struct sfc_mae_counter *counters,
- unsigned int n_counters,
- efx_mae_actions_t *action_set_spec)
+sfc_mae_counter_add(struct sfc_adapter *sa,
+ const struct sfc_mae_counter *counter_tmp,
+ struct sfc_mae_counter **counterp)
{
- int rc;
+ struct sfc_mae_counter *counter;
+ struct sfc_mae *mae = &sa->mae;
- sfc_log_init(sa, "entry");
+ SFC_ASSERT(sfc_adapter_is_locked(sa));
- if (n_counters == 0) {
- sfc_log_init(sa, "no counters - skip");
- return 0;
+ counter = rte_zmalloc("sfc_mae_counter", sizeof(*counter), 0);
+ if (counter == NULL)
+ return ENOMEM;
+
+ if (counter_tmp != NULL) {
+ counter->rte_id_valid = counter_tmp->rte_id_valid;
+ counter->rte_id = counter_tmp->rte_id;
}
- SFC_ASSERT(sfc_adapter_is_locked(sa));
- SFC_ASSERT(n_counters == 1);
+ counter->fw_rsrc.counter_id.id = EFX_MAE_RSRC_ID_INVALID;
+ counter->refcnt = 1;
- rc = sfc_mae_counter_fw_rsrc_enable(sa, &counters[0]);
- if (rc != 0) {
- sfc_err(sa, "failed to enable MAE counter %u: %s",
- counters[0].mae_id.id, rte_strerror(rc));
- goto fail_counter_add;
- }
+ TAILQ_INSERT_TAIL(&mae->counters, counter, entries);
+ *counterp = counter;
- rc = efx_mae_action_set_fill_in_counter_id(action_set_spec,
- &counters[0].mae_id);
- if (rc != 0) {
- sfc_err(sa, "failed to fill in MAE counter %u in action set: %s",
- counters[0].mae_id.id, rte_strerror(rc));
- goto fail_fill_in_id;
- }
+ sfc_dbg(sa, "added counter=%p", counter);
return 0;
+}
+
+static void
+sfc_mae_counter_del(struct sfc_adapter *sa, struct sfc_mae_counter *counter)
+{
+ struct sfc_mae *mae = &sa->mae;
-fail_fill_in_id:
- (void)sfc_mae_counter_fw_rsrc_disable(sa, &counters[0]);
+ if (counter == NULL)
+ return;
-fail_counter_add:
- sfc_log_init(sa, "failed: %s", rte_strerror(rc));
- return rc;
+ SFC_ASSERT(sfc_adapter_is_locked(sa));
+ SFC_ASSERT(counter->refcnt != 0);
+
+ --(counter->refcnt);
+
+ if (counter->refcnt != 0)
+ return;
+
+ 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,
+ counter->fw_rsrc.refcnt);
+ }
+
+ TAILQ_REMOVE(&mae->counters, counter, entries);
+ rte_free(counter);
+
+ sfc_dbg(sa, "deleted counter=%p", counter);
}
static int
-sfc_mae_counters_disable(struct sfc_adapter *sa,
- struct sfc_mae_counter *counters,
- unsigned int n_counters)
+sfc_mae_counter_enable(struct sfc_adapter *sa, struct sfc_mae_counter *counter,
+ efx_mae_actions_t *action_set_spec)
{
- if (n_counters == 0)
+ struct sfc_mae_fw_rsrc *fw_rsrc;
+ int rc;
+
+ if (counter == NULL)
return 0;
SFC_ASSERT(sfc_adapter_is_locked(sa));
- SFC_ASSERT(n_counters == 1);
- if (counters[0].mae_id.id == EFX_MAE_RSRC_ID_INVALID) {
- sfc_err(sa, "failed to disable: already disabled");
- return EALREADY;
+ fw_rsrc = &counter->fw_rsrc;
+
+ if (fw_rsrc->refcnt == 0) {
+ SFC_ASSERT(fw_rsrc->counter_id.id == EFX_MAE_RSRC_ID_INVALID);
+
+ rc = sfc_mae_counter_fw_rsrc_enable(sa, counter);
+ if (rc != 0) {
+ sfc_err(sa, "failed to enable counter=%p: %s",
+ counter, rte_strerror(rc));
+ return rc;
+ }
+ }
+
+ if (action_set_spec != NULL) {
+ rc = efx_mae_action_set_fill_in_counter_id(
+ action_set_spec, &fw_rsrc->counter_id);
+ if (rc != 0) {
+ if (fw_rsrc->refcnt == 0) {
+ (void)sfc_mae_counter_fw_rsrc_disable(sa, counter);
+ fw_rsrc->counter_id.id = EFX_MAE_RSRC_ID_INVALID;
+ }
+
+ sfc_err(sa, "cannot fill in counter ID: %s",
+ strerror(rc));
+ return rc;
+ }
+ }
+
+ if (fw_rsrc->refcnt == 0) {
+ sfc_dbg(sa, "enabled counter=%p: COUNTER_ID=0x%08x",
+ counter, fw_rsrc->counter_id.id);
+ }
+
+ ++(fw_rsrc->refcnt);
+
+ return 0;
+}
+
+static void
+sfc_mae_counter_disable(struct sfc_adapter *sa, struct sfc_mae_counter *counter)
+{
+ struct sfc_mae_fw_rsrc *fw_rsrc;
+ int rc;
+
+ if (counter == NULL)
+ return;
+
+ SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+ fw_rsrc = &counter->fw_rsrc;
+
+ 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);
+ return;
+ }
+
+ if (fw_rsrc->refcnt == 1) {
+ uint32_t counter_id = fw_rsrc->counter_id.id;
+
+ 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);
+ } else {
+ sfc_err(sa, "failed to disable counter=%p with COUNTER_ID=0x%08x: %s",
+ counter, counter_id, strerror(rc));
+ }
+
+ fw_rsrc->counter_id.id = EFX_MAE_RSRC_ID_INVALID;
}
- return sfc_mae_counter_fw_rsrc_disable(sa, &counters[0]);
+ --(fw_rsrc->refcnt);
}
struct sfc_mae_aset_ctx {
- uint64_t *ft_switch_hit_counter;
- struct sfc_ft_ctx *counter_ft_ctx;
struct sfc_mae_encap_header *encap_header;
- unsigned int n_counters;
+ struct sfc_mae_counter *counter;
struct sfc_mae_mac_addr *dst_mac;
struct sfc_mae_mac_addr *src_mac;
@@ -897,17 +981,11 @@ sfc_mae_action_set_attach(struct sfc_adapter *sa,
SFC_ASSERT(sfc_adapter_is_locked(sa));
- /*
- * Shared counters are not supported, hence, action
- * sets with counters are not attachable.
- */
- if (ctx->n_counters != 0)
- return NULL;
-
TAILQ_FOREACH(action_set, &mae->action_sets, entries) {
if (action_set->encap_header == ctx->encap_header &&
action_set->dst_mac_addr == ctx->dst_mac &&
action_set->src_mac_addr == ctx->src_mac &&
+ action_set->counter == ctx->counter &&
efx_mae_action_set_specs_equal(action_set->spec,
ctx->spec)) {
sfc_dbg(sa, "attaching to action_set=%p", action_set);
@@ -921,13 +999,11 @@ sfc_mae_action_set_attach(struct sfc_adapter *sa,
static int
sfc_mae_action_set_add(struct sfc_adapter *sa,
- const struct rte_flow_action actions[],
const struct sfc_mae_aset_ctx *ctx,
struct sfc_mae_action_set **action_setp)
{
struct sfc_mae_action_set *action_set;
struct sfc_mae *mae = &sa->mae;
- unsigned int i;
SFC_ASSERT(sfc_adapter_is_locked(sa));
@@ -937,49 +1013,12 @@ sfc_mae_action_set_add(struct sfc_adapter *sa,
return ENOMEM;
}
- if (ctx->n_counters > 0) {
- const struct rte_flow_action *action;
-
- action_set->counters = rte_malloc("sfc_mae_counter_ids",
- sizeof(action_set->counters[0]) * ctx->n_counters, 0);
- if (action_set->counters == NULL) {
- rte_free(action_set);
- sfc_err(sa, "failed to alloc counters");
- return ENOMEM;
- }
-
- for (i = 0; i < ctx->n_counters; ++i) {
- action_set->counters[i].rte_id_valid = B_FALSE;
- action_set->counters[i].mae_id.id =
- EFX_MAE_RSRC_ID_INVALID;
-
- action_set->counters[i].ft_ctx = ctx->counter_ft_ctx;
- action_set->counters[i].ft_switch_hit_counter =
- ctx->ft_switch_hit_counter;
- }
-
- for (action = actions, i = 0;
- action->type != RTE_FLOW_ACTION_TYPE_END &&
- i < ctx->n_counters; ++action) {
- const struct rte_flow_action_count *conf;
-
- if (action->type != RTE_FLOW_ACTION_TYPE_COUNT)
- continue;
-
- conf = action->conf;
-
- action_set->counters[i].rte_id_valid = B_TRUE;
- action_set->counters[i].rte_id = conf->id;
- i++;
- }
- action_set->n_counters = ctx->n_counters;
- }
-
action_set->refcnt = 1;
action_set->spec = ctx->spec;
action_set->encap_header = ctx->encap_header;
action_set->dst_mac_addr = ctx->dst_mac;
action_set->src_mac_addr = ctx->src_mac;
+ action_set->counter = ctx->counter;
action_set->fw_rsrc.aset_id.id = EFX_MAE_RSRC_ID_INVALID;
@@ -1020,12 +1059,7 @@ sfc_mae_action_set_del(struct sfc_adapter *sa,
sfc_mae_encap_header_del(sa, action_set->encap_header);
sfc_mae_mac_addr_del(sa, action_set->dst_mac_addr);
sfc_mae_mac_addr_del(sa, action_set->src_mac_addr);
- if (action_set->n_counters > 0) {
- SFC_ASSERT(action_set->n_counters == 1);
- SFC_ASSERT(action_set->counters[0].mae_id.id ==
- EFX_MAE_RSRC_ID_INVALID);
- rte_free(action_set->counters);
- }
+ sfc_mae_counter_del(sa, action_set->counter);
TAILQ_REMOVE(&mae->action_sets, action_set, entries);
rte_free(action_set);
@@ -1039,7 +1073,7 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
struct sfc_mae_encap_header *encap_header;
struct sfc_mae_mac_addr *dst_mac_addr;
struct sfc_mae_mac_addr *src_mac_addr;
- struct sfc_mae_counter *counters;
+ struct sfc_mae_counter *counter;
struct sfc_mae_fw_rsrc *fw_rsrc;
int rc;
@@ -1051,8 +1085,8 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
encap_header = action_set->encap_header;
dst_mac_addr = action_set->dst_mac_addr;
src_mac_addr = action_set->src_mac_addr;
- counters = action_set->counters;
fw_rsrc = &action_set->fw_rsrc;
+ counter = action_set->counter;
if (fw_rsrc->refcnt == 0) {
SFC_ASSERT(fw_rsrc->aset_id.id == EFX_MAE_RSRC_ID_INVALID);
@@ -1080,7 +1114,7 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
return rc;
}
- if (action_set->n_counters > 0) {
+ if (counter != NULL) {
rc = sfc_mae_counter_start(sa);
if (rc != 0) {
sfc_err(sa, "failed to start MAE counters support: %s",
@@ -1092,13 +1126,8 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
}
}
- rc = sfc_mae_counters_enable(sa, counters,
- action_set->n_counters,
- action_set->spec);
+ rc = sfc_mae_counter_enable(sa, counter, action_set->spec);
if (rc != 0) {
- sfc_err(sa, "failed to enable %u MAE counters: %s",
- action_set->n_counters, rte_strerror(rc));
-
sfc_mae_encap_header_disable(sa, encap_header);
sfc_mae_mac_addr_disable(sa, src_mac_addr);
sfc_mae_mac_addr_disable(sa, dst_mac_addr);
@@ -1111,11 +1140,10 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
sfc_err(sa, "failed to enable action_set=%p: %s",
action_set, strerror(rc));
- (void)sfc_mae_counters_disable(sa, counters,
- action_set->n_counters);
sfc_mae_encap_header_disable(sa, encap_header);
sfc_mae_mac_addr_disable(sa, src_mac_addr);
sfc_mae_mac_addr_disable(sa, dst_mac_addr);
+ sfc_mae_counter_disable(sa, counter);
return rc;
}
@@ -1160,16 +1188,10 @@ sfc_mae_action_set_disable(struct sfc_adapter *sa,
}
fw_rsrc->aset_id.id = EFX_MAE_RSRC_ID_INVALID;
- rc = sfc_mae_counters_disable(sa, action_set->counters,
- action_set->n_counters);
- if (rc != 0) {
- sfc_err(sa, "failed to disable %u MAE counters: %s",
- action_set->n_counters, rte_strerror(rc));
- }
-
sfc_mae_encap_header_disable(sa, action_set->encap_header);
sfc_mae_mac_addr_disable(sa, action_set->src_mac_addr);
sfc_mae_mac_addr_disable(sa, action_set->dst_mac_addr);
+ sfc_mae_counter_disable(sa, action_set->counter);
}
--(fw_rsrc->refcnt);
@@ -3929,10 +3951,11 @@ 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
- __rte_unused,
+ const struct rte_flow_action_count *conf,
+ struct sfc_mae_counter **counterp,
efx_mae_actions_t *spec)
{
+ struct sfc_mae_counter counter_tmp = {};
int rc;
if ((sa->counter_rxq.state & SFC_COUNTER_RXQ_INITIALIZED) == 0) {
@@ -3947,17 +3970,33 @@ sfc_mae_rule_parse_action_count(struct sfc_adapter *sa,
goto fail_no_service_core;
}
- rc = efx_mae_action_set_populate_count(spec);
- if (rc != 0) {
- sfc_err(sa,
- "failed to populate counters in MAE action set: %s",
- rte_strerror(rc));
- goto fail_populate_count;
+ if (*counterp != NULL) {
+ sfc_err(sa, "cannot request more than 1 action COUNT per flow");
+ rc = EINVAL;
+ goto fail_more_than_one;
+ }
+
+ if (spec != NULL) {
+ rc = efx_mae_action_set_populate_count(spec);
+ if (rc != 0) {
+ sfc_err(sa,
+ "failed to populate counters in MAE action set: %s",
+ rte_strerror(rc));
+ goto fail_populate_count;
+ }
+ }
+
+ if (conf != NULL) {
+ counter_tmp.rte_id_valid = true;
+ counter_tmp.rte_id = conf->id;
}
+ return sfc_mae_counter_add(sa, &counter_tmp, counterp);
+
return 0;
fail_populate_count:
+fail_more_than_one:
fail_no_service_core:
fail_counter_queue_uninit:
@@ -4124,7 +4163,9 @@ 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;
const uint64_t rx_metadata = sa->negotiated_rx_metadata;
+ struct sfc_mae_counter **counterp = &ctx->counter;
efx_mae_actions_t *spec = ctx->spec;
+ efx_mae_actions_t *spec_ptr = spec;
unsigned int switch_port_type_mask;
bool custom_error = B_FALSE;
int rc = 0;
@@ -4212,7 +4253,8 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
case RTE_FLOW_ACTION_TYPE_COUNT:
SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_COUNT,
bundle->actions_mask);
- rc = sfc_mae_rule_parse_action_count(sa, action->conf, spec);
+ rc = sfc_mae_rule_parse_action_count(sa, action->conf,
+ counterp, spec_ptr);
break;
case RTE_FLOW_ACTION_TYPE_FLAG:
SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_FLAG,
@@ -4362,19 +4404,23 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
if (rc != 0)
goto fail_action_set_spec_init;
- for (action = actions;
- action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
- if (action->type == RTE_FLOW_ACTION_TYPE_COUNT)
- ++(ctx.n_counters);
- }
-
if (spec_mae->ft_rule_type == SFC_FT_RULE_SWITCH) {
+ bool have_user_action_count = false;
+
/* TUNNEL rules don't decapsulate packets. SWITCH rules do. */
rc = efx_mae_action_set_populate_decap(ctx.spec);
if (rc != 0)
goto fail_enforce_ft_decap;
- if (ctx.n_counters == 0 &&
+ for (action = actions;
+ action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
+ if (action->type == RTE_FLOW_ACTION_TYPE_COUNT) {
+ have_user_action_count = true;
+ break;
+ }
+ }
+
+ if (!have_user_action_count &&
sfc_mae_counter_stream_enabled(sa)) {
/*
* The user opted not to use action COUNT in this rule,
@@ -4386,7 +4432,9 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
if (rc != 0)
goto fail_enforce_ft_count;
- ctx.n_counters = 1;
+ rc = sfc_mae_counter_add(sa, NULL, &ctx.counter);
+ if (rc != 0)
+ goto fail_enforce_ft_count;
}
}
@@ -4416,13 +4464,6 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
if (rc != 0)
goto fail_process_encap_header;
- if (ctx.n_counters > 1) {
- rc = ENOTSUP;
- sfc_err(sa, "too many count actions requested: %u",
- ctx.n_counters);
- goto fail_nb_count;
- }
-
switch (spec_mae->ft_rule_type) {
case SFC_FT_RULE_NONE:
break;
@@ -4432,7 +4473,8 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
if (rc != 0)
goto fail_workaround_tunnel_delivery;
- ctx.counter_ft_ctx = spec_mae->ft_ctx;
+ if (ctx.counter != NULL)
+ (ctx.counter)->ft_ctx = spec_mae->ft_ctx;
break;
case SFC_FT_RULE_SWITCH:
/*
@@ -4441,7 +4483,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
*/
efx_mae_action_set_populate_mark_reset(ctx.spec);
- ctx.ft_switch_hit_counter =
+ (ctx.counter)->ft_switch_hit_counter =
&spec_mae->ft_ctx->switch_hit_counter;
break;
default:
@@ -4465,6 +4507,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
action_rule_ctx->action_set = sfc_mae_action_set_attach(sa, &ctx);
if (action_rule_ctx->action_set != NULL) {
+ sfc_mae_counter_del(sa, ctx.counter);
sfc_mae_mac_addr_del(sa, ctx.src_mac);
sfc_mae_mac_addr_del(sa, ctx.dst_mac);
sfc_mae_encap_header_del(sa, ctx.encap_header);
@@ -4472,8 +4515,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
return 0;
}
- rc = sfc_mae_action_set_add(sa, actions, &ctx,
- &action_rule_ctx->action_set);
+ rc = sfc_mae_action_set_add(sa, &ctx, &action_rule_ctx->action_set);
if (rc != 0)
goto fail_action_set_add;
@@ -4482,11 +4524,11 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
fail_action_set_add:
fail_check_fate_action:
fail_workaround_tunnel_delivery:
-fail_nb_count:
sfc_mae_encap_header_del(sa, ctx.encap_header);
fail_process_encap_header:
fail_rule_parse_action:
+ sfc_mae_counter_del(sa, ctx.counter);
sfc_mae_mac_addr_del(sa, ctx.src_mac);
sfc_mae_mac_addr_del(sa, ctx.dst_mac);
efx_mae_action_set_spec_fini(sa->nic, ctx.spec);
@@ -4766,28 +4808,22 @@ sfc_mae_query_counter(struct sfc_adapter *sa,
const struct sfc_mae_action_rule *action_rule = spec->action_rule;
const struct rte_flow_action_count *conf = action->conf;
struct sfc_mae_action_set *action_set;
- unsigned int i;
+ struct sfc_mae_counter *counter;
int rc;
- if (action_rule == NULL || action_rule->action_set->n_counters == 0) {
+ if (action_rule == NULL || action_rule->action_set->counter == NULL) {
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, action,
"Queried flow rule does not have count actions");
}
action_set = action_rule->action_set;
+ counter = action_set->counter;
- for (i = 0; i < action_set->n_counters; i++) {
- /*
- * Get the first available counter of the flow rule if
- * counter ID is not specified, provided that this
- * counter is not an automatic (implicit) one.
- */
- if (conf != NULL && action_set->counters[i].rte_id != conf->id)
- continue;
-
+ if (conf == NULL ||
+ (counter->rte_id_valid && conf->id == counter->rte_id)) {
rc = sfc_mae_counter_get(&sa->mae.counter_registry.counters,
- &action_set->counters[i], data);
+ counter, data);
if (rc != 0) {
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, action,
@@ -27,6 +27,7 @@ struct sfc_mae_fw_rsrc {
unsigned int refcnt;
RTE_STD_C11
union {
+ efx_counter_t counter_id;
efx_mae_aset_id_t aset_id;
efx_mae_rule_id_t rule_id;
efx_mae_mac_id_t mac_id;
@@ -67,10 +68,11 @@ struct sfc_mae_encap_header {
TAILQ_HEAD(sfc_mae_encap_headers, sfc_mae_encap_header);
-/* Counter ID */
+/* Counter object registry entry */
struct sfc_mae_counter {
- /* ID of a counter in MAE */
- efx_counter_t mae_id;
+ TAILQ_ENTRY(sfc_mae_counter) entries;
+ unsigned int refcnt;
+
/* ID of a counter in RTE */
uint32_t rte_id;
/* RTE counter ID validity status */
@@ -80,18 +82,21 @@ struct sfc_mae_counter {
uint64_t *ft_switch_hit_counter;
/* Flow Tunnel (FT) context (for TUNNEL rules; otherwise, NULL) */
struct sfc_ft_ctx *ft_ctx;
+
+ struct sfc_mae_fw_rsrc fw_rsrc;
};
+TAILQ_HEAD(sfc_mae_counters, sfc_mae_counter);
+
/** Action set registry entry */
struct sfc_mae_action_set {
TAILQ_ENTRY(sfc_mae_action_set) entries;
unsigned int refcnt;
- struct sfc_mae_counter *counters;
- uint32_t n_counters;
efx_mae_actions_t *spec;
struct sfc_mae_encap_header *encap_header;
struct sfc_mae_mac_addr *dst_mac_addr;
struct sfc_mae_mac_addr *src_mac_addr;
+ struct sfc_mae_counter *counter;
struct sfc_mae_fw_rsrc fw_rsrc;
};
@@ -221,6 +226,8 @@ struct sfc_mae {
bool counter_rxq_running;
/** Counter record registry */
struct sfc_mae_counter_registry counter_registry;
+ /** Counter object registry */
+ struct sfc_mae_counters counters;
/**
* Switchdev default rules. They forward traffic from PHY port
* to PF and vice versa.
@@ -110,7 +110,7 @@ sfc_mae_counter_fw_rsrc_enable(struct sfc_adapter *sa,
goto fail_counter_id_range;
}
- counterp->mae_id = mae_counter;
+ counterp->fw_rsrc.counter_id.id = mae_counter.id;
p = &counters->mae_counters[mae_counter.id];
@@ -152,29 +152,27 @@ sfc_mae_counter_fw_rsrc_disable(struct sfc_adapter *sa,
{
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_record *p;
uint32_t unused;
int rc;
- if (counter->mae_id.id == EFX_MAE_RSRC_ID_INVALID)
- return 0;
-
- SFC_ASSERT(counter->mae_id.id < counters->n_mae_counters);
+ SFC_ASSERT(mae_counter->id < counters->n_mae_counters);
/*
* The flag is set at the very end of add operation and reset
* at the beginning of delete operation. Release ordering is
* paired with acquire ordering on load in counter increment operation.
*/
- p = &counters->mae_counters[counter->mae_id.id];
+ p = &counters->mae_counters[mae_counter->id];
__atomic_store_n(&p->inuse, false, __ATOMIC_RELEASE);
- rc = efx_mae_counters_free(sa->nic, 1, &unused, &counter->mae_id, NULL);
+ rc = efx_mae_counters_free(sa->nic, 1, &unused, mae_counter, NULL);
if (rc != 0)
sfc_err(sa, "failed to free MAE counter %u: %s",
- counter->mae_id.id, rte_strerror(rc));
+ mae_counter->id, rte_strerror(rc));
sfc_info(sa, "disabled MAE counter #%u with reset pkts=%" PRIu64
- " bytes=%" PRIu64, counter->mae_id.id,
+ " bytes=%" PRIu64, mae_counter->id,
p->reset.pkts, p->reset.bytes);
/*
@@ -182,7 +180,7 @@ sfc_mae_counter_fw_rsrc_disable(struct sfc_adapter *sa,
* If there's some error, the resulting resource leakage is bad, but
* nothing sensible can be done in this case.
*/
- counter->mae_id.id = EFX_MAE_RSRC_ID_INVALID;
+ mae_counter->id = EFX_MAE_RSRC_ID_INVALID;
return rc;
}
@@ -952,8 +950,8 @@ sfc_mae_counter_get(struct sfc_mae_counter_records *counters,
struct sfc_mae_counter_record *p;
union sfc_pkts_bytes value;
- SFC_ASSERT(counter->mae_id.id < counters->n_mae_counters);
- p = &counters->mae_counters[counter->mae_id.id];
+ SFC_ASSERT(counter->fw_rsrc.counter_id.id < counters->n_mae_counters);
+ p = &counters->mae_counters[counter->fw_rsrc.counter_id.id];
/*
* Ordering is relaxed since it is the only operation on counter value.