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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
Extension
.c
Size
18164 bytes
Lines
623
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_tx_timeout_ctx {
	struct mlx5e_txqsq *sq;
	signed int status;
};

static int mlx5e_tx_reporter_timeout_recover(void *ctx)
{
	struct mlx5e_tx_timeout_ctx *to_ctx;
	struct mlx5e_priv *priv;
	struct mlx5_eq_comp *eq;
	struct mlx5e_txqsq *sq;
	int err;

	to_ctx = ctx;
	sq = to_ctx->sq;
	eq = sq->cq.mcq.eq;
	priv = sq->priv;

	/* Recovering the TX queues implies re-enabling NAPI, which requires
	 * the netdev instance lock.
	 * However, channel closing flows have to wait for this work to finish
	 * while holding the same lock. So either get the lock or find that
	 * channels are being closed for other reason and this work is not
	 * relevant anymore.
	 */
	while (!netdev_trylock(priv->netdev)) {
		if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state))
			return 0;
		msleep(20);
	}

	err = mlx5e_health_channel_eq_recover(priv->netdev, eq, sq->cq.ch_stats);
	if (!err) {
		to_ctx->status = 0; /* this sq recovered */
		goto out;
	}

	mutex_lock(&priv->state_lock);
	err = mlx5e_safe_reopen_channels(priv);
	mutex_unlock(&priv->state_lock);
	if (!err) {
		to_ctx->status = 1; /* all channels recovered */
		goto out;
	}

	to_ctx->status = err;
	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
	netdev_err(priv->netdev,
		   "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
		   err);
out:
	netdev_unlock(priv->netdev);
	return err;
}

static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
{
	struct mlx5e_ptpsq *ptpsq = ctx;
	struct mlx5e_channels *chs;
	struct net_device *netdev;
	struct mlx5e_priv *priv;
	int carrier_ok;
	int err;

	if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &ptpsq->txqsq.state))
		return 0;

	priv = ptpsq->txqsq.priv;
	netdev = priv->netdev;

	/* Recovering the PTP SQ means re-enabling NAPI, which requires the
	 * netdev instance lock. However, SQ closing has to wait for this work
	 * task to finish while also holding the same lock. So either get the
	 * lock or find that the SQ is no longer enabled and thus this work is
	 * not relevant anymore.
	 */
	while (!netdev_trylock(netdev)) {
		if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state))
			return 0;
		msleep(20);
	}

	mutex_lock(&priv->state_lock);
	chs = &priv->channels;

	carrier_ok = netif_carrier_ok(netdev);
	netif_carrier_off(netdev);

	mlx5e_deactivate_priv_channels(priv);

Annotation

Implementation Notes