Skip to content

Commit 51f9574

Browse files
dtatuleamstsirkin
authored andcommitted
vdpa/mlx5: Improve mr update flow
The current flow for updating an mr works directly on mvdev->mr which makes it cumbersome to handle multiple new mr structs. This patch makes the flow more straightforward by having mlx5_vdpa_create_mr return a new mr which will update the old mr (if any). The old mr will be deleted and unlinked from mvdev. For the case when the iotlb is empty (not NULL), the old mr will be cleared. This change paves the way for adding mrs for different ASIDs. The initialized bool is no longer needed as mr is now a pointer in the mlx5_vdpa_dev struct which will be NULL when not initialized. Acked-by: Eugenio Pérez <eperezma@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com> Message-Id: <20231018171456.1624030-14-dtatulea@nvidia.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent f9fcb38 commit 51f9574

File tree

3 files changed

+82
-72
lines changed

3 files changed

+82
-72
lines changed

drivers/vdpa/mlx5/core/mlx5_vdpa.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
3131
struct list_head head;
3232
unsigned long num_directs;
3333
unsigned long num_klms;
34-
/* state of dvq mr */
35-
bool initialized;
3634

3735
bool user_mr;
3836
};
@@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
9189
u16 max_idx;
9290
u32 generation;
9391

94-
struct mlx5_vdpa_mr mr;
92+
struct mlx5_vdpa_mr *mr;
9593
/* serialize mr access */
9694
struct mutex mr_mtx;
9795
struct mlx5_control_vq cvq;
@@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev);
114112
int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
115113
int inlen);
116114
int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
117-
int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
118-
bool *change_map, unsigned int asid);
119-
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
120-
struct mlx5_vdpa_mr *mr,
121-
struct vhost_iotlb *iotlb);
115+
struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
116+
struct vhost_iotlb *iotlb);
122117
void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
123118
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
124119
struct mlx5_vdpa_mr *mr);
120+
void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
121+
struct mlx5_vdpa_mr *mr,
122+
unsigned int asid);
125123
int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
126124
struct vhost_iotlb *iotlb,
127125
unsigned int asid);

drivers/vdpa/mlx5/core/mr.c

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr
495495

496496
static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
497497
{
498-
if (!mr->initialized)
499-
return;
500-
501498
if (mr->user_mr)
502499
destroy_user_mr(mvdev, mr);
503500
else
504501
destroy_dma_mr(mvdev, mr);
505-
506-
mr->initialized = false;
507502
}
508503

509504
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
510505
struct mlx5_vdpa_mr *mr)
511506
{
507+
if (!mr)
508+
return;
509+
512510
mutex_lock(&mvdev->mr_mtx);
513511

514512
_mlx5_vdpa_destroy_mr(mvdev, mr);
515513

514+
if (mvdev->mr == mr)
515+
mvdev->mr = NULL;
516+
517+
mutex_unlock(&mvdev->mr_mtx);
518+
519+
kfree(mr);
520+
}
521+
522+
void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
523+
struct mlx5_vdpa_mr *new_mr,
524+
unsigned int asid)
525+
{
526+
struct mlx5_vdpa_mr *old_mr = mvdev->mr;
527+
528+
mutex_lock(&mvdev->mr_mtx);
529+
530+
mvdev->mr = new_mr;
531+
if (old_mr) {
532+
_mlx5_vdpa_destroy_mr(mvdev, old_mr);
533+
kfree(old_mr);
534+
}
535+
516536
mutex_unlock(&mvdev->mr_mtx);
537+
517538
}
518539

519540
void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
520541
{
521-
mlx5_vdpa_destroy_mr(mvdev, &mvdev->mr);
542+
mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
522543
prune_iotlb(mvdev);
523544
}
524545

@@ -528,52 +549,36 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
528549
{
529550
int err;
530551

531-
if (mr->initialized)
532-
return 0;
533-
534552
if (iotlb)
535553
err = create_user_mr(mvdev, mr, iotlb);
536554
else
537555
err = create_dma_mr(mvdev, mr);
538556

539-
if (err)
540-
return err;
541-
542-
mr->initialized = true;
543-
544-
return 0;
557+
return err;
545558
}
546559

547-
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
548-
struct mlx5_vdpa_mr *mr,
549-
struct vhost_iotlb *iotlb)
560+
struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
561+
struct vhost_iotlb *iotlb)
550562
{
563+
struct mlx5_vdpa_mr *mr;
551564
int err;
552565

566+
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
567+
if (!mr)
568+
return ERR_PTR(-ENOMEM);
569+
553570
mutex_lock(&mvdev->mr_mtx);
554571
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
555572
mutex_unlock(&mvdev->mr_mtx);
556573

557-
return err;
558-
}
559-
560-
int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
561-
bool *change_map, unsigned int asid)
562-
{
563-
struct mlx5_vdpa_mr *mr = &mvdev->mr;
564-
int err = 0;
574+
if (err)
575+
goto out_err;
565576

566-
*change_map = false;
567-
mutex_lock(&mvdev->mr_mtx);
568-
if (mr->initialized) {
569-
mlx5_vdpa_info(mvdev, "memory map update\n");
570-
*change_map = true;
571-
}
572-
if (!*change_map)
573-
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
574-
mutex_unlock(&mvdev->mr_mtx);
577+
return mr;
575578

576-
return err;
579+
out_err:
580+
kfree(mr);
581+
return ERR_PTR(err);
577582
}
578583

579584
int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
@@ -597,11 +602,13 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
597602

598603
int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
599604
{
600-
int err;
605+
struct mlx5_vdpa_mr *mr;
601606

602-
err = mlx5_vdpa_create_mr(mvdev, &mvdev->mr, NULL);
603-
if (err)
604-
return err;
607+
mr = mlx5_vdpa_create_mr(mvdev, NULL);
608+
if (IS_ERR(mr))
609+
return PTR_ERR(mr);
610+
611+
mlx5_vdpa_update_mr(mvdev, mr, 0);
605612

606613
return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
607614
}

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
914914
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
915915
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
916916
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
917-
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr.mkey);
917+
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
918918
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
919919
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
920920
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2679,35 +2679,26 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev)
26792679
}
26802680

26812681
static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
2682-
struct vhost_iotlb *iotlb, unsigned int asid)
2682+
struct mlx5_vdpa_mr *new_mr, unsigned int asid)
26832683
{
26842684
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
26852685
int err;
26862686

26872687
suspend_vqs(ndev);
26882688
err = save_channels_info(ndev);
26892689
if (err)
2690-
goto err_mr;
2690+
return err;
26912691

26922692
teardown_driver(ndev);
2693-
mlx5_vdpa_destroy_mr(mvdev, &mvdev->mr);
2694-
err = mlx5_vdpa_create_mr(mvdev, &mvdev->mr, iotlb);
2695-
if (err)
2696-
goto err_mr;
2693+
2694+
mlx5_vdpa_update_mr(mvdev, new_mr, asid);
26972695

26982696
if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)
2699-
goto err_mr;
2697+
return 0;
27002698

27012699
restore_channels_info(ndev);
27022700
err = setup_driver(mvdev);
2703-
if (err)
2704-
goto err_setup;
2705-
2706-
return 0;
27072701

2708-
err_setup:
2709-
mlx5_vdpa_destroy_mr(mvdev, &mvdev->mr);
2710-
err_mr:
27112702
return err;
27122703
}
27132704

@@ -2925,26 +2916,40 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
29252916
static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
29262917
unsigned int asid)
29272918
{
2928-
bool change_map;
2919+
struct mlx5_vdpa_mr *new_mr;
29292920
int err;
29302921

29312922
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
29322923
goto end;
29332924

2934-
err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid);
2935-
if (err) {
2936-
mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
2937-
return err;
2925+
if (vhost_iotlb_itree_first(iotlb, 0, U64_MAX)) {
2926+
new_mr = mlx5_vdpa_create_mr(mvdev, iotlb);
2927+
if (IS_ERR(new_mr)) {
2928+
err = PTR_ERR(new_mr);
2929+
mlx5_vdpa_warn(mvdev, "create map failed(%d)\n", err);
2930+
return err;
2931+
}
2932+
} else {
2933+
/* Empty iotlbs don't have an mr but will clear the previous mr. */
2934+
new_mr = NULL;
29382935
}
29392936

2940-
if (change_map) {
2941-
err = mlx5_vdpa_change_map(mvdev, iotlb, asid);
2942-
if (err)
2943-
return err;
2937+
if (!mvdev->mr) {
2938+
mlx5_vdpa_update_mr(mvdev, new_mr, asid);
2939+
} else {
2940+
err = mlx5_vdpa_change_map(mvdev, new_mr, asid);
2941+
if (err) {
2942+
mlx5_vdpa_warn(mvdev, "change map failed(%d)\n", err);
2943+
goto out_err;
2944+
}
29442945
}
29452946

29462947
end:
29472948
return mlx5_vdpa_update_cvq_iotlb(mvdev, iotlb, asid);
2949+
2950+
out_err:
2951+
mlx5_vdpa_destroy_mr(mvdev, new_mr);
2952+
return err;
29482953
}
29492954

29502955
static int mlx5_vdpa_set_map(struct vdpa_device *vdev, unsigned int asid,

0 commit comments

Comments
 (0)