Commit c4bad432 authored by Edward Cree's avatar Edward Cree Committed by David S. Miller
Browse files

sfc: accumulate MAE counter values from update packets



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: default avatarEdward Cree <ecree.xilinx@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0363aa29
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -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);
@@ -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,
@@ -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)
+4 −0
Original line number Diff line number Diff line
@@ -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 {