Skip to content

Commit 5262912

Browse files
elic307imstsirkin
authored andcommitted
vdpa/mlx5: Add support for control VQ and MAC setting
Add support to handle control virtqueue configurations per virtio specification. The control virtqueue is implemented in software and no hardware offloading is involved. Control VQ configuration need task context, therefore all configurations are handled in a workqueue created for the purpose. Modifications are made to the memory registration code to allow for saving a copy of itolb to be used by the control VQ to access the vring. The max number of data virtqueus supported by the driver has been updated to 2 since multiqueue is not supported at this stage and we need to ensure consistency of VQ indices mapping to either data or control VQ. Signed-off-by: Eli Cohen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent e4fc665 commit 5262912

File tree

5 files changed

+329
-32
lines changed

5 files changed

+329
-32
lines changed

drivers/vdpa/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ config MLX5_VDPA
5353
config MLX5_VDPA_NET
5454
tristate "vDPA driver for ConnectX devices"
5555
select MLX5_VDPA
56+
select VHOST_RING
5657
depends on MLX5_CORE
5758
help
5859
VDPA network driver for ConnectX6 and newer. Provides offloading

drivers/vdpa/mlx5/core/mlx5_vdpa.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define __MLX5_VDPA_H__
66

77
#include <linux/etherdevice.h>
8+
#include <linux/vringh.h>
89
#include <linux/vdpa.h>
910
#include <linux/mlx5/driver.h>
1011

@@ -47,6 +48,26 @@ struct mlx5_vdpa_resources {
4748
bool valid;
4849
};
4950

51+
struct mlx5_control_vq {
52+
struct vhost_iotlb *iotlb;
53+
/* spinlock to synchronize iommu table */
54+
spinlock_t iommu_lock;
55+
struct vringh vring;
56+
bool ready;
57+
u64 desc_addr;
58+
u64 device_addr;
59+
u64 driver_addr;
60+
struct vdpa_callback event_cb;
61+
struct vringh_kiov riov;
62+
struct vringh_kiov wiov;
63+
unsigned short head;
64+
};
65+
66+
struct mlx5_ctrl_wq_ent {
67+
struct work_struct work;
68+
struct mlx5_vdpa_dev *mvdev;
69+
};
70+
5071
struct mlx5_vdpa_dev {
5172
struct vdpa_device vdev;
5273
struct mlx5_core_dev *mdev;
@@ -60,6 +81,8 @@ struct mlx5_vdpa_dev {
6081
u32 generation;
6182

6283
struct mlx5_vdpa_mr mr;
84+
struct mlx5_control_vq cvq;
85+
struct workqueue_struct *wq;
6386
};
6487

6588
int mlx5_vdpa_alloc_pd(struct mlx5_vdpa_dev *dev, u32 *pdn, u16 uid);

drivers/vdpa/mlx5/core/mr.c

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
22
/* Copyright (c) 2020 Mellanox Technologies Ltd. */
33

4+
#include <linux/vhost_types.h>
45
#include <linux/vdpa.h>
56
#include <linux/gcd.h>
67
#include <linux/string.h>
@@ -451,33 +452,30 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
451452
mlx5_vdpa_destroy_mkey(mvdev, &mr->mkey);
452453
}
453454

454-
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
455+
static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
455456
{
456-
struct mlx5_vdpa_mr *mr = &mvdev->mr;
457+
struct vhost_iotlb_map *map;
458+
u64 start = 0, last = ULLONG_MAX;
457459
int err;
458460

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;
461+
if (!src) {
462+
err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, start, VHOST_ACCESS_RW);
463+
return err;
464+
}
469465

470-
return err;
466+
for (map = vhost_iotlb_itree_first(src, start, last); map;
467+
map = vhost_iotlb_itree_next(map, start, last)) {
468+
err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, map->last,
469+
map->addr, map->perm);
470+
if (err)
471+
return err;
472+
}
473+
return 0;
471474
}
472475

473-
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
476+
static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
474477
{
475-
int err;
476-
477-
mutex_lock(&mvdev->mr.mkey_mtx);
478-
err = _mlx5_vdpa_create_mr(mvdev, iotlb);
479-
mutex_unlock(&mvdev->mr.mkey_mtx);
480-
return err;
478+
vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
481479
}
482480

483481
static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr)
@@ -501,6 +499,7 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
501499
if (!mr->initialized)
502500
goto out;
503501

502+
prune_iotlb(mvdev);
504503
if (mr->user_mr)
505504
destroy_user_mr(mvdev, mr);
506505
else
@@ -512,6 +511,48 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
512511
mutex_unlock(&mr->mkey_mtx);
513512
}
514513

514+
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
515+
{
516+
struct mlx5_vdpa_mr *mr = &mvdev->mr;
517+
int err;
518+
519+
if (mr->initialized)
520+
return 0;
521+
522+
if (iotlb)
523+
err = create_user_mr(mvdev, iotlb);
524+
else
525+
err = create_dma_mr(mvdev, mr);
526+
527+
if (err)
528+
return err;
529+
530+
err = dup_iotlb(mvdev, iotlb);
531+
if (err)
532+
goto out_err;
533+
534+
mr->initialized = true;
535+
return 0;
536+
537+
out_err:
538+
if (iotlb)
539+
destroy_user_mr(mvdev, mr);
540+
else
541+
destroy_dma_mr(mvdev, mr);
542+
543+
return err;
544+
}
545+
546+
int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb)
547+
{
548+
int err;
549+
550+
mutex_lock(&mvdev->mr.mkey_mtx);
551+
err = _mlx5_vdpa_create_mr(mvdev, iotlb);
552+
mutex_unlock(&mvdev->mr.mkey_mtx);
553+
return err;
554+
}
555+
515556
int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
516557
bool *change_map)
517558
{

drivers/vdpa/mlx5/core/resources.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
22
/* Copyright (c) 2020 Mellanox Technologies Ltd. */
33

4+
#include <linux/iova.h>
45
#include <linux/mlx5/driver.h>
56
#include "mlx5_vdpa.h"
67

@@ -221,6 +222,22 @@ int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, struct mlx5_core_mkey *m
221222
return mlx5_cmd_exec_in(mvdev->mdev, destroy_mkey, in);
222223
}
223224

225+
static int init_ctrl_vq(struct mlx5_vdpa_dev *mvdev)
226+
{
227+
mvdev->cvq.iotlb = vhost_iotlb_alloc(0, 0);
228+
if (!mvdev->cvq.iotlb)
229+
return -ENOMEM;
230+
231+
vringh_set_iotlb(&mvdev->cvq.vring, mvdev->cvq.iotlb, &mvdev->cvq.iommu_lock);
232+
233+
return 0;
234+
}
235+
236+
static void cleanup_ctrl_vq(struct mlx5_vdpa_dev *mvdev)
237+
{
238+
vhost_iotlb_free(mvdev->cvq.iotlb);
239+
}
240+
224241
int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
225242
{
226243
u64 offset = MLX5_CAP64_DEV_VDPA_EMULATION(mvdev->mdev, doorbell_bar_offset);
@@ -260,10 +277,17 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
260277
err = -ENOMEM;
261278
goto err_key;
262279
}
280+
281+
err = init_ctrl_vq(mvdev);
282+
if (err)
283+
goto err_ctrl;
284+
263285
res->valid = true;
264286

265287
return 0;
266288

289+
err_ctrl:
290+
iounmap(res->kick_addr);
267291
err_key:
268292
dealloc_pd(mvdev, res->pdn, res->uid);
269293
err_pd:
@@ -282,6 +306,7 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev)
282306
if (!res->valid)
283307
return;
284308

309+
cleanup_ctrl_vq(mvdev);
285310
iounmap(res->kick_addr);
286311
res->kick_addr = NULL;
287312
dealloc_pd(mvdev, res->pdn, res->uid);

0 commit comments

Comments
 (0)