drivers/net/ethernet/mellanox/mlx5/core/en/htb.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/htb.c
Extension
.c
Size
18956 bytes
Lines
723
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_qos_node {
	struct hlist_node hnode;
	struct mlx5e_qos_node *parent;
	u64 rate;
	u32 bw_share;
	u32 max_average_bw;
	u32 hw_id;
	u32 classid; /* 16-bit, except root. */
	u16 qid;
};

struct mlx5e_htb {
	DECLARE_HASHTABLE(qos_tc2node, order_base_2(MLX5E_QOS_MAX_LEAF_NODES));
	DECLARE_BITMAP(qos_used_qids, MLX5E_QOS_MAX_LEAF_NODES);
	struct mlx5_core_dev *mdev;
	struct net_device *netdev;
	struct mlx5e_priv *priv;
	struct mlx5e_selq *selq;
};

#define MLX5E_QOS_QID_INNER 0xffff
#define MLX5E_HTB_CLASSID_ROOT 0xffffffff

/* Software representation of the QoS tree */

int mlx5e_htb_enumerate_leaves(struct mlx5e_htb *htb, mlx5e_fp_htb_enumerate callback, void *data)
{
	struct mlx5e_qos_node *node = NULL;
	int bkt, err;

	hash_for_each(htb->qos_tc2node, bkt, node, hnode) {
		if (node->qid == MLX5E_QOS_QID_INNER)
			continue;
		err = callback(data, node->qid, node->hw_id);
		if (err)
			return err;
	}
	return 0;
}

int mlx5e_htb_cur_leaf_nodes(struct mlx5e_htb *htb)
{
	int last;

	last = find_last_bit(htb->qos_used_qids, mlx5e_qos_max_leaf_nodes(htb->mdev));
	return last == mlx5e_qos_max_leaf_nodes(htb->mdev) ? 0 : last + 1;
}

static int mlx5e_htb_find_unused_qos_qid(struct mlx5e_htb *htb)
{
	int size = mlx5e_qos_max_leaf_nodes(htb->mdev);
	struct mlx5e_priv *priv = htb->priv;
	int res;

	WARN_ONCE(!mutex_is_locked(&priv->state_lock), "%s: state_lock is not held\n", __func__);
	res = find_first_zero_bit(htb->qos_used_qids, size);

	return res == size ? -ENOSPC : res;
}

static struct mlx5e_qos_node *
mlx5e_htb_node_create_leaf(struct mlx5e_htb *htb, u16 classid, u16 qid,
			   struct mlx5e_qos_node *parent)
{
	struct mlx5e_qos_node *node;

	node = kzalloc_obj(*node);
	if (!node)
		return ERR_PTR(-ENOMEM);

	node->parent = parent;

	node->qid = qid;
	__set_bit(qid, htb->qos_used_qids);

	node->classid = classid;
	hash_add_rcu(htb->qos_tc2node, &node->hnode, classid);

	mlx5e_update_tx_netdev_queues(htb->priv);

	return node;
}

static struct mlx5e_qos_node *mlx5e_htb_node_create_root(struct mlx5e_htb *htb)
{
	struct mlx5e_qos_node *node;

	node = kzalloc_obj(*node);
	if (!node)
		return ERR_PTR(-ENOMEM);

Annotation

Implementation Notes