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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
Extension
.c
Size
13687 bytes
Lines
537
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 qos_sq_callback_params {
	struct mlx5e_priv *priv;
	struct mlx5e_channels *chs;
};

int mlx5e_qos_bytes_rate_check(struct mlx5_core_dev *mdev, u64 nbytes)
{
	if (nbytes < BYTES_IN_MBIT) {
		qos_warn(mdev, "Input rate (%llu Bytes/sec) below minimum supported (%u Bytes/sec)\n",
			 nbytes, BYTES_IN_MBIT);
		return -EINVAL;
	}
	return 0;
}

static u32 mlx5e_qos_bytes2mbits(struct mlx5_core_dev *mdev, u64 nbytes)
{
	return div_u64(nbytes, BYTES_IN_MBIT);
}

int mlx5e_qos_max_leaf_nodes(struct mlx5_core_dev *mdev)
{
	return min(MLX5E_QOS_MAX_LEAF_NODES, mlx5_qos_max_leaf_nodes(mdev));
}

/* TX datapath API */

u16 mlx5e_qid_from_qos(struct mlx5e_channels *chs, u16 qid)
{
	/* These channel params are safe to access from the datapath, because:
	 * 1. This function is called only after checking selq->htb_maj_id != 0,
	 *    and the number of queues can't change while HTB offload is active.
	 * 2. When selq->htb_maj_id becomes 0, synchronize_rcu waits for
	 *    mlx5e_select_queue to finish while holding priv->state_lock,
	 *    preventing other code from changing the number of queues.
	 */
	bool is_ptp = MLX5E_GET_PFLAG(&chs->params, MLX5E_PFLAG_TX_PORT_TS);

	return (chs->params.num_channels + is_ptp) * mlx5e_get_dcb_num_tc(&chs->params) + qid;
}

/* SQ lifecycle */

static struct mlx5e_txqsq *mlx5e_get_qos_sq(struct mlx5e_priv *priv, int qid)
{
	struct mlx5e_params *params = &priv->channels.params;
	struct mlx5e_txqsq __rcu **qos_sqs;
	struct mlx5e_channel *c;
	int ix;

	ix = qid % params->num_channels;
	qid /= params->num_channels;
	c = priv->channels.c[ix];

	qos_sqs = mlx5e_state_dereference(priv, c->qos_sqs);
	return mlx5e_state_dereference(priv, qos_sqs[qid]);
}

int mlx5e_open_qos_sq(struct mlx5e_priv *priv, struct mlx5e_channels *chs,
		      u16 node_qid, u32 hw_id)
{
	struct mlx5e_create_cq_param ccp = {};
	struct mlx5e_txqsq __rcu **qos_sqs;
	struct mlx5e_sq_param param_sq;
	struct mlx5e_cq_param param_cq;
	int txq_ix, ix, qid, err = 0;
	struct mlx5e_params *params;
	struct mlx5e_channel *c;
	struct mlx5e_txqsq *sq;
	u32 tisn;

	params = &chs->params;

	txq_ix = mlx5e_qid_from_qos(chs, node_qid);

	WARN_ON(node_qid >= mlx5e_htb_cur_leaf_nodes(priv->htb));
	if (!priv->htb_qos_sq_stats) {
		struct mlx5e_sq_stats **stats_list;

		stats_list = kvzalloc_objs(*stats_list,
					   mlx5e_qos_max_leaf_nodes(priv->mdev));
		if (!stats_list)
			return -ENOMEM;

		WRITE_ONCE(priv->htb_qos_sq_stats, stats_list);
	}

	if (!priv->htb_qos_sq_stats[node_qid]) {
		struct mlx5e_sq_stats *stats;

Annotation

Implementation Notes