Skip to content

Commit

Permalink
sfc: accumulate MAE counter values from update packets
Browse files Browse the repository at this point in the history
Add the packet and byte counts to the software running total, and store
 the latest jiffies every time the counter is bumped.

Signed-off-by: Edward Cree <ecree.xilinx@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Edward Cree authored and David S. Miller committed Nov 16, 2022
1 parent 0363aa2 commit c4bad43
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
54 changes: 53 additions & 1 deletion drivers/net/ethernet/sfc/tc_counters.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ static struct efx_tc_counter *efx_tc_flower_allocate_counter(struct efx_nic *efx
if (!cnt)
return ERR_PTR(-ENOMEM);

spin_lock_init(&cnt->lock);
cnt->touched = jiffies;
cnt->type = type;

rc = efx_mae_allocate_counter(efx, cnt);
Expand Down Expand Up @@ -131,9 +133,22 @@ static void efx_tc_flower_release_counter(struct efx_nic *efx,
* is handled by the generation count.
*/
synchronize_rcu();
EFX_WARN_ON_PARANOID(spin_is_locked(&cnt->lock));
kfree(cnt);
}

static struct efx_tc_counter *efx_tc_flower_find_counter_by_fw_id(
struct efx_nic *efx, int type, u32 fw_id)
{
struct efx_tc_counter key = {};

key.fw_id = fw_id;
key.type = type;

return rhashtable_lookup_fast(&efx->tc->counter_ht, &key,
efx_tc_counter_ht_params);
}

/* TC cookie to counter mapping */

void efx_tc_flower_put_counter_index(struct efx_nic *efx,
Expand Down Expand Up @@ -241,7 +256,44 @@ static void efx_tc_counter_update(struct efx_nic *efx,
u32 counter_idx, u64 packets, u64 bytes,
u32 mark)
{
/* Software counter objects do not exist yet, for now we ignore this */
struct efx_tc_counter *cnt;

rcu_read_lock(); /* Protect against deletion of 'cnt' */
cnt = efx_tc_flower_find_counter_by_fw_id(efx, counter_type, counter_idx);
if (!cnt) {
/* This can legitimately happen when a counter is removed,
* with updates for the counter still in-flight; however this
* should be an infrequent occurrence.
*/
if (net_ratelimit())
netif_dbg(efx, drv, efx->net_dev,
"Got update for unwanted MAE counter %u type %u\n",
counter_idx, counter_type);
goto out;
}

spin_lock_bh(&cnt->lock);
if ((s32)mark - (s32)cnt->gen < 0) {
/* This counter update packet is from before the counter was
* allocated; thus it must be for a previous counter with
* the same ID that has since been freed, and it should be
* ignored.
*/
} else {
/* Update latest seen generation count. This ensures that
* even a long-lived counter won't start getting ignored if
* the generation count wraps around, unless it somehow
* manages to go 1<<31 generations without an update.
*/
cnt->gen = mark;
/* update counter values */
cnt->packets += packets;
cnt->bytes += bytes;
cnt->touched = jiffies;
}
spin_unlock_bh(&cnt->lock);
out:
rcu_read_unlock();
}

static void efx_tc_rx_version_1(struct efx_nic *efx, const u8 *data, u32 mark)
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/sfc/tc_counters.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ 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 */
spinlock_t lock; /* Serialises updates to counter values */
u32 gen; /* Generation count at which this counter is current */
u64 packets, bytes;
/* jiffies of the last time we saw packets increase */
unsigned long touched;
};

struct efx_tc_counter_index {
Expand Down

0 comments on commit c4bad43

Please sign in to comment.