Skip to content

Commit 6f5312f

Browse files
elic307imstsirkin
authored andcommitted
vdpa/mlx5: Add support for running with virtio_vdpa
In order to support running vdpa using vritio_vdpa driver, we need to create a different kind of MR, one that has 1:1 mapping, since the addresses referring to virtqueues are dma addresses. We create the 1:1 MR in mlx5_vdpa_dev_add() only in case firmware supports the general capability umem_uid_0. The reason for that is that 1:1 MRs must be created with uid == 0 while virtqueue objects can be created with uid == 0 only when the firmware capability is on. If the set_map() callback is called with new translations provided through iotlb, the driver will destroy the 1:1 MR and create a regular one. Signed-off-by: Eli Cohen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]> Acked-by: Jason Wang <[email protected]>
1 parent 7d23dcd commit 6f5312f

File tree

3 files changed

+87
-15
lines changed

3 files changed

+87
-15
lines changed

drivers/vdpa/mlx5/core/mlx5_vdpa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct mlx5_vdpa_mr {
3535

3636
/* serialize mkey creation and destruction */
3737
struct mutex mkey_mtx;
38+
bool user_mr;
3839
};
3940

4041
struct mlx5_vdpa_resources {

drivers/vdpa/mlx5/core/mr.c

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, u8
355355
* indirect memory key that provides access to the enitre address space given
356356
* by iotlb.
357357
*/
358-
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
358+
static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
359359
{
360360
struct mlx5_vdpa_mr *mr = &mvdev->mr;
361361
struct mlx5_vdpa_direct_mr *dmr;
@@ -369,9 +369,6 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
369369
int err = 0;
370370
int nnuls;
371371

372-
if (mr->initialized)
373-
return 0;
374-
375372
INIT_LIST_HEAD(&mr->head);
376373
for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
377374
map = vhost_iotlb_itree_next(map, start, last)) {
@@ -409,7 +406,7 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
409406
if (err)
410407
goto err_chain;
411408

412-
mr->initialized = true;
409+
mr->user_mr = true;
413410
return 0;
414411

415412
err_chain:
@@ -421,33 +418,94 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
421418
return err;
422419
}
423420

424-
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
421+
static int create_dma_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
422+
{
423+
int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
424+
void *mkc;
425+
u32 *in;
426+
int err;
427+
428+
in = kzalloc(inlen, GFP_KERNEL);
429+
if (!in)
430+
return -ENOMEM;
431+
432+
mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
433+
434+
MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_PA);
435+
MLX5_SET(mkc, mkc, length64, 1);
436+
MLX5_SET(mkc, mkc, lw, 1);
437+
MLX5_SET(mkc, mkc, lr, 1);
438+
MLX5_SET(mkc, mkc, pd, mvdev->res.pdn);
439+
MLX5_SET(mkc, mkc, qpn, 0xffffff);
440+
441+
err = mlx5_vdpa_create_mkey(mvdev, &mr->mkey, in, inlen);
442+
if (!err)
443+
mr->user_mr = false;
444+
445+
kfree(in);
446+
return err;
447+
}
448+
449+
static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
450+
{
451+
mlx5_vdpa_destroy_mkey(mvdev, &mr->mkey);
452+
}
453+
454+
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
425455
{
426456
struct mlx5_vdpa_mr *mr = &mvdev->mr;
427457
int err;
428458

429-
mutex_lock(&mr->mkey_mtx);
459+
if (mr->initialized)
460+
return 0;
461+
462+
if (iotlb)
463+
err = create_user_mr(mvdev, iotlb);
464+
else
465+
err = create_dma_mr(mvdev, mr);
466+
467+
if (!err)
468+
mr->initialized = true;
469+
470+
return err;
471+
}
472+
473+
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
474+
{
475+
int err;
476+
477+
mutex_lock(&mvdev->mr.mkey_mtx);
430478
err = _mlx5_vdpa_create_mr(mvdev, iotlb);
431-
mutex_unlock(&mr->mkey_mtx);
479+
mutex_unlock(&mvdev->mr.mkey_mtx);
432480
return err;
433481
}
434482

435-
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
483+
static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
436484
{
437-
struct mlx5_vdpa_mr *mr = &mvdev->mr;
438485
struct mlx5_vdpa_direct_mr *dmr;
439486
struct mlx5_vdpa_direct_mr *n;
440487

441-
mutex_lock(&mr->mkey_mtx);
442-
if (!mr->initialized)
443-
goto out;
444-
445488
destroy_indirect_key(mvdev, mr);
446489
list_for_each_entry_safe_reverse(dmr, n, &mr->head, list) {
447490
list_del_init(&dmr->list);
448491
unmap_direct_mr(mvdev, dmr);
449492
kfree(dmr);
450493
}
494+
}
495+
496+
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
497+
{
498+
struct mlx5_vdpa_mr *mr = &mvdev->mr;
499+
500+
mutex_lock(&mr->mkey_mtx);
501+
if (!mr->initialized)
502+
goto out;
503+
504+
if (mr->user_mr)
505+
destroy_user_mr(mvdev, mr);
506+
else
507+
destroy_dma_mr(mvdev, mr);
508+
451509
memset(mr, 0, sizeof(*mr));
452510
mr->initialized = false;
453511
out:

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,10 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
17811781
ndev->mvdev.status = 0;
17821782
ndev->mvdev.mlx_features = 0;
17831783
++mvdev->generation;
1784+
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
1785+
if (mlx5_vdpa_create_mr(mvdev, NULL))
1786+
mlx5_vdpa_warn(mvdev, "create MR failed\n");
1787+
}
17841788
return;
17851789
}
17861790

@@ -1861,6 +1865,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev)
18611865
ndev = to_mlx5_vdpa_ndev(mvdev);
18621866

18631867
free_resources(ndev);
1868+
mlx5_vdpa_destroy_mr(mvdev);
18641869
if (!is_zero_ether_addr(ndev->config.mac)) {
18651870
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
18661871
mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
@@ -2037,9 +2042,15 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name)
20372042
if (err)
20382043
goto err_mpfs;
20392044

2045+
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
2046+
err = mlx5_vdpa_create_mr(mvdev, NULL);
2047+
if (err)
2048+
goto err_res;
2049+
}
2050+
20402051
err = alloc_resources(ndev);
20412052
if (err)
2042-
goto err_res;
2053+
goto err_mr;
20432054

20442055
mvdev->vdev.mdev = &mgtdev->mgtdev;
20452056
err = _vdpa_register_device(&mvdev->vdev, 2 * mlx5_vdpa_max_qps(max_vqs));
@@ -2051,6 +2062,8 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name)
20512062

20522063
err_reg:
20532064
free_resources(ndev);
2065+
err_mr:
2066+
mlx5_vdpa_destroy_mr(mvdev);
20542067
err_res:
20552068
mlx5_vdpa_free_resources(&ndev->mvdev);
20562069
err_mpfs:

0 commit comments

Comments
 (0)