Skip to content

Commit 625e4b5

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 <[email protected]> Acked-by: Jason Wang <[email protected]> Signed-off-by: Dragos Tatulea <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Reviewed-by: Si-Wei Liu <[email protected]> Tested-by: Si-Wei Liu <[email protected]> Tested-by: Lei Yang <[email protected]>
1 parent 186e253 commit 625e4b5

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
@@ -913,7 +913,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque
913913
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
914914
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
915915
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
916-
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr.mkey);
916+
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
917917
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
918918
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
919919
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2673,35 +2673,26 @@ static void restore_channels_info(struct mlx5_vdpa_net *ndev)
26732673
}
26742674

26752675
static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
2676-
struct vhost_iotlb *iotlb, unsigned int asid)
2676+
struct mlx5_vdpa_mr *new_mr, unsigned int asid)
26772677
{
26782678
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
26792679
int err;
26802680

26812681
suspend_vqs(ndev);
26822682
err = save_channels_info(ndev);
26832683
if (err)
2684-
goto err_mr;
2684+
return err;
26852685

26862686
teardown_driver(ndev);
2687-
mlx5_vdpa_destroy_mr(mvdev, &mvdev->mr);
2688-
err = mlx5_vdpa_create_mr(mvdev, &mvdev->mr, iotlb);
2689-
if (err)
2690-
goto err_mr;
2687+
2688+
mlx5_vdpa_update_mr(mvdev, new_mr, asid);
26912689

26922690
if (!(mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) || mvdev->suspended)
2693-
goto err_mr;
2691+
return 0;
26942692

26952693
restore_channels_info(ndev);
26962694
err = setup_driver(mvdev);
2697-
if (err)
2698-
goto err_setup;
2699-
2700-
return 0;
27012695

2702-
err_setup:
2703-
mlx5_vdpa_destroy_mr(mvdev, &mvdev->mr);
2704-
err_mr:
27052696
return err;
27062697
}
27072698

@@ -2919,26 +2910,40 @@ static u32 mlx5_vdpa_get_generation(struct vdpa_device *vdev)
29192910
static int set_map_data(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
29202911
unsigned int asid)
29212912
{
2922-
bool change_map;
2913+
struct mlx5_vdpa_mr *new_mr;
29232914
int err;
29242915

29252916
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
29262917
goto end;
29272918

2928-
err = mlx5_vdpa_handle_set_map(mvdev, iotlb, &change_map, asid);
2929-
if (err) {
2930-
mlx5_vdpa_warn(mvdev, "set map failed(%d)\n", err);
2931-
return err;
2919+
if (vhost_iotlb_itree_first(iotlb, 0, U64_MAX)) {
2920+
new_mr = mlx5_vdpa_create_mr(mvdev, iotlb);
2921+
if (IS_ERR(new_mr)) {
2922+
err = PTR_ERR(new_mr);
2923+
mlx5_vdpa_warn(mvdev, "create map failed(%d)\n", err);
2924+
return err;
2925+
}
2926+
} else {
2927+
/* Empty iotlbs don't have an mr but will clear the previous mr. */
2928+
new_mr = NULL;
29322929
}
29332930

2934-
if (change_map) {
2935-
err = mlx5_vdpa_change_map(mvdev, iotlb, asid);
2936-
if (err)
2937-
return err;
2931+
if (!mvdev->mr) {
2932+
mlx5_vdpa_update_mr(mvdev, new_mr, asid);
2933+
} else {
2934+
err = mlx5_vdpa_change_map(mvdev, new_mr, asid);
2935+
if (err) {
2936+
mlx5_vdpa_warn(mvdev, "change map failed(%d)\n", err);
2937+
goto out_err;
2938+
}
29382939
}
29392940

29402941
end:
29412942
return mlx5_vdpa_update_cvq_iotlb(mvdev, iotlb, asid);
2943+
2944+
out_err:
2945+
mlx5_vdpa_destroy_mr(mvdev, new_mr);
2946+
return err;
29422947
}
29432948

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

0 commit comments

Comments
 (0)