sfc: add hashtables for MAE counters and counter ID mappings
authorEdward Cree <ecree.xilinx@gmail.com>
Mon, 14 Nov 2022 13:15:56 +0000 (13:15 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Nov 2022 09:07:02 +0000 (09:07 +0000)
Nothing populates them yet.

Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/tc.c
drivers/net/ethernet/sfc/tc.h
drivers/net/ethernet/sfc/tc_counters.c
drivers/net/ethernet/sfc/tc_counters.h

index 37d56a1ba958362965c0f76623b7b2153a8fa5d9..8ea7f52130498bf5d88b340927fdf822fdc2cb43 100644 (file)
@@ -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);
index 97dc06f2e694e6df1583d9c64ae0067294190c17..6c8ebb2d79c0d2731c4df0fe2fceee49089c3415 100644 (file)
@@ -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;
index 4a310cd7f17f6576db898dc87c74cb32626cbbd3..9a4d1d2a1271ffb39f15406148ad8a982d405f01 100644 (file)
 #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)
index 400a39b00f01cfb449770a54f28c0f98eeedf4f2..f998cee324c7b0d92a49a2d3dc844e61dbb6eec9 100644 (file)
@@ -10,6 +10,7 @@
 
 #ifndef EFX_TC_COUNTERS_H
 #define EFX_TC_COUNTERS_H
+#include <linux/refcount.h>
 #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 */