drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c
Extension
.c
Size
6151 bytes
Lines
274
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 dr_arg_pool {
	enum dr_arg_chunk_size log_chunk_size;
	struct mlx5dr_domain *dmn;
	struct list_head free_list;
	struct mutex mutex; /* protect arg pool */
};

struct mlx5dr_arg_mgr {
	struct mlx5dr_domain *dmn;
	struct dr_arg_pool *pools[DR_ARG_CHUNK_SIZE_MAX];
};

static int dr_arg_pool_alloc_objs(struct dr_arg_pool *pool)
{
	struct mlx5dr_arg_obj *arg_obj, *tmp_arg;
	struct list_head cur_list;
	u16 object_range;
	int num_of_objects;
	u32 obj_id = 0;
	int i, ret;

	INIT_LIST_HEAD(&cur_list);

	object_range =
		pool->dmn->info.caps.log_header_modify_argument_granularity;

	object_range =
		max_t(u32, pool->dmn->info.caps.log_header_modify_argument_granularity,
		      DR_ICM_MODIFY_HDR_GRANULARITY_4K);
	object_range =
		min_t(u32, pool->dmn->info.caps.log_header_modify_argument_max_alloc,
		      object_range);

	if (pool->log_chunk_size > object_range) {
		mlx5dr_err(pool->dmn, "Required chunk size (%d) is not supported\n",
			   pool->log_chunk_size);
		return -ENOMEM;
	}

	num_of_objects = (1 << (object_range - pool->log_chunk_size));
	/* Only one devx object per range */
	ret = mlx5dr_cmd_create_modify_header_arg(pool->dmn->mdev,
						  object_range,
						  pool->dmn->pdn,
						  &obj_id);
	if (ret) {
		mlx5dr_err(pool->dmn, "failed allocating object with range: %d:\n",
			   object_range);
		return -EAGAIN;
	}

	for (i = 0; i < num_of_objects; i++) {
		arg_obj = kzalloc_obj(*arg_obj);
		if (!arg_obj) {
			ret = -ENOMEM;
			goto clean_arg_obj;
		}

		arg_obj->log_chunk_size = pool->log_chunk_size;

		list_add_tail(&arg_obj->list_node, &cur_list);

		arg_obj->obj_id = obj_id;
		arg_obj->obj_offset = i * (1 << pool->log_chunk_size);
	}
	list_splice_tail_init(&cur_list, &pool->free_list);

	return 0;

clean_arg_obj:
	mlx5dr_cmd_destroy_modify_header_arg(pool->dmn->mdev, obj_id);
	list_for_each_entry_safe(arg_obj, tmp_arg, &cur_list, list_node) {
		list_del(&arg_obj->list_node);
		kfree(arg_obj);
	}
	return ret;
}

static struct mlx5dr_arg_obj *dr_arg_pool_get_arg_obj(struct dr_arg_pool *pool)
{
	struct mlx5dr_arg_obj *arg_obj = NULL;
	int ret;

	mutex_lock(&pool->mutex);
	if (list_empty(&pool->free_list)) {
		ret = dr_arg_pool_alloc_objs(pool);
		if (ret)
			goto out;
	}

Annotation

Implementation Notes