Skip to content

Commit 0118717

Browse files
Eli CohenSaeed Mahameed
authored andcommitted
net/mlx5: Add interface to get reference to a UAR
A reference to a UAR is required to generate CQ or EQ doorbells. Since CQ or EQ doorbells can all be generated using the same UAR area without any effect on performance, we are just getting a reference to any available UAR, If one is not available we allocate it but we don't waste the blue flame registers it can provide and we will use them for subsequent allocations. We get a reference to such UAR and put in mlx5_priv so any kernel consumer can make use of it. Signed-off-by: Eli Cohen <[email protected]> Reviewed-by: Matan Barak <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent a6d51b6 commit 0118717

File tree

4 files changed

+59
-14
lines changed

4 files changed

+59
-14
lines changed

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ static void init_eq_buf(struct mlx5_eq *eq)
512512

513513
int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
514514
int nent, u64 mask, const char *name,
515-
struct mlx5_uar *uar, enum mlx5_eq_type type)
515+
enum mlx5_eq_type type)
516516
{
517517
u32 out[MLX5_ST_SZ_DW(create_eq_out)] = {0};
518518
struct mlx5_priv *priv = &dev->priv;
@@ -556,7 +556,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
556556

557557
eqc = MLX5_ADDR_OF(create_eq_in, in, eq_context_entry);
558558
MLX5_SET(eqc, eqc, log_eq_size, ilog2(eq->nent));
559-
MLX5_SET(eqc, eqc, uar_page, uar->index);
559+
MLX5_SET(eqc, eqc, uar_page, priv->uar->index);
560560
MLX5_SET(eqc, eqc, intr, vecidx);
561561
MLX5_SET(eqc, eqc, log_page_size,
562562
eq->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
@@ -571,7 +571,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
571571
eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
572572
eq->irqn = priv->msix_arr[vecidx].vector;
573573
eq->dev = dev;
574-
eq->doorbell = uar->map + MLX5_EQ_DOORBEL_OFFSET;
574+
eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET;
575575
err = request_irq(eq->irqn, handler, 0,
576576
priv->irq_info[vecidx].name, eq);
577577
if (err)
@@ -686,8 +686,7 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
686686

687687
err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
688688
MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
689-
"mlx5_cmd_eq", &dev->priv.bfregi.uars[0],
690-
MLX5_EQ_TYPE_ASYNC);
689+
"mlx5_cmd_eq", MLX5_EQ_TYPE_ASYNC);
691690
if (err) {
692691
mlx5_core_warn(dev, "failed to create cmd EQ %d\n", err);
693692
return err;
@@ -697,8 +696,7 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
697696

698697
err = mlx5_create_map_eq(dev, &table->async_eq, MLX5_EQ_VEC_ASYNC,
699698
MLX5_NUM_ASYNC_EQE, async_event_mask,
700-
"mlx5_async_eq", &dev->priv.bfregi.uars[0],
701-
MLX5_EQ_TYPE_ASYNC);
699+
"mlx5_async_eq", MLX5_EQ_TYPE_ASYNC);
702700
if (err) {
703701
mlx5_core_warn(dev, "failed to create async EQ %d\n", err);
704702
goto err1;
@@ -708,7 +706,6 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
708706
MLX5_EQ_VEC_PAGES,
709707
/* TODO: sriov max_vf + */ 1,
710708
1 << MLX5_EVENT_TYPE_PAGE_REQUEST, "mlx5_pages_eq",
711-
&dev->priv.bfregi.uars[0],
712709
MLX5_EQ_TYPE_ASYNC);
713710
if (err) {
714711
mlx5_core_warn(dev, "failed to create pages EQ %d\n", err);
@@ -722,7 +719,6 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
722719
MLX5_NUM_ASYNC_EQE,
723720
1 << MLX5_EVENT_TYPE_PAGE_FAULT,
724721
"mlx5_page_fault_eq",
725-
&dev->priv.bfregi.uars[0],
726722
MLX5_EQ_TYPE_PF);
727723
if (err) {
728724
mlx5_core_warn(dev, "failed to create page fault EQ %d\n",

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,7 @@ static int alloc_comp_eqs(struct mlx5_core_dev *dev)
753753
snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i);
754754
err = mlx5_create_map_eq(dev, eq,
755755
i + MLX5_EQ_VEC_COMP_BASE, nent, 0,
756-
name, &dev->priv.bfregi.uars[0],
757-
MLX5_EQ_TYPE_COMP);
756+
name, MLX5_EQ_TYPE_COMP);
758757
if (err) {
759758
kfree(eq);
760759
goto clean;
@@ -1094,12 +1093,18 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
10941093
goto err_cleanup_once;
10951094
}
10961095

1097-
err = mlx5_alloc_bfregs(dev, &priv->bfregi);
1098-
if (err) {
1096+
dev->priv.uar = mlx5_get_uars_page(dev);
1097+
if (!dev->priv.uar) {
10991098
dev_err(&pdev->dev, "Failed allocating uar, aborting\n");
11001099
goto err_disable_msix;
11011100
}
11021101

1102+
err = mlx5_alloc_bfregs(dev, &priv->bfregi);
1103+
if (err) {
1104+
dev_err(&pdev->dev, "Failed allocating uuars, aborting\n");
1105+
goto err_uar_cleanup;
1106+
}
1107+
11031108
err = mlx5_start_eqs(dev);
11041109
if (err) {
11051110
dev_err(&pdev->dev, "Failed to start pages and async EQs\n");
@@ -1172,6 +1177,9 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
11721177
err_free_uar:
11731178
mlx5_free_bfregs(dev, &priv->bfregi);
11741179

1180+
err_uar_cleanup:
1181+
mlx5_put_uars_page(dev, priv->uar);
1182+
11751183
err_disable_msix:
11761184
mlx5_disable_msix(dev);
11771185

@@ -1231,6 +1239,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
12311239
free_comp_eqs(dev);
12321240
mlx5_stop_eqs(dev);
12331241
mlx5_free_bfregs(dev, &priv->bfregi);
1242+
mlx5_put_uars_page(dev, priv->uar);
12341243
mlx5_disable_msix(dev);
12351244
if (cleanup)
12361245
mlx5_cleanup_once(dev);
@@ -1305,6 +1314,11 @@ static int init_one(struct pci_dev *pdev,
13051314
goto clean_dev;
13061315
}
13071316
#endif
1317+
mutex_init(&priv->bfregs.reg_head.lock);
1318+
mutex_init(&priv->bfregs.wc_head.lock);
1319+
INIT_LIST_HEAD(&priv->bfregs.reg_head.list);
1320+
INIT_LIST_HEAD(&priv->bfregs.wc_head.list);
1321+
13081322
err = mlx5_pci_init(dev, priv);
13091323
if (err) {
13101324
dev_err(&pdev->dev, "mlx5_pci_init failed with error code %d\n", err);

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,38 @@ static struct mlx5_uars_page *alloc_uars_page(struct mlx5_core_dev *mdev,
332332
return ERR_PTR(err);
333333
}
334334

335+
struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev)
336+
{
337+
struct mlx5_uars_page *ret;
338+
339+
mutex_lock(&mdev->priv.bfregs.reg_head.lock);
340+
if (list_empty(&mdev->priv.bfregs.reg_head.list)) {
341+
ret = alloc_uars_page(mdev, false);
342+
if (IS_ERR(ret)) {
343+
ret = NULL;
344+
goto out;
345+
}
346+
list_add(&ret->list, &mdev->priv.bfregs.reg_head.list);
347+
} else {
348+
ret = list_first_entry(&mdev->priv.bfregs.reg_head.list,
349+
struct mlx5_uars_page, list);
350+
kref_get(&ret->ref_count);
351+
}
352+
out:
353+
mutex_unlock(&mdev->priv.bfregs.reg_head.lock);
354+
355+
return ret;
356+
}
357+
EXPORT_SYMBOL(mlx5_get_uars_page);
358+
359+
void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up)
360+
{
361+
mutex_lock(&mdev->priv.bfregs.reg_head.lock);
362+
kref_put(&up->ref_count, up_rel_func);
363+
mutex_unlock(&mdev->priv.bfregs.reg_head.lock);
364+
}
365+
EXPORT_SYMBOL(mlx5_put_uars_page);
366+
335367
static unsigned long map_offset(struct mlx5_core_dev *mdev, int dbi)
336368
{
337369
/* return the offset in bytes from the start of the page to the

include/linux/mlx5/driver.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ struct mlx5_priv {
679679
struct srcu_struct pfault_srcu;
680680
#endif
681681
struct mlx5_bfreg_data bfregs;
682+
struct mlx5_uars_page *uar;
682683
};
683684

684685
enum mlx5_device_state {
@@ -1007,7 +1008,7 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec);
10071008
void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type);
10081009
int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
10091010
int nent, u64 mask, const char *name,
1010-
struct mlx5_uar *uar, enum mlx5_eq_type type);
1011+
enum mlx5_eq_type type);
10111012
int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
10121013
int mlx5_start_eqs(struct mlx5_core_dev *dev);
10131014
int mlx5_stop_eqs(struct mlx5_core_dev *dev);
@@ -1118,6 +1119,8 @@ int mlx5_cmd_create_vport_lag(struct mlx5_core_dev *dev);
11181119
int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev);
11191120
bool mlx5_lag_is_active(struct mlx5_core_dev *dev);
11201121
struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev);
1122+
struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);
1123+
void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);
11211124

11221125
struct mlx5_profile {
11231126
u64 mask;

0 commit comments

Comments
 (0)