drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c
Extension
.c
Size
4516 bytes
Lines
200
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mlx5e_tc_act_stats_handle {
	struct rhashtable ht;
	spinlock_t ht_lock; /* protects hashtable */
};

struct mlx5e_tc_act_stats {
	unsigned long		tc_act_cookie;

	struct mlx5_fc		*counter;
	u64			lastpackets;
	u64			lastbytes;

	struct rhash_head	hash;
	struct rcu_head		rcu_head;
};

static const struct rhashtable_params act_counters_ht_params = {
	.head_offset = offsetof(struct mlx5e_tc_act_stats, hash),
	.key_offset = offsetof(struct mlx5e_tc_act_stats, tc_act_cookie),
	.key_len = sizeof_field(struct mlx5e_tc_act_stats, tc_act_cookie),
	.automatic_shrinking = true,
};

struct mlx5e_tc_act_stats_handle *
mlx5e_tc_act_stats_create(void)
{
	struct mlx5e_tc_act_stats_handle *handle;
	int err;

	handle = kvzalloc_obj(*handle);
	if (!handle)
		return ERR_PTR(-ENOMEM);

	err = rhashtable_init(&handle->ht, &act_counters_ht_params);
	if (err)
		goto err;

	spin_lock_init(&handle->ht_lock);
	return handle;
err:
	kvfree(handle);
	return ERR_PTR(err);
}

void mlx5e_tc_act_stats_free(struct mlx5e_tc_act_stats_handle *handle)
{
	rhashtable_destroy(&handle->ht);
	kvfree(handle);
}

static int
mlx5e_tc_act_stats_add(struct mlx5e_tc_act_stats_handle *handle,
		       unsigned long act_cookie,
		       struct mlx5_fc *counter)
{
	struct mlx5e_tc_act_stats *act_stats, *old_act_stats;
	struct rhashtable *ht = &handle->ht;
	u64 lastused;
	int err = 0;

	act_stats = kvzalloc_obj(*act_stats);
	if (!act_stats)
		return -ENOMEM;

	act_stats->tc_act_cookie = act_cookie;
	act_stats->counter = counter;

	mlx5_fc_query_cached_raw(counter,
				 &act_stats->lastbytes,
				 &act_stats->lastpackets, &lastused);

	rcu_read_lock();
	old_act_stats = rhashtable_lookup_get_insert_fast(ht,
							  &act_stats->hash,
							  act_counters_ht_params);
	if (IS_ERR(old_act_stats)) {
		err = PTR_ERR(old_act_stats);
		goto err_hash_insert;
	} else if (old_act_stats) {
		err = -EEXIST;
		goto err_hash_insert;
	}
	rcu_read_unlock();

	return 0;

err_hash_insert:
	rcu_read_unlock();
	kvfree(act_stats);
	return err;

Annotation

Implementation Notes