From 19a0c989104a08c07c97f8713d083cc635ef8d01 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Mon, 14 Nov 2022 13:15:56 +0000 Subject: [PATCH] sfc: add hashtables for MAE counters and counter ID mappings Nothing populates them yet. Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/tc.c | 6 +++ drivers/net/ethernet/sfc/tc.h | 4 ++ drivers/net/ethernet/sfc/tc_counters.c | 61 ++++++++++++++++++++++++++ drivers/net/ethernet/sfc/tc_counters.h | 19 ++++++++ 4 files changed, 90 insertions(+) diff --git a/drivers/net/ethernet/sfc/tc.c b/drivers/net/ethernet/sfc/tc.c index 37d56a1ba958..8ea7f5213049 100644 --- a/drivers/net/ethernet/sfc/tc.c +++ b/drivers/net/ethernet/sfc/tc.c @@ -752,6 +752,9 @@ int efx_init_struct_tc(struct efx_nic *efx) mutex_init(&efx->tc->mutex); init_waitqueue_head(&efx->tc->flush_wq); + rc = efx_tc_init_counters(efx); + if (rc < 0) + goto fail_counters; rc = rhashtable_init(&efx->tc->match_action_ht, &efx_tc_match_action_ht_params); if (rc < 0) goto fail_match_action_ht; @@ -764,6 +767,8 @@ int efx_init_struct_tc(struct efx_nic *efx) efx->extra_channel_type[EFX_EXTRA_CHANNEL_TC] = &efx_tc_channel_type; return 0; fail_match_action_ht: + efx_tc_destroy_counters(efx); +fail_counters: mutex_destroy(&efx->tc->mutex); kfree(efx->tc->caps); fail_alloc_caps: @@ -784,6 +789,7 @@ void efx_fini_struct_tc(struct efx_nic *efx) MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL); rhashtable_free_and_destroy(&efx->tc->match_action_ht, efx_tc_flow_free, efx); + efx_tc_fini_counters(efx); mutex_unlock(&efx->tc->mutex); mutex_destroy(&efx->tc->mutex); kfree(efx->tc->caps); diff --git a/drivers/net/ethernet/sfc/tc.h b/drivers/net/ethernet/sfc/tc.h index 97dc06f2e694..6c8ebb2d79c0 100644 --- a/drivers/net/ethernet/sfc/tc.h +++ b/drivers/net/ethernet/sfc/tc.h @@ -75,6 +75,8 @@ enum efx_tc_rule_prios { * @caps: MAE capabilities reported by MCDI * @block_list: List of &struct efx_tc_block_binding * @mutex: Used to serialise operations on TC hashtables + * @counter_ht: Hashtable of TC counters (FW IDs and counter values) + * @counter_id_ht: Hashtable mapping TC counter cookies to counters * @match_action_ht: Hashtable of TC match-action rules * @reps_mport_id: MAE port allocated for representor RX * @reps_filter_uc: VNIC filter for representor unicast RX (promisc) @@ -96,6 +98,8 @@ struct efx_tc_state { struct mae_caps *caps; struct list_head block_list; struct mutex mutex; + struct rhashtable counter_ht; + struct rhashtable counter_id_ht; struct rhashtable match_action_ht; u32 reps_mport_id, reps_mport_vport_id; s32 reps_filter_uc, reps_filter_mc; diff --git a/drivers/net/ethernet/sfc/tc_counters.c b/drivers/net/ethernet/sfc/tc_counters.c index 4a310cd7f17f..9a4d1d2a1271 100644 --- a/drivers/net/ethernet/sfc/tc_counters.c +++ b/drivers/net/ethernet/sfc/tc_counters.c @@ -13,6 +13,67 @@ #include "mae.h" #include "rx_common.h" +/* Counter-management hashtables */ + +static const struct rhashtable_params efx_tc_counter_id_ht_params = { + .key_len = offsetof(struct efx_tc_counter_index, linkage), + .key_offset = 0, + .head_offset = offsetof(struct efx_tc_counter_index, linkage), +}; + +static const struct rhashtable_params efx_tc_counter_ht_params = { + .key_len = offsetof(struct efx_tc_counter, linkage), + .key_offset = 0, + .head_offset = offsetof(struct efx_tc_counter, linkage), +}; + +static void efx_tc_counter_free(void *ptr, void *__unused) +{ + struct efx_tc_counter *cnt = ptr; + + kfree(cnt); +} + +static void efx_tc_counter_id_free(void *ptr, void *__unused) +{ + struct efx_tc_counter_index *ctr = ptr; + + WARN_ON(refcount_read(&ctr->ref)); + kfree(ctr); +} + +int efx_tc_init_counters(struct efx_nic *efx) +{ + int rc; + + rc = rhashtable_init(&efx->tc->counter_id_ht, &efx_tc_counter_id_ht_params); + if (rc < 0) + goto fail_counter_id_ht; + rc = rhashtable_init(&efx->tc->counter_ht, &efx_tc_counter_ht_params); + if (rc < 0) + goto fail_counter_ht; + return 0; +fail_counter_ht: + rhashtable_destroy(&efx->tc->counter_id_ht); +fail_counter_id_ht: + return rc; +} + +/* Only call this in init failure teardown. + * Normal exit should fini instead as there may be entries in the table. + */ +void efx_tc_destroy_counters(struct efx_nic *efx) +{ + rhashtable_destroy(&efx->tc->counter_ht); + rhashtable_destroy(&efx->tc->counter_id_ht); +} + +void efx_tc_fini_counters(struct efx_nic *efx) +{ + rhashtable_free_and_destroy(&efx->tc->counter_id_ht, efx_tc_counter_id_free, NULL); + rhashtable_free_and_destroy(&efx->tc->counter_ht, efx_tc_counter_free, NULL); +} + /* TC Channel. Counter updates are delivered on this channel's RXQ. */ static void efx_tc_handle_no_channel(struct efx_nic *efx) diff --git a/drivers/net/ethernet/sfc/tc_counters.h b/drivers/net/ethernet/sfc/tc_counters.h index 400a39b00f01..f998cee324c7 100644 --- a/drivers/net/ethernet/sfc/tc_counters.h +++ b/drivers/net/ethernet/sfc/tc_counters.h @@ -10,6 +10,7 @@ #ifndef EFX_TC_COUNTERS_H #define EFX_TC_COUNTERS_H +#include #include "net_driver.h" #include "mcdi_pcol.h" /* for MAE_COUNTER_TYPE_* */ @@ -21,6 +22,24 @@ enum efx_tc_counter_type { EFX_TC_COUNTER_TYPE_MAX }; +struct efx_tc_counter { + u32 fw_id; /* index in firmware counter table */ + enum efx_tc_counter_type type; + struct rhash_head linkage; /* efx->tc->counter_ht */ +}; + +struct efx_tc_counter_index { + unsigned long cookie; + struct rhash_head linkage; /* efx->tc->counter_id_ht */ + refcount_t ref; + struct efx_tc_counter *cnt; +}; + +/* create/uncreate/teardown hashtables */ +int efx_tc_init_counters(struct efx_nic *efx); +void efx_tc_destroy_counters(struct efx_nic *efx); +void efx_tc_fini_counters(struct efx_nic *efx); + extern const struct efx_channel_type efx_tc_channel_type; #endif /* EFX_TC_COUNTERS_H */