drivers/net/ethernet/mellanox/mlx5/core/rl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/rl.c
Extension
.c
Size
13192 bytes
Lines
460
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (dedicated) {
			if (!table->rl_entry[i].refcount)
				return &table->rl_entry[i];
			continue;
		}

		if (table->rl_entry[i].refcount) {
			if (table->rl_entry[i].dedicated)
				continue;
			if (mlx5_rl_are_equal_raw(&table->rl_entry[i], rl_in,
						  uid))
				return &table->rl_entry[i];
		} else if (!empty_found) {
			empty_found = true;
			ret_entry = &table->rl_entry[i];
		}
	}

	return ret_entry;
}

static int mlx5_set_pp_rate_limit_cmd(struct mlx5_core_dev *dev,
				      struct mlx5_rl_entry *entry, bool set)
{
	u32 in[MLX5_ST_SZ_DW(set_pp_rate_limit_in)] = {};
	void *pp_context;

	pp_context = MLX5_ADDR_OF(set_pp_rate_limit_in, in, ctx);
	MLX5_SET(set_pp_rate_limit_in, in, opcode,
		 MLX5_CMD_OP_SET_PP_RATE_LIMIT);
	MLX5_SET(set_pp_rate_limit_in, in, uid, entry->uid);
	MLX5_SET(set_pp_rate_limit_in, in, rate_limit_index, entry->index);
	if (set)
		memcpy(pp_context, entry->rl_raw, sizeof(entry->rl_raw));
	return mlx5_cmd_exec_in(dev, set_pp_rate_limit, in);
}

bool mlx5_rl_is_in_range(struct mlx5_core_dev *dev, u32 rate)
{
	struct mlx5_rl_table *table = &dev->priv.rl_table;

	return (rate <= table->max_rate && rate >= table->min_rate);
}
EXPORT_SYMBOL(mlx5_rl_is_in_range);

bool mlx5_rl_are_equal(struct mlx5_rate_limit *rl_0,
		       struct mlx5_rate_limit *rl_1)
{
	return ((rl_0->rate == rl_1->rate) &&
		(rl_0->max_burst_sz == rl_1->max_burst_sz) &&
		(rl_0->typical_pkt_sz == rl_1->typical_pkt_sz));
}
EXPORT_SYMBOL(mlx5_rl_are_equal);

static int mlx5_rl_table_get(struct mlx5_rl_table *table)
{
	int i;

	lockdep_assert_held(&table->rl_lock);

	if (table->rl_entry) {
		table->refcount++;
		return 0;
	}

	table->rl_entry = kzalloc_objs(struct mlx5_rl_entry, table->max_size);
	if (!table->rl_entry)
		return -ENOMEM;

	/* The index represents the index in HW rate limit table
	 * Index 0 is reserved for unlimited rate
	 */
	for (i = 0; i < table->max_size; i++)
		table->rl_entry[i].index = i + 1;

	table->refcount++;
	return 0;
}

static void mlx5_rl_table_put(struct mlx5_rl_table *table)
{
	lockdep_assert_held(&table->rl_lock);
	if (--table->refcount)
		return;

	kfree(table->rl_entry);
	table->rl_entry = NULL;
}

static void mlx5_rl_table_free(struct mlx5_core_dev *dev, struct mlx5_rl_table *table)

Annotation

Implementation Notes