Commit 71fb4832 authored by Cosmin Ratiu's avatar Cosmin Ratiu Committed by Jakub Kicinski
Browse files

net/mlx5e: Use multiple TX doorbells



First, allocate more doorbells in mlx5e_create_mdev_resources:
- one doorbell remains 'global' and will be used by all non-channel
  associated SQs (e.g. ASO, HWS, PTP, ...).
- allocate additional 'num_doorbells' doorbells. This defaults to
  minimum between 8 and max number of channels.

mlx5e_channel_pick_doorbell() now spreads out channel SQs across
available doorbells.

Signed-off-by: default avatarCosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: default avatarDragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: default avatarTariq Toukan <tariqt@nvidia.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a315b723
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ static int mlx5e_create_tises(struct mlx5_core_dev *mdev, u32 tisn[MLX5_MAX_PORT
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
{
	struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs;
	unsigned int num_doorbells, i;
	int err;

	err = mlx5_core_alloc_pd(mdev, &res->pdn);
@@ -163,11 +164,30 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
		goto err_dealloc_transport_domain;
	}

	num_doorbells = min(MLX5_DEFAULT_NUM_DOORBELLS,
			    mlx5e_get_max_num_channels(mdev));
	res->bfregs = kcalloc(num_doorbells, sizeof(*res->bfregs), GFP_KERNEL);
	if (!res->bfregs) {
		err = -ENOMEM;
		goto err_destroy_mkey;
	}

	for (i = 0; i < num_doorbells; i++) {
		err = mlx5_alloc_bfreg(mdev, res->bfregs + i, false, false);
		if (err) {
			mlx5_core_warn(mdev,
				       "could only allocate %d/%d doorbells, err %d.\n",
				       i, num_doorbells, err);
			break;
		}
	}
	res->num_bfregs = i;

	if (create_tises) {
		err = mlx5e_create_tises(mdev, res->tisn);
		if (err) {
			mlx5_core_err(mdev, "alloc tises failed, %d\n", err);
			goto err_destroy_mkey;
			goto err_destroy_bfregs;
		}
		res->tisn_valid = true;
	}
@@ -184,6 +204,10 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)

	return 0;

err_destroy_bfregs:
	for (i = 0; i < res->num_bfregs; i++)
		mlx5_free_bfreg(mdev, res->bfregs + i);
	kfree(res->bfregs);
err_destroy_mkey:
	mlx5_core_destroy_mkey(mdev, res->mkey);
err_dealloc_transport_domain:
@@ -201,6 +225,9 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
	mdev->mlx5e_res.dek_priv = NULL;
	if (res->tisn_valid)
		mlx5e_destroy_tises(mdev, res->tisn);
	for (unsigned int i = 0; i < res->num_bfregs; i++)
		mlx5_free_bfreg(mdev, res->bfregs + i);
	kfree(res->bfregs);
	mlx5_core_destroy_mkey(mdev, res->mkey);
	mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
	mlx5_core_dealloc_pd(mdev, res->pdn);
+10 −1
Original line number Diff line number Diff line
@@ -2752,7 +2752,16 @@ void mlx5e_trigger_napi_sched(struct napi_struct *napi)

static void mlx5e_channel_pick_doorbell(struct mlx5e_channel *c)
{
	struct mlx5e_hw_objs *hw_objs = &c->mdev->mlx5e_res.hw_objs;

	/* No dedicated Ethernet doorbells, use the global one. */
	if (hw_objs->num_bfregs == 0) {
		c->bfreg = &c->mdev->priv.bfreg;
		return;
	}

	/* Round-robin between doorbells. */
	c->bfreg = hw_objs->bfregs + c->vec_ix % hw_objs->num_bfregs;
}

static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
+4 −0
Original line number Diff line number Diff line
@@ -658,6 +658,8 @@ struct mlx5e_resources {
		u32                        pdn;
		struct mlx5_td             td;
		u32			   mkey;
		struct mlx5_sq_bfreg      *bfregs;
		unsigned int               num_bfregs;
#define MLX5_MAX_NUM_TC 8
		u32                        tisn[MLX5_MAX_PORTS][MLX5_MAX_NUM_TC];
		bool			   tisn_valid;
@@ -801,6 +803,8 @@ struct mlx5_db {
	int			index;
};

#define MLX5_DEFAULT_NUM_DOORBELLS 8

enum {
	MLX5_COMP_EQ_SIZE = 1024,
};