Re: [PATCH] vhost-vdpa: fix NULL pointer deref in _compat_vdpa_reset

2023-10-24 Thread Dragos Tatulea via Virtualization
On Mon, 2023-10-23 at 16:14 -0700, Si-Wei Liu wrote:
> As subject. There's a vhost_vdpa_reset() done earlier before
> vhost_dev is initialized via vhost_dev_init(), ending up with
> NULL pointer dereference. Fix is to check if vqs is initialized
> before checking backend features and resetting the device.
> 
>   BUG: kernel NULL pointer dereference, address: 
>   #PF: supervisor read access in kernel mode
>   #PF: error_code(0x) - not-present page
>   PGD 0 P4D 0
>   Oops:  [#1] SMP
>   CPU: 3 PID: 1727 Comm: qemu-system-x86 Not tainted 6.6.0-rc6+ #2
>   Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-
>   a4aeb02-prebuilt.qemu.org 04/01/2014
>   RIP: 0010:_compat_vdpa_reset+0x47/0xc0 [vhost_vdpa]
>   Code: c7 c7 fb 12 56 a0 4c 8d a5 b8 02 00 00 48 89 ea e8 7e b8 c4
>   48 89 ee 48 c7 c7 19 13 56 a0 4c 8b ad b0 02 00 00 <48> 8b 00 49
>   00 48 8b 80 88 45 00 00 48 c1 e8 08 48
>   RSP: 0018:8881063c3c38 EFLAGS: 00010246
>   RAX:  RBX: 8881074eb800 RCX: 
>   RDX:  RSI: 888103ab4000 RDI: a0561319
>   RBP: 888103ab4000 R08: dfff R09: 0001
>   R10: 0003 R11: 7fecbac0 R12: 888103ab42b8
>   R13: 888106dbe850 R14: 0003 R15: 8881074ebc18
>   FS:  7f02fba6ef00() GS:5f8c()
>   knlGS:
>   CS:  0010 DS:  ES:  CR0: 80050033
>   CR2:  CR3: 0001325e5003 CR4: 00372ea0
>   DR0:  DR1:  DR2: 
>   DR3:  DR6: fffe0ff0 DR7: 0400
>   Call Trace:
>    
>    ? __die+0x1f/0x60
>    ? page_fault_oops+0x14c/0x3b0
>    ? exc_page_fault+0x74/0x140
>    ? asm_exc_page_fault+0x22/0x30
>    ? _compat_vdpa_reset+0x47/0xc0 [vhost_vdpa]
>    ? _compat_vdpa_reset+0x32/0xc0 [vhost_vdpa]
>    vhost_vdpa_open+0x55/0x270 [vhost_vdpa]
>    ? sb_init_dio_done_wq+0x50/0x50
>    chrdev_open+0xc0/0x210
>    ? __unregister_chrdev+0x50/0x50
>    do_dentry_open+0x1fc/0x4f0
>    path_openat+0xc2d/0xf20
>    do_filp_open+0xb4/0x160
>    ? kmem_cache_alloc+0x3c/0x490
>    do_sys_openat2+0x8d/0xc0
>    __x64_sys_openat+0x6a/0xa0
>    do_syscall_64+0x3c/0x80
>    entry_SYSCALL_64_after_hwframe+0x46/0xb0
> 
> Fixes: 10cbf8dfaf93 ("vhost-vdpa: clean iotlb map during reset for older
> userspace")
> Reported-by: Dragos Tatulea 

This works, thanks for the quick response.

Tested-by: Dragos Tatulea 

> Closes:
> https://lore.kernel.org/all/b4913f84-8b52-4d28-af51-8573dc361...@oracle.com/
> Signed-off-by: Si-Wei Liu 
> ---
>  drivers/vhost/vdpa.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
> index 9ce40003793b..9a2343c45df0 100644
> --- a/drivers/vhost/vdpa.c
> +++ b/drivers/vhost/vdpa.c
> @@ -232,9 +232,11 @@ static int _compat_vdpa_reset(struct vhost_vdpa *v)
> struct vdpa_device *vdpa = v->vdpa;
> u32 flags = 0;
>  
> -   flags |= !vhost_backend_has_feature(v->vdev.vqs[0],
> -   VHOST_BACKEND_F_IOTLB_PERSIST) ?
> -    VDPA_RESET_F_CLEAN_MAP : 0;
> +   if (v->vdev.vqs) {
> +   flags |= !vhost_backend_has_feature(v->vdev.vqs[0],
> +  
> VHOST_BACKEND_F_IOTLB_PERSIST) ?
> +    VDPA_RESET_F_CLEAN_MAP : 0;
> +   }
>  
> return vdpa_reset(vdpa, flags);
>  }

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH vhost v4 12/16] vdpa/mlx5: Improve mr update flow

2023-10-23 Thread Dragos Tatulea via Virtualization
On Fri, 2023-10-20 at 18:01 +0200, Eugenio Perez Martin wrote:
> On Wed, Oct 18, 2023 at 7:21 PM Dragos Tatulea  wrote:
> > 
> > On Wed, 2023-10-18 at 20:14 +0300, Dragos Tatulea wrote:
> > > 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 
> > > Acked-by: Jason Wang 
> > > Signed-off-by: Dragos Tatulea 
> > > ---
> > >  drivers/vdpa/mlx5/core/mlx5_vdpa.h | 14 +++--
> > >  drivers/vdpa/mlx5/core/mr.c    | 87 --
> > >  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 53 +-
> > >  3 files changed, 82 insertions(+), 72 deletions(-)
> > > 
> > > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > index 9c6ac42c21e1..bbe4335106bd 100644
> > > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > @@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
> > >     struct list_head head;
> > >     unsigned long num_directs;
> > >     unsigned long num_klms;
> > > -   /* state of dvq mr */
> > > -   bool initialized;
> > > 
> > >     bool user_mr;
> > >  };
> > > @@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
> > >     u16 max_idx;
> > >     u32 generation;
> > > 
> > > -   struct mlx5_vdpa_mr mr;
> > > +   struct mlx5_vdpa_mr *mr;
> > >     /* serialize mr access */
> > >     struct mutex mr_mtx;
> > >     struct mlx5_control_vq cvq;
> > > @@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev
> > > *mvdev);
> > >  int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32
> > > *in,
> > >   int inlen);
> > >  int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
> > > -int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct
> > > vhost_iotlb
> > > *iotlb,
> > > -    bool *change_map, unsigned int asid);
> > > -int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> > > -   struct mlx5_vdpa_mr *mr,
> > > -   struct vhost_iotlb *iotlb);
> > > +struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> > > +    struct vhost_iotlb *iotlb);
> > >  void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
> > >  void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
> > >   struct mlx5_vdpa_mr *mr);
> > > +void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
> > > +    struct mlx5_vdpa_mr *mr,
> > > +    unsigned int asid);
> > >  int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
> > >     struct vhost_iotlb *iotlb,
> > >     unsigned int asid);
> > > diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> > > index abd6a6fb122f..00eff5a07152 100644
> > > --- a/drivers/vdpa/mlx5/core/mr.c
> > > +++ b/drivers/vdpa/mlx5/core/mr.c
> > > @@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev
> > > *mvdev,
> > > struct mlx5_vdpa_mr *mr
> > > 
> > >  static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct
> > > mlx5_vdpa_mr *mr)
> > >  {
> > > -   if (!mr->initialized)
> > > -   return;
> > > -
> > >     if (mr->user_mr)
> > >     destroy_user_mr(mvdev, mr);
> > >     else
> > >     destroy_dma_mr(mvdev, mr);
> > > -
> > > -   mr->initialized = false;
> > >  }
> > > 
> > >  void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
> > >   struct mlx5_vdpa_mr *mr)
> > >  {
> > > +   if (!mr)
> > > +   return;
> > > +
> > >     mutex_lock(>mr_mtx);
> > > 
> > >     _mlx5_vdpa_destroy_mr(mvdev, mr);
> > > 
> > > +   if (mvdev->mr == mr)
> > > +   mvdev->mr = NULL;
> > > +
> > > +   mutex_unlock(>mr_mtx);
> > > +
> > > +   kfree(mr);
> > > +}
> > > +
> > > +void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
> > > +    struct mlx5_vdpa_mr *new_mr,
> > > +    unsigned int asid)
> > > +{
> > > +   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
> > > +
> > > +   mutex_lock(>mr_mtx);
> > > +
> > > +   mvdev->mr = new_mr;
> > > +   if (old_mr) {
> > > +   _mlx5_vdpa_destroy_mr(mvdev, old_mr);
> > > +  

Re: [PATCH vhost v4 12/16] vdpa/mlx5: Improve mr update flow

2023-10-18 Thread Dragos Tatulea via Virtualization
On Wed, 2023-10-18 at 20:14 +0300, Dragos Tatulea wrote:
> 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 
> Acked-by: Jason Wang 
> Signed-off-by: Dragos Tatulea 
> ---
>  drivers/vdpa/mlx5/core/mlx5_vdpa.h | 14 +++--
>  drivers/vdpa/mlx5/core/mr.c    | 87 --
>  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 53 +-
>  3 files changed, 82 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> index 9c6ac42c21e1..bbe4335106bd 100644
> --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> @@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
> struct list_head head;
> unsigned long num_directs;
> unsigned long num_klms;
> -   /* state of dvq mr */
> -   bool initialized;
>  
> bool user_mr;
>  };
> @@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
> u16 max_idx;
> u32 generation;
>  
> -   struct mlx5_vdpa_mr mr;
> +   struct mlx5_vdpa_mr *mr;
> /* serialize mr access */
> struct mutex mr_mtx;
> struct mlx5_control_vq cvq;
> @@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev
> *mvdev);
>  int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
>   int inlen);
>  int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
> -int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
> *iotlb,
> -    bool *change_map, unsigned int asid);
> -int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> -   struct mlx5_vdpa_mr *mr,
> -   struct vhost_iotlb *iotlb);
> +struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> +    struct vhost_iotlb *iotlb);
>  void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
>  void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
>   struct mlx5_vdpa_mr *mr);
> +void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
> +    struct mlx5_vdpa_mr *mr,
> +    unsigned int asid);
>  int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
> struct vhost_iotlb *iotlb,
> unsigned int asid);
> diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> index abd6a6fb122f..00eff5a07152 100644
> --- a/drivers/vdpa/mlx5/core/mr.c
> +++ b/drivers/vdpa/mlx5/core/mr.c
> @@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev,
> struct mlx5_vdpa_mr *mr
>  
>  static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct
> mlx5_vdpa_mr *mr)
>  {
> -   if (!mr->initialized)
> -   return;
> -
> if (mr->user_mr)
> destroy_user_mr(mvdev, mr);
> else
> destroy_dma_mr(mvdev, mr);
> -
> -   mr->initialized = false;
>  }
>  
>  void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
>   struct mlx5_vdpa_mr *mr)
>  {
> +   if (!mr)
> +   return;
> +
> mutex_lock(>mr_mtx);
>  
> _mlx5_vdpa_destroy_mr(mvdev, mr);
>  
> +   if (mvdev->mr == mr)
> +   mvdev->mr = NULL;
> +
> +   mutex_unlock(>mr_mtx);
> +
> +   kfree(mr);
> +}
> +
> +void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
> +    struct mlx5_vdpa_mr *new_mr,
> +    unsigned int asid)
> +{
> +   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
> +
> +   mutex_lock(>mr_mtx);
> +
> +   mvdev->mr = new_mr;
> +   if (old_mr) {
> +   _mlx5_vdpa_destroy_mr(mvdev, old_mr);
> +   kfree(old_mr);
> +   }
> +
> mutex_unlock(>mr_mtx);
> +
>  }
>  
>  void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
>  {
> -   mlx5_vdpa_destroy_mr(mvdev, >mr);
> +   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
> prune_iotlb(mvdev);
>  }
>  
> @@ -528,52 +549,36 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev
> *mvdev,
>  {
> int err;
>  
> -   if (mr->initialized)
> -   return 0;
> -
> if (iotlb)
> err = create_user_mr(mvdev, mr, iotlb);
> else
> err = create_dma_mr(mvdev, mr);
>  
> 

[PATCH vhost v4 16/16] vdpa/mlx5: Update cvq iotlb mapping on ASID change

2023-10-18 Thread Dragos Tatulea via Virtualization
For the following sequence:
- cvq group is in ASID 0
- .set_map(1, cvq_iotlb)
- .set_group_asid(cvq_group, 1)

... the cvq mapping from ASID 0 will be used. This is not always correct
behaviour.

This patch adds support for the above mentioned flow by saving the iotlb
on each .set_map and updating the cvq iotlb with it on a cvq group change.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  2 ++
 drivers/vdpa/mlx5/core/mr.c| 26 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  9 -
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ae09296f4270..db988ced5a5d 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -32,6 +32,8 @@ struct mlx5_vdpa_mr {
unsigned long num_directs;
unsigned long num_klms;
 
+   struct vhost_iotlb *iotlb;
+
bool user_mr;
 };
 
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 4a3df865df40..66530e28f327 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -502,6 +502,8 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
+
+   vhost_iotlb_free(mr->iotlb);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
@@ -561,6 +563,30 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
else
err = create_dma_mr(mvdev, mr);
 
+   if (err)
+   return err;
+
+   mr->iotlb = vhost_iotlb_alloc(0, 0);
+   if (!mr->iotlb) {
+   err = -ENOMEM;
+   goto err_mr;
+   }
+
+   err = dup_iotlb(mr->iotlb, iotlb);
+   if (err)
+   goto err_iotlb;
+
+   return 0;
+
+err_iotlb:
+   vhost_iotlb_free(mr->iotlb);
+
+err_mr:
+   if (iotlb)
+   destroy_user_mr(mvdev, mr);
+   else
+   destroy_dma_mr(mvdev, mr);
+
return err;
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 87dd0ba76899..5774f4adb7c4 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -3159,12 +3159,19 @@ static int mlx5_set_group_asid(struct vdpa_device 
*vdev, u32 group,
   unsigned int asid)
 {
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+   int err = 0;
 
if (group >= MLX5_VDPA_NUMVQ_GROUPS)
return -EINVAL;
 
mvdev->group2asid[group] = asid;
-   return 0;
+
+   mutex_lock(>mr_mtx);
+   if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid])
+   err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, 
asid);
+   mutex_unlock(>mr_mtx);
+
+   return err;
 }
 
 static const struct vdpa_config_ops mlx5_vdpa_ops = {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 15/16] vdpa/mlx5: Make iotlb helper functions more generic

2023-10-18 Thread Dragos Tatulea via Virtualization
They will be used in a follow-up patch.

For dup_iotlb, avoid the src == dst case. This is an error.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 3dee6d9bed6b..4a3df865df40 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -454,20 +454,23 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr)
mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
 }
 
-static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
+static int dup_iotlb(struct vhost_iotlb *dst, struct vhost_iotlb *src)
 {
struct vhost_iotlb_map *map;
u64 start = 0, last = ULLONG_MAX;
int err;
 
+   if (dst == src)
+   return -EINVAL;
+
if (!src) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, 
start, VHOST_ACCESS_RW);
+   err = vhost_iotlb_add_range(dst, start, last, start, 
VHOST_ACCESS_RW);
return err;
}
 
for (map = vhost_iotlb_itree_first(src, start, last); map;
map = vhost_iotlb_itree_next(map, start, last)) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, 
map->last,
+   err = vhost_iotlb_add_range(dst, map->start, map->last,
map->addr, map->perm);
if (err)
return err;
@@ -475,9 +478,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *src)
return 0;
 }
 
-static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
+static void prune_iotlb(struct vhost_iotlb *iotlb)
 {
-   vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
+   vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
 }
 
 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr 
*mr)
@@ -544,7 +547,7 @@ void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev 
*mvdev)
for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
 
-   prune_iotlb(mvdev);
+   prune_iotlb(mvdev->cvq.iotlb);
 }
 
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
@@ -596,8 +599,8 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
 
spin_lock(>cvq.iommu_lock);
 
-   prune_iotlb(mvdev);
-   err = dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev->cvq.iotlb);
+   err = dup_iotlb(mvdev->cvq.iotlb, iotlb);
 
spin_unlock(>cvq.iommu_lock);
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 14/16] vdpa/mlx5: Enable hw support for vq descriptor mapping

2023-10-18 Thread Dragos Tatulea via Virtualization
Vq descriptor mappings are supported in hardware by filling in an
additional mkey which contains the descriptor mappings to the hw vq.

A previous patch in this series added support for hw mkey (mr) creation
for ASID 1.

This patch fills in both the vq data and vq descriptor mkeys based on
group ASID mapping.

The feature is signaled to the vdpa core through the presence of the
.get_vq_desc_group op.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 24 +++-
 include/linux/mlx5/mlx5_ifc_vdpa.h |  7 ++-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index ea76c0b4b78e..87dd0ba76899 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -823,6 +823,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
struct mlx5_vdpa_dev *mvdev = >mvdev;
struct mlx5_vdpa_mr *vq_mr;
+   struct mlx5_vdpa_mr *vq_desc_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -878,6 +879,11 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
if (vq_mr)
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
+
+   vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
+   if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, 
desc_group_mkey_supported))
+   MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey);
+
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2265,6 +2271,16 @@ static u32 mlx5_vdpa_get_vq_group(struct vdpa_device 
*vdev, u16 idx)
return MLX5_VDPA_DATAVQ_GROUP;
 }
 
+static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
+{
+   struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+
+   if (is_ctrl_vq_idx(mvdev, idx))
+   return MLX5_VDPA_CVQ_GROUP;
+
+   return MLX5_VDPA_DATAVQ_DESC_GROUP;
+}
+
 static u64 mlx_to_vritio_features(u16 dev_features)
 {
u64 result = 0;
@@ -3165,6 +3181,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
.get_vq_irq = mlx5_get_vq_irq,
.get_vq_align = mlx5_vdpa_get_vq_align,
.get_vq_group = mlx5_vdpa_get_vq_group,
+   .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not 
supported. */
.get_device_features = mlx5_vdpa_get_device_features,
.set_driver_features = mlx5_vdpa_set_driver_features,
.get_driver_features = mlx5_vdpa_get_driver_features,
@@ -3263,6 +3280,7 @@ struct mlx5_vdpa_mgmtdev {
struct vdpa_mgmt_dev mgtdev;
struct mlx5_adev *madev;
struct mlx5_vdpa_net *ndev;
+   struct vdpa_config_ops vdpa_ops;
 };
 
 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
@@ -3376,7 +3394,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
max_vqs = 2;
}
 
-   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, _vdpa_ops,
+   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, >vdpa_ops,
 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, 
name, false);
if (IS_ERR(ndev))
return PTR_ERR(ndev);
@@ -3551,6 +3569,10 @@ static int mlx5v_probe(struct auxiliary_device *adev,
MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
mgtdev->mgtdev.supported_features = get_supported_features(mdev);
mgtdev->madev = madev;
+   mgtdev->vdpa_ops = mlx5_vdpa_ops;
+
+   if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported))
+   mgtdev->vdpa_ops.get_vq_desc_group = NULL;
 
err = vdpa_mgmtdev_register(>mgtdev);
if (err)
diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h 
b/include/linux/mlx5/mlx5_ifc_vdpa.h
index 9becdc3fa503..b86d51a855f6 100644
--- a/include/linux/mlx5/mlx5_ifc_vdpa.h
+++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
@@ -74,7 +74,11 @@ struct mlx5_ifc_virtio_q_bits {
u8reserved_at_320[0x8];
u8pd[0x18];
 
-   u8reserved_at_340[0xc0];
+   u8reserved_at_340[0x20];
+
+   u8desc_group_mkey[0x20];
+
+   u8reserved_at_380[0x80];
 };
 
 struct mlx5_ifc_virtio_net_q_object_bits {
@@ -141,6 +145,7 @@ enum {
MLX5_VIRTQ_MODIFY_MASK_STATE= (u64)1 << 0,
MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS  = (u64)1 << 3,
MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4,
+   MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY  = (u64)1 << 14,
 

[PATCH vhost v4 12/16] vdpa/mlx5: Improve mr update flow

2023-10-18 Thread Dragos Tatulea via Virtualization
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 
Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 14 +++--
 drivers/vdpa/mlx5/core/mr.c| 87 --
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 53 +-
 3 files changed, 82 insertions(+), 72 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 9c6ac42c21e1..bbe4335106bd 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
struct list_head head;
unsigned long num_directs;
unsigned long num_klms;
-   /* state of dvq mr */
-   bool initialized;
 
bool user_mr;
 };
@@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr mr;
+   struct mlx5_vdpa_mr *mr;
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
@@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev 
*mvdev);
 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
  int inlen);
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
-int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
-bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb);
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr);
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *mr,
+unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index abd6a6fb122f..00eff5a07152 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
 
 static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   if (!mr->initialized)
-   return;
-
if (mr->user_mr)
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
-
-   mr->initialized = false;
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
+   if (!mr)
+   return;
+
mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
+   if (mvdev->mr == mr)
+   mvdev->mr = NULL;
+
+   mutex_unlock(>mr_mtx);
+
+   kfree(mr);
+}
+
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *new_mr,
+unsigned int asid)
+{
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+
+   mutex_lock(>mr_mtx);
+
+   mvdev->mr = new_mr;
+   if (old_mr) {
+   _mlx5_vdpa_destroy_mr(mvdev, old_mr);
+   kfree(old_mr);
+   }
+
mutex_unlock(>mr_mtx);
+
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, >mr);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
prune_iotlb(mvdev);
 }
 
@@ -528,52 +549,36 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
 {
int err;
 
-   if (mr->initialized)
-   return 0;
-
if (iotlb)
err = create_user_mr(mvdev, mr, iotlb);
else
err = create_dma_mr(mvdev, mr);
 
-   if (err)
-   return err;
-
-   mr->initialized = true;
-
-   return 0;
+   return err;
 }
 
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb)
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 

[PATCH vhost v4 13/16] vdpa/mlx5: Introduce mr for vq descriptor

2023-10-18 Thread Dragos Tatulea via Virtualization
Introduce the vq descriptor group and mr per ASID. Until now
.set_map on ASID 1 was only updating the cvq iotlb. From now on it also
creates a mkey for it. The current patch doesn't use it but follow-up
patches will add hardware support for mapping the vq descriptors.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  5 +++--
 drivers/vdpa/mlx5/core/mr.c| 14 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 20 +---
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index bbe4335106bd..ae09296f4270 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -70,11 +70,12 @@ struct mlx5_vdpa_wq_ent {
 enum {
MLX5_VDPA_DATAVQ_GROUP,
MLX5_VDPA_CVQ_GROUP,
+   MLX5_VDPA_DATAVQ_DESC_GROUP,
MLX5_VDPA_NUMVQ_GROUPS
 };
 
 enum {
-   MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
+   MLX5_VDPA_NUM_AS = 2
 };
 
 struct mlx5_vdpa_dev {
@@ -89,7 +90,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr *mr;
+   struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS];
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00eff5a07152..3dee6d9bed6b 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -511,8 +511,10 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   if (mvdev->mr == mr)
-   mvdev->mr = NULL;
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
+   if (mvdev->mr[i] == mr)
+   mvdev->mr[i] = NULL;
+   }
 
mutex_unlock(>mr_mtx);
 
@@ -523,11 +525,11 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 struct mlx5_vdpa_mr *new_mr,
 unsigned int asid)
 {
-   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
 
mutex_lock(>mr_mtx);
 
-   mvdev->mr = new_mr;
+   mvdev->mr[asid] = new_mr;
if (old_mr) {
_mlx5_vdpa_destroy_mr(mvdev, old_mr);
kfree(old_mr);
@@ -539,7 +541,9 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
+
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 7b878995b6aa..ea76c0b4b78e 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -821,6 +821,8 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
 {
int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
+   struct mlx5_vdpa_dev *mvdev = >mvdev;
+   struct mlx5_vdpa_mr *vq_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -873,7 +875,9 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
-   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
+   vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
+   if (vq_mr)
+   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2633,7 +2637,8 @@ static void restore_channels_info(struct mlx5_vdpa_net 
*ndev)
 }
 
 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *new_mr, unsigned int asid)
+   struct mlx5_vdpa_mr *new_mr,
+   unsigned int asid)
 {
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
int err;
@@ -2652,8 +2657,10 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
 
restore_channels_info(ndev);
err = setup_driver(mvdev);
+   if (err)
+   return err;
 
-   return err;
+   return 0;
 }
 
 /* reslock must be held for this function */
@@ -2869,8 +2876,8 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
struct mlx5_vdpa_mr *new_mr;
int err;
 
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-  

[PATCH vhost v4 11/16] vdpa/mlx5: Move mr mutex out of mr struct

2023-10-18 Thread Dragos Tatulea via Virtualization
The mutex is named like it is supposed to protect only the mkey but in
reality it is a global lock for all mr resources.

Shift the mutex to it's rightful location (struct mlx5_vdpa_dev) and
give it a more appropriate name.

Signed-off-by: Dragos Tatulea 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c| 13 +++--
 drivers/vdpa/mlx5/core/resources.c |  6 +++---
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 01d4ee58ccb1..9c6ac42c21e1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -34,8 +34,6 @@ struct mlx5_vdpa_mr {
/* state of dvq mr */
bool initialized;
 
-   /* serialize mkey creation and destruction */
-   struct mutex mkey_mtx;
bool user_mr;
 };
 
@@ -94,6 +92,8 @@ struct mlx5_vdpa_dev {
u32 generation;
 
struct mlx5_vdpa_mr mr;
+   /* serialize mr access */
+   struct mutex mr_mtx;
struct mlx5_control_vq cvq;
struct workqueue_struct *wq;
unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 6f29e8eaabb1..abd6a6fb122f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -509,11 +509,11 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
@@ -550,9 +550,10 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
 {
int err;
 
-   mutex_lock(>mr.mkey_mtx);
+   mutex_lock(>mr_mtx);
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mr.mkey_mtx);
+   mutex_unlock(>mr_mtx);
+
return err;
 }
 
@@ -563,14 +564,14 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
int err = 0;
 
*change_map = false;
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
if (mr->initialized) {
mlx5_vdpa_info(mvdev, "memory map update\n");
*change_map = true;
}
if (!*change_map)
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 
return err;
 }
diff --git a/drivers/vdpa/mlx5/core/resources.c 
b/drivers/vdpa/mlx5/core/resources.c
index d5a59c9035fb..5c5a41b64bfc 100644
--- a/drivers/vdpa/mlx5/core/resources.c
+++ b/drivers/vdpa/mlx5/core/resources.c
@@ -256,7 +256,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
mlx5_vdpa_warn(mvdev, "resources already allocated\n");
return -EINVAL;
}
-   mutex_init(>mr.mkey_mtx);
+   mutex_init(>mr_mtx);
res->uar = mlx5_get_uars_page(mdev);
if (IS_ERR(res->uar)) {
err = PTR_ERR(res->uar);
@@ -301,7 +301,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
 err_uctx:
mlx5_put_uars_page(mdev, res->uar);
 err_uars:
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
return err;
 }
 
@@ -318,6 +318,6 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev)
dealloc_pd(mvdev, res->pdn, res->uid);
destroy_uctx(mvdev, res->uid);
mlx5_put_uars_page(mvdev->mdev, res->uar);
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
res->valid = false;
 }
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 10/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-10-18 Thread Dragos Tatulea via Virtualization
This patch adapts the mr creation/deletion code to be able to work with
any given mr struct pointer. All the APIs are adapted to take an extra
parameter for the mr.

mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
check is done in the caller instead (mlx5_set_map).

This change is needed for a followup patch which will introduce an
additional mr for the vq descriptor data.

Signed-off-by: Dragos Tatulea 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  8 +++--
 drivers/vdpa/mlx5/core/mr.c| 53 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 10 --
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index e1e6e7aba50e..01d4ee58ccb1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -116,10 +116,12 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, 
u32 *mkey, u32 *in,
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
 int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
 bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
-   unsigned int asid);
+int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00dcce190a1f..6f29e8eaabb1 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -301,10 +301,13 @@ static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_direct
sg_free_table(>sg_head);
 }
 
-static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, 
u8 perm,
+static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   u64 start,
+   u64 size,
+   u8 perm,
struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
LIST_HEAD(tmp);
@@ -354,9 +357,10 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, 
u64 start, u64 size, u8
  * indirect memory key that provides access to the enitre address space given
  * by iotlb.
  */
-static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb)
+static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr,
+ struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
struct vhost_iotlb_map *map;
@@ -384,7 +388,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
   
LOG_MAX_KLM_SIZE);
mr->num_klms += nnuls;
}
-   err = add_direct_chain(mvdev, ps, pe - ps, 
pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, 
pperm, iotlb);
if (err)
goto err_chain;
}
@@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
pperm = map->perm;
}
}
-   err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
if (err)
goto err_chain;
 
@@ -489,13 +493,8 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
-
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   return;
-
if (!mr->initialized)
return;
 
@@ -507,38 +506,33 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr(struct 

[PATCH vhost v4 07/16] vdpa/mlx5: Take cvq iotlb lock during refresh

2023-10-18 Thread Dragos Tatulea via Virtualization
The reslock is taken while refresh is called but iommu_lock is more
specific to this resource. So take the iommu_lock during cvq iotlb
refresh.

Based on Eugenio's patch [0].

[0] https://lore.kernel.org/lkml/20230112142218.725622-4-epere...@redhat.com/

Acked-by: Jason Wang 
Suggested-by: Eugenio Pérez 
Reviewed-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fcb6ae32e9ed..587300e7c18e 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -590,11 +590,19 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev 
*mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid)
 {
+   int err;
+
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
return 0;
 
+   spin_lock(>cvq.iommu_lock);
+
prune_iotlb(mvdev);
-   return dup_iotlb(mvdev, iotlb);
+   err = dup_iotlb(mvdev, iotlb);
+
+   spin_unlock(>cvq.iommu_lock);
+
+   return err;
 }
 
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 06/16] vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code

2023-10-18 Thread Dragos Tatulea via Virtualization
The handling of the cvq iotlb is currently coupled with the creation
and destruction of the hardware mkeys (mr).

This patch moves cvq iotlb handling into its own function and shifts it
to a scope that is not related to mr handling. As cvq handling is just a
prune_iotlb + dup_iotlb cycle, put it all in the same "update" function.
Finally, the destruction path is handled by directly pruning the iotlb.

After this move is done the ASID mr code can be collapsed into a single
function.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  3 ++
 drivers/vdpa/mlx5/core/mr.c| 57 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  7 ++--
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 3748f027cfe9..554899a80241 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,9 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid);
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 7bd0883b8b25..fcb6ae32e9ed 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,14 +489,6 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return;
-
-   prune_iotlb(mvdev);
-}
-
 static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
@@ -522,25 +514,14 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid)
mutex_lock(>mkey_mtx);
 
_mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]);
mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
-}
-
-static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return 0;
-
-   return dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev);
 }
 
 static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
@@ -572,22 +553,7 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb, unsigned int asid)
 {
-   int err;
-
-   err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-   if (err)
-   return err;
-
-   err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
-   if (err)
-   goto out_err;
-
-   return 0;
-
-out_err:
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-
-   return err;
+   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
 }
 
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
@@ -620,7 +586,24 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
return err;
 }
 
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
+{
+   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
+   return 0;
+
+   prune_iotlb(mvdev);
+   return dup_iotlb(mvdev, iotlb);
+}
+
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   int err;
+
+   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   if (err)
+   return err;
+
+   return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
 }
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 65b6a54ad344..aa4896662699 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2884,10 +2884,13 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
return err;
}
 
-   if 

[PATCH vhost v4 04/16] vhost-vdpa: uAPI to get dedicated descriptor group id

2023-10-18 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

With _F_DESC_ASID backend feature, the device can now support the
VHOST_VDPA_GET_VRING_DESC_GROUP ioctl, and it may expose the descriptor
table (including avail and used ring) in a different group than the
buffers it contains. This new uAPI will fetch the group ID of the
descriptor table.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c   | 10 ++
 include/uapi/linux/vhost.h |  8 
 2 files changed, 18 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 2f21798a37ee..851535f57b95 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -613,6 +613,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, 
unsigned int cmd,
else if (copy_to_user(argp, , sizeof(s)))
return -EFAULT;
return 0;
+   case VHOST_VDPA_GET_VRING_DESC_GROUP:
+   if (!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
+   s.index = idx;
+   s.num = ops->get_vq_desc_group(vdpa, idx);
+   if (s.num >= vdpa->ngroups)
+   return -EIO;
+   else if (copy_to_user(argp, , sizeof(s)))
+   return -EFAULT;
+   return 0;
case VHOST_VDPA_SET_GROUP_ASID:
if (copy_from_user(, argp, sizeof(s)))
return -EFAULT;
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index f5c48b61ab62..649560c685f1 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -219,4 +219,12 @@
  */
 #define VHOST_VDPA_RESUME  _IO(VHOST_VIRTIO, 0x7E)
 
+/* Get the group for the descriptor table including driver & device areas
+ * of a virtqueue: read index, write group in num.
+ * The virtqueue index is stored in the index field of vhost_vring_state.
+ * The group ID of the descriptor table for this specific virtqueue
+ * is returned via num field of vhost_vring_state.
+ */
+#define VHOST_VDPA_GET_VRING_DESC_GROUP_IOWR(VHOST_VIRTIO, 0x7F,   
\
+ struct vhost_vring_state)
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 09/16] vdpa/mlx5: Rename mr destroy functions

2023-10-18 Thread Dragos Tatulea via Virtualization
Make mlx5_destroy_mr symmetric to mlx5_create_mr.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c|  6 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 12 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 554899a80241..e1e6e7aba50e 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -118,8 +118,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 bool *change_map, unsigned int asid);
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fde00497f4ad..00dcce190a1f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -507,7 +507,7 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -518,9 +518,9 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
mutex_unlock(>mkey_mtx);
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index aa4896662699..ab196c43694c 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2644,7 +2644,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
goto err_mr;
 
teardown_driver(ndev);
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
if (err)
goto err_mr;
@@ -2660,7 +2660,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 
 err_setup:
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
 err_mr:
return err;
 }
@@ -2797,7 +2797,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device 
*vdev, u8 status)
 err_driver:
unregister_link_notifier(ndev);
 err_setup:
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
 err_clear:
up_write(>reslock);
@@ -2824,7 +2824,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
unregister_link_notifier(ndev);
teardown_driver(ndev);
clear_vqs_ready(ndev);
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status = 0;
ndev->mvdev.suspended = false;
ndev->cur_num_vqs = 0;
@@ -2944,7 +2944,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev)
ndev = to_mlx5_vdpa_ndev(mvdev);
 
free_resources(ndev);
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
if (!is_zero_ether_addr(ndev->config.mac)) {
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
@@ -3474,7 +3474,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
 err_res2:
free_resources(ndev);
 err_mr:
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
 err_res:
mlx5_vdpa_free_resources(>mvdev);
 err_mpfs:
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 08/16] vdpa/mlx5: Collapse "dvq" mr add/delete functions

2023-10-18 Thread Dragos Tatulea via Virtualization
Now that the cvq code is out of mlx5_vdpa_create/destroy_mr, the "dvq"
functions can be folded into their callers.

Having "dvq" in the naming will no longer be accurate in the downstream
patches.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 587300e7c18e..fde00497f4ad 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,7 +489,7 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -513,7 +513,7 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
 
mutex_lock(>mkey_mtx);
 
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
+   _mlx5_vdpa_destroy_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
@@ -524,9 +524,9 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
prune_iotlb(mvdev);
 }
 
-static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
+static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
int err;
@@ -550,12 +550,6 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 }
 
-static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb, unsigned int asid)
-{
-   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-}
-
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid)
 {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 03/16] vhost-vdpa: introduce descriptor group backend feature

2023-10-18 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

Userspace knows if the device has dedicated descriptor group or not
by checking this feature bit.

It's only exposed if the vdpa driver backend implements the
.get_vq_desc_group() operation callback. Userspace trying to negotiate
this feature when it or the dependent _F_IOTLB_ASID feature hasn't
been exposed will result in an error.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c | 17 +
 include/uapi/linux/vhost_types.h |  5 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 78379ffd2336..2f21798a37ee 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -389,6 +389,14 @@ static bool vhost_vdpa_can_resume(const struct vhost_vdpa 
*v)
return ops->resume;
 }
 
+static bool vhost_vdpa_has_desc_group(const struct vhost_vdpa *v)
+{
+   struct vdpa_device *vdpa = v->vdpa;
+   const struct vdpa_config_ops *ops = vdpa->config;
+
+   return ops->get_vq_desc_group;
+}
+
 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
 {
struct vdpa_device *vdpa = v->vdpa;
@@ -690,6 +698,7 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if (copy_from_user(, featurep, sizeof(features)))
return -EFAULT;
if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
+BIT_ULL(VHOST_BACKEND_F_DESC_ASID) |
 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
 BIT_ULL(VHOST_BACKEND_F_RESUME) |
 
BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))
@@ -700,6 +709,12 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&
 !vhost_vdpa_can_resume(v))
return -EOPNOTSUPP;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+   !(features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)))
+   return -EINVAL;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
vhost_set_backend_features(>vdev, features);
return 0;
}
@@ -753,6 +768,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
if (vhost_vdpa_can_resume(v))
features |= BIT_ULL(VHOST_BACKEND_F_RESUME);
+   if (vhost_vdpa_has_desc_group(v))
+   features |= BIT_ULL(VHOST_BACKEND_F_DESC_ASID);
features |= vhost_vdpa_get_backend_features(v);
if (copy_to_user(featurep, , sizeof(features)))
r = -EFAULT;
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
index 2d827d22cd99..18ad6ae7ab5c 100644
--- a/include/uapi/linux/vhost_types.h
+++ b/include/uapi/linux/vhost_types.h
@@ -185,5 +185,10 @@ struct vhost_vdpa_iova_range {
  * DRIVER_OK
  */
 #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK  0x6
+/* Device may expose the virtqueue's descriptor area, driver area and
+ * device area to a different group for ASID binding than where its
+ * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID.
+ */
+#define VHOST_BACKEND_F_DESC_ASID0x7
 
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 05/16] vdpa/mlx5: Create helper function for dma mappings

2023-10-18 Thread Dragos Tatulea via Virtualization
Necessary for upcoming cvq separation from mr allocation.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 1 +
 drivers/vdpa/mlx5/core/mr.c| 5 +
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 4 ++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ca56242972b3..3748f027cfe9 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,7 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, 
__func__, __LINE__, \
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 5a1971fcd87b..7bd0883b8b25 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -619,3 +619,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 
return err;
 }
+
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
+{
+   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+}
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 40a03b08d7cf..65b6a54ad344 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2836,7 +2836,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
++mvdev->generation;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   if (mlx5_vdpa_create_mr(mvdev, NULL, 0))
+   if (mlx5_vdpa_create_dma_mr(mvdev))
mlx5_vdpa_warn(mvdev, "create MR failed\n");
}
up_write(>reslock);
@@ -3441,7 +3441,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
goto err_mpfs;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   err = mlx5_vdpa_create_dma_mr(mvdev);
if (err)
goto err_res;
}
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v4 02/16] vdpa: introduce dedicated descriptor group for virtqueue

2023-10-18 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

In some cases, the access to the virtqueue's descriptor area, device
and driver areas (precluding indirect descriptor table in guest memory)
may have to be confined to a different address space than where its
buffers reside. Without loss of simplicity and generality with already
established terminology, let's fold up these 3 areas and call them
as a whole as descriptor table group, or descriptor group for short.
Specifically, in case of split virtqueues, descriptor group consists of
regions for Descriptor Table, Available Ring and Used Ring; for packed
virtqueues layout, descriptor group contains Descriptor Ring, Driver
and Device Event Suppression structures.

The group ID for a dedicated descriptor group can be obtained through a
new .get_vq_desc_group() op. If driver implements this op, it means that
the descriptor, device and driver areas of the virtqueue may reside
in a dedicated group than where its buffers reside, a.k.a the default
virtqueue group through the .get_vq_group() op.

In principle, the descriptor group may or may not have same group ID
as the default group. Even if the descriptor group has a different ID,
meaning the vq's descriptor group areas can optionally move to a
separate address space than where guest memory resides, the descriptor
group may still start from a default address space, same as where its
buffers reside. To move the descriptor group to a different address
space, .set_group_asid() has to be called to change the ASID binding
for the group, which is no different than what needs to be done on any
other virtqueue group. On the other hand, the .reset() semantics also
applies on descriptor table group, meaning the device reset will clear
all ASID bindings and move all virtqueue groups including descriptor
group back to the default address space, i.e. in ASID 0.

QEMU's shadow virtqueue is going to utilize dedicated descriptor group
to speed up map and unmap operations, yielding tremendous downtime
reduction by avoiding the full and slow remap cycle in SVQ switching.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 include/linux/vdpa.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index 0e652026b776..d376309b99cf 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -204,6 +204,16 @@ struct vdpa_map_file {
  * @vdev: vdpa device
  * @idx: virtqueue index
  * Returns u32: group id for this virtqueue
+ * @get_vq_desc_group: Get the group id for the descriptor table of
+ * a specific virtqueue (optional)
+ * @vdev: vdpa device
+ * @idx: virtqueue index
+ * Returns u32: group id for the descriptor table
+ * portion of this virtqueue. Could be different
+ * than the one from @get_vq_group, in which case
+ * the access to the descriptor table can be
+ * confined to a separate asid, isolating from
+ * the virtqueue's buffer address access.
  * @get_device_features:   Get virtio features supported by the device
  * @vdev: vdpa device
  * Returns the virtio features support by the
@@ -360,6 +370,7 @@ struct vdpa_config_ops {
/* Device ops */
u32 (*get_vq_align)(struct vdpa_device *vdev);
u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
+   u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
u64 (*get_device_features)(struct vdpa_device *vdev);
u64 (*get_backend_features)(const struct vdpa_device *vdev);
int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v4 01/16] vdpa/mlx5: Expose descriptor group mkey hw capability

2023-10-18 Thread Dragos Tatulea via Virtualization
Necessary for improved live migration flow. Actual support will be added
in a downstream patch.

Signed-off-by: Dragos Tatulea 
Reviewed-by: Gal Pressman 
---
 include/linux/mlx5/mlx5_ifc.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index b23d8ff286a1..6b6be1a0d575 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1231,7 +1231,13 @@ struct mlx5_ifc_virtio_emulation_cap_bits {
u8 max_emulated_devices[0x8];
u8 max_num_virtio_queues[0x18];
 
-   u8 reserved_at_a0[0x60];
+   u8 reserved_at_a0[0x20];
+
+   u8 reserved_at_c0[0x13];
+   u8 desc_group_mkey_supported[0x1];
+   u8 reserved_at_d4[0xc];
+
+   u8 reserved_at_e0[0x20];
 
u8 umem_1_buffer_param_a[0x20];
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v4 00/16] vdpa: Add support for vq descriptor mappings

2023-10-18 Thread Dragos Tatulea via Virtualization
This patch series adds support for vq descriptor table mappings which
are used to improve vdpa live migration downtime. The improvement comes
from using smaller mappings which take less time to create and destroy
in hw.

The first part adds the vdpa core changes from Si-Wei [0].

The second part adds support in mlx5_vdpa:
- Refactor the mr code to be able to cleanly add descriptor mappings.
- Add hardware descriptor mr support.
- Properly update iotlb for cvq during ASID switch.

Changes in v4:

- Improved the handling of empty iotlbs. See mlx5_vdpa_change_map
  section in patch "12/16 vdpa/mlx5: Improve mr upate flow".
- Fixed a invalid usage of desc_group_mkey hw vq field when the
  capability is not there. See patch
  "15/16 vdpa/mlx5: Enable hw support for vq descriptor map".

Changes in v3:

- dup_iotlb now checks for src == dst case and returns an error.
- Renamed iotlb parameter in dup_iotlb to dst.
- Removed a redundant check of the asid value.
- Fixed a commit message.
- mx5_ifc.h patch has been applied to mlx5-vhost tree. When applying
  this series please pull from that tree first.

Changes in v2:

- The "vdpa/mlx5: Enable hw support for vq descriptor mapping" change
  was split off into two patches to avoid merge conflicts into the tree
  of Linus.

  The first patch contains only changes for mlx5_ifc.h. This must be
  applied into the mlx5-vdpa tree [1] first. Once this patch is applied
  on mlx5-vdpa, the change has to be pulled fom mlx5-vdpa into the vhost
  tree and only then the remaining patches can be applied.

[0] 
https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-vhost

Dragos Tatulea (13):
  vdpa/mlx5: Expose descriptor group mkey hw capability
  vdpa/mlx5: Create helper function for dma mappings
  vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
  vdpa/mlx5: Take cvq iotlb lock during refresh
  vdpa/mlx5: Collapse "dvq" mr add/delete functions
  vdpa/mlx5: Rename mr destroy functions
  vdpa/mlx5: Allow creation/deletion of any given mr struct
  vdpa/mlx5: Move mr mutex out of mr struct
  vdpa/mlx5: Improve mr update flow
  vdpa/mlx5: Introduce mr for vq descriptor
  vdpa/mlx5: Enable hw support for vq descriptor mapping
  vdpa/mlx5: Make iotlb helper functions more generic
  vdpa/mlx5: Update cvq iotlb mapping on ASID change

Si-Wei Liu (3):
  vdpa: introduce dedicated descriptor group for virtqueue
  vhost-vdpa: introduce descriptor group backend feature
  vhost-vdpa: uAPI to get dedicated descriptor group id

 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
 drivers/vdpa/mlx5/core/mr.c| 194 -
 drivers/vdpa/mlx5/core/resources.c |   6 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 105 +++-
 drivers/vhost/vdpa.c   |  27 
 include/linux/mlx5/mlx5_ifc.h  |   8 +-
 include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
 include/linux/vdpa.h   |  11 ++
 include/uapi/linux/vhost.h |   8 ++
 include/uapi/linux/vhost_types.h   |   5 +
 10 files changed, 272 insertions(+), 130 deletions(-)

-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v3 16/16] vdpa/mlx5: Update cvq iotlb mapping on ASID change

2023-10-09 Thread Dragos Tatulea via Virtualization
For the following sequence:
- cvq group is in ASID 0
- .set_map(1, cvq_iotlb)
- .set_group_asid(cvq_group, 1)

... the cvq mapping from ASID 0 will be used. This is not always correct
behaviour.

This patch adds support for the above mentioned flow by saving the iotlb
on each .set_map and updating the cvq iotlb with it on a cvq group change.

Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  2 ++
 drivers/vdpa/mlx5/core/mr.c| 26 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  9 -
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ae09296f4270..db988ced5a5d 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -32,6 +32,8 @@ struct mlx5_vdpa_mr {
unsigned long num_directs;
unsigned long num_klms;
 
+   struct vhost_iotlb *iotlb;
+
bool user_mr;
 };
 
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 4a3df865df40..66530e28f327 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -502,6 +502,8 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
+
+   vhost_iotlb_free(mr->iotlb);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
@@ -561,6 +563,30 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
else
err = create_dma_mr(mvdev, mr);
 
+   if (err)
+   return err;
+
+   mr->iotlb = vhost_iotlb_alloc(0, 0);
+   if (!mr->iotlb) {
+   err = -ENOMEM;
+   goto err_mr;
+   }
+
+   err = dup_iotlb(mr->iotlb, iotlb);
+   if (err)
+   goto err_iotlb;
+
+   return 0;
+
+err_iotlb:
+   vhost_iotlb_free(mr->iotlb);
+
+err_mr:
+   if (iotlb)
+   destroy_user_mr(mvdev, mr);
+   else
+   destroy_dma_mr(mvdev, mr);
+
return err;
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 2e0a3ce1c0cf..6abe02310f2b 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -3154,12 +3154,19 @@ static int mlx5_set_group_asid(struct vdpa_device 
*vdev, u32 group,
   unsigned int asid)
 {
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+   int err = 0;
 
if (group >= MLX5_VDPA_NUMVQ_GROUPS)
return -EINVAL;
 
mvdev->group2asid[group] = asid;
-   return 0;
+
+   mutex_lock(>mr_mtx);
+   if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid])
+   err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, 
asid);
+   mutex_unlock(>mr_mtx);
+
+   return err;
 }
 
 static const struct vdpa_config_ops mlx5_vdpa_ops = {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 15/16] vdpa/mlx5: Make iotlb helper functions more generic

2023-10-09 Thread Dragos Tatulea via Virtualization
They will be used in a follow-up patch.

For dup_iotlb, avoid the src == dst case. This is an error.

Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 3dee6d9bed6b..4a3df865df40 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -454,20 +454,23 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr)
mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
 }
 
-static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
+static int dup_iotlb(struct vhost_iotlb *dst, struct vhost_iotlb *src)
 {
struct vhost_iotlb_map *map;
u64 start = 0, last = ULLONG_MAX;
int err;
 
+   if (dst == src)
+   return -EINVAL;
+
if (!src) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, 
start, VHOST_ACCESS_RW);
+   err = vhost_iotlb_add_range(dst, start, last, start, 
VHOST_ACCESS_RW);
return err;
}
 
for (map = vhost_iotlb_itree_first(src, start, last); map;
map = vhost_iotlb_itree_next(map, start, last)) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, 
map->last,
+   err = vhost_iotlb_add_range(dst, map->start, map->last,
map->addr, map->perm);
if (err)
return err;
@@ -475,9 +478,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *src)
return 0;
 }
 
-static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
+static void prune_iotlb(struct vhost_iotlb *iotlb)
 {
-   vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
+   vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
 }
 
 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr 
*mr)
@@ -544,7 +547,7 @@ void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev 
*mvdev)
for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
 
-   prune_iotlb(mvdev);
+   prune_iotlb(mvdev->cvq.iotlb);
 }
 
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
@@ -596,8 +599,8 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
 
spin_lock(>cvq.iommu_lock);
 
-   prune_iotlb(mvdev);
-   err = dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev->cvq.iotlb);
+   err = dup_iotlb(mvdev->cvq.iotlb, iotlb);
 
spin_unlock(>cvq.iommu_lock);
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 14/16] vdpa/mlx5: Enable hw support for vq descriptor mapping

2023-10-09 Thread Dragos Tatulea via Virtualization
Vq descriptor mappings are supported in hardware by filling in an
additional mkey which contains the descriptor mappings to the hw vq.

A previous patch in this series added support for hw mkey (mr) creation
for ASID 1.

This patch fills in both the vq data and vq descriptor mkeys based on
group ASID mapping.

The feature is signaled to the vdpa core through the presence of the
.get_vq_desc_group op.

Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 24 +++-
 include/linux/mlx5/mlx5_ifc_vdpa.h |  7 ++-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 25bd2c324f5b..2e0a3ce1c0cf 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -823,6 +823,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
struct mlx5_vdpa_dev *mvdev = >mvdev;
struct mlx5_vdpa_mr *vq_mr;
+   struct mlx5_vdpa_mr *vq_desc_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -878,6 +879,11 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
if (vq_mr)
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
+
+   vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
+   if (vq_desc_mr)
+   MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey);
+
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2265,6 +2271,16 @@ static u32 mlx5_vdpa_get_vq_group(struct vdpa_device 
*vdev, u16 idx)
return MLX5_VDPA_DATAVQ_GROUP;
 }
 
+static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
+{
+   struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+
+   if (is_ctrl_vq_idx(mvdev, idx))
+   return MLX5_VDPA_CVQ_GROUP;
+
+   return MLX5_VDPA_DATAVQ_DESC_GROUP;
+}
+
 static u64 mlx_to_vritio_features(u16 dev_features)
 {
u64 result = 0;
@@ -3160,6 +3176,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
.get_vq_irq = mlx5_get_vq_irq,
.get_vq_align = mlx5_vdpa_get_vq_align,
.get_vq_group = mlx5_vdpa_get_vq_group,
+   .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not 
supported. */
.get_device_features = mlx5_vdpa_get_device_features,
.set_driver_features = mlx5_vdpa_set_driver_features,
.get_driver_features = mlx5_vdpa_get_driver_features,
@@ -3258,6 +3275,7 @@ struct mlx5_vdpa_mgmtdev {
struct vdpa_mgmt_dev mgtdev;
struct mlx5_adev *madev;
struct mlx5_vdpa_net *ndev;
+   struct vdpa_config_ops vdpa_ops;
 };
 
 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
@@ -3371,7 +3389,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
max_vqs = 2;
}
 
-   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, _vdpa_ops,
+   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, >vdpa_ops,
 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, 
name, false);
if (IS_ERR(ndev))
return PTR_ERR(ndev);
@@ -3546,6 +3564,10 @@ static int mlx5v_probe(struct auxiliary_device *adev,
MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
mgtdev->mgtdev.supported_features = get_supported_features(mdev);
mgtdev->madev = madev;
+   mgtdev->vdpa_ops = mlx5_vdpa_ops;
+
+   if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported))
+   mgtdev->vdpa_ops.get_vq_desc_group = NULL;
 
err = vdpa_mgmtdev_register(>mgtdev);
if (err)
diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h 
b/include/linux/mlx5/mlx5_ifc_vdpa.h
index 9becdc3fa503..b86d51a855f6 100644
--- a/include/linux/mlx5/mlx5_ifc_vdpa.h
+++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
@@ -74,7 +74,11 @@ struct mlx5_ifc_virtio_q_bits {
u8reserved_at_320[0x8];
u8pd[0x18];
 
-   u8reserved_at_340[0xc0];
+   u8reserved_at_340[0x20];
+
+   u8desc_group_mkey[0x20];
+
+   u8reserved_at_380[0x80];
 };
 
 struct mlx5_ifc_virtio_net_q_object_bits {
@@ -141,6 +145,7 @@ enum {
MLX5_VIRTQ_MODIFY_MASK_STATE= (u64)1 << 0,
MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_PARAMS  = (u64)1 << 3,
MLX5_VIRTQ_MODIFY_MASK_DIRTY_BITMAP_DUMP_ENABLE = (u64)1 << 4,
+   MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY  = (u64)1 << 14,
 };
 
 enum {
-- 
2.41.0

___
Virtualization 

[PATCH vhost v3 13/16] vdpa/mlx5: Introduce mr for vq descriptor

2023-10-09 Thread Dragos Tatulea via Virtualization
Introduce the vq descriptor group and mr per ASID. Until now
.set_map on ASID 1 was only updating the cvq iotlb. From now on it also
creates a mkey for it. The current patch doesn't use it but follow-up
patches will add hardware support for mapping the vq descriptors.

Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  5 +++--
 drivers/vdpa/mlx5/core/mr.c| 14 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 20 +---
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index bbe4335106bd..ae09296f4270 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -70,11 +70,12 @@ struct mlx5_vdpa_wq_ent {
 enum {
MLX5_VDPA_DATAVQ_GROUP,
MLX5_VDPA_CVQ_GROUP,
+   MLX5_VDPA_DATAVQ_DESC_GROUP,
MLX5_VDPA_NUMVQ_GROUPS
 };
 
 enum {
-   MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
+   MLX5_VDPA_NUM_AS = 2
 };
 
 struct mlx5_vdpa_dev {
@@ -89,7 +90,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr *mr;
+   struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS];
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00eff5a07152..3dee6d9bed6b 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -511,8 +511,10 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   if (mvdev->mr == mr)
-   mvdev->mr = NULL;
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
+   if (mvdev->mr[i] == mr)
+   mvdev->mr[i] = NULL;
+   }
 
mutex_unlock(>mr_mtx);
 
@@ -523,11 +525,11 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 struct mlx5_vdpa_mr *new_mr,
 unsigned int asid)
 {
-   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
 
mutex_lock(>mr_mtx);
 
-   mvdev->mr = new_mr;
+   mvdev->mr[asid] = new_mr;
if (old_mr) {
_mlx5_vdpa_destroy_mr(mvdev, old_mr);
kfree(old_mr);
@@ -539,7 +541,9 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
+
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 4a87f9119fca..25bd2c324f5b 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -821,6 +821,8 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
 {
int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
+   struct mlx5_vdpa_dev *mvdev = >mvdev;
+   struct mlx5_vdpa_mr *vq_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -873,7 +875,9 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
-   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
+   vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
+   if (vq_mr)
+   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2633,7 +2637,8 @@ static void restore_channels_info(struct mlx5_vdpa_net 
*ndev)
 }
 
 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *new_mr, unsigned int asid)
+   struct mlx5_vdpa_mr *new_mr,
+   unsigned int asid)
 {
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
int err;
@@ -2652,8 +2657,10 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
 
restore_channels_info(ndev);
err = setup_driver(mvdev);
+   if (err)
+   return err;
 
-   return err;
+   return 0;
 }
 
 /* reslock must be held for this function */
@@ -2869,8 +2876,8 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
struct mlx5_vdpa_mr *new_mr;
int err;
 
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   goto end;
+  

[PATCH vhost v3 12/16] vdpa/mlx5: Improve mr update flow

2023-10-09 Thread Dragos Tatulea via Virtualization
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.

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 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 14 +++--
 drivers/vdpa/mlx5/core/mr.c| 87 --
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 46 
 3 files changed, 76 insertions(+), 71 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 9c6ac42c21e1..bbe4335106bd 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
struct list_head head;
unsigned long num_directs;
unsigned long num_klms;
-   /* state of dvq mr */
-   bool initialized;
 
bool user_mr;
 };
@@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr mr;
+   struct mlx5_vdpa_mr *mr;
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
@@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev 
*mvdev);
 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
  int inlen);
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
-int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
-bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb);
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr);
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *mr,
+unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index abd6a6fb122f..00eff5a07152 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
 
 static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   if (!mr->initialized)
-   return;
-
if (mr->user_mr)
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
-
-   mr->initialized = false;
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
+   if (!mr)
+   return;
+
mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
+   if (mvdev->mr == mr)
+   mvdev->mr = NULL;
+
+   mutex_unlock(>mr_mtx);
+
+   kfree(mr);
+}
+
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *new_mr,
+unsigned int asid)
+{
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+
+   mutex_lock(>mr_mtx);
+
+   mvdev->mr = new_mr;
+   if (old_mr) {
+   _mlx5_vdpa_destroy_mr(mvdev, old_mr);
+   kfree(old_mr);
+   }
+
mutex_unlock(>mr_mtx);
+
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, >mr);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
prune_iotlb(mvdev);
 }
 
@@ -528,52 +549,36 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
 {
int err;
 
-   if (mr->initialized)
-   return 0;
-
if (iotlb)
err = create_user_mr(mvdev, mr, iotlb);
else
err = create_dma_mr(mvdev, mr);
 
-   if (err)
-   return err;
-
-   mr->initialized = true;
-
-   return 0;
+   return err;
 }
 
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb)
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb)
 {
+   struct 

[PATCH vhost v3 10/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-10-09 Thread Dragos Tatulea via Virtualization
This patch adapts the mr creation/deletion code to be able to work with
any given mr struct pointer. All the APIs are adapted to take an extra
parameter for the mr.

mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
check is done in the caller instead (mlx5_set_map).

This change is needed for a followup patch which will introduce an
additional mr for the vq descriptor data.

Signed-off-by: Dragos Tatulea 
Acked-by: Eugenio Pérez 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  8 +++--
 drivers/vdpa/mlx5/core/mr.c| 53 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 10 --
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index e1e6e7aba50e..01d4ee58ccb1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -116,10 +116,12 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, 
u32 *mkey, u32 *in,
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
 int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
 bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
-   unsigned int asid);
+int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00dcce190a1f..6f29e8eaabb1 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -301,10 +301,13 @@ static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_direct
sg_free_table(>sg_head);
 }
 
-static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, 
u8 perm,
+static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   u64 start,
+   u64 size,
+   u8 perm,
struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
LIST_HEAD(tmp);
@@ -354,9 +357,10 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, 
u64 start, u64 size, u8
  * indirect memory key that provides access to the enitre address space given
  * by iotlb.
  */
-static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb)
+static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr,
+ struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
struct vhost_iotlb_map *map;
@@ -384,7 +388,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
   
LOG_MAX_KLM_SIZE);
mr->num_klms += nnuls;
}
-   err = add_direct_chain(mvdev, ps, pe - ps, 
pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, 
pperm, iotlb);
if (err)
goto err_chain;
}
@@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
pperm = map->perm;
}
}
-   err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
if (err)
goto err_chain;
 
@@ -489,13 +493,8 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
-
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   return;
-
if (!mr->initialized)
return;
 
@@ -507,38 +506,33 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned 

[PATCH vhost v3 11/16] vdpa/mlx5: Move mr mutex out of mr struct

2023-10-09 Thread Dragos Tatulea via Virtualization
The mutex is named like it is supposed to protect only the mkey but in
reality it is a global lock for all mr resources.

Shift the mutex to it's rightful location (struct mlx5_vdpa_dev) and
give it a more appropriate name.

Signed-off-by: Dragos Tatulea 
Acked-by: Eugenio Pérez 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c| 13 +++--
 drivers/vdpa/mlx5/core/resources.c |  6 +++---
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 01d4ee58ccb1..9c6ac42c21e1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -34,8 +34,6 @@ struct mlx5_vdpa_mr {
/* state of dvq mr */
bool initialized;
 
-   /* serialize mkey creation and destruction */
-   struct mutex mkey_mtx;
bool user_mr;
 };
 
@@ -94,6 +92,8 @@ struct mlx5_vdpa_dev {
u32 generation;
 
struct mlx5_vdpa_mr mr;
+   /* serialize mr access */
+   struct mutex mr_mtx;
struct mlx5_control_vq cvq;
struct workqueue_struct *wq;
unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 6f29e8eaabb1..abd6a6fb122f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -509,11 +509,11 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
@@ -550,9 +550,10 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
 {
int err;
 
-   mutex_lock(>mr.mkey_mtx);
+   mutex_lock(>mr_mtx);
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mr.mkey_mtx);
+   mutex_unlock(>mr_mtx);
+
return err;
 }
 
@@ -563,14 +564,14 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
int err = 0;
 
*change_map = false;
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
if (mr->initialized) {
mlx5_vdpa_info(mvdev, "memory map update\n");
*change_map = true;
}
if (!*change_map)
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 
return err;
 }
diff --git a/drivers/vdpa/mlx5/core/resources.c 
b/drivers/vdpa/mlx5/core/resources.c
index d5a59c9035fb..5c5a41b64bfc 100644
--- a/drivers/vdpa/mlx5/core/resources.c
+++ b/drivers/vdpa/mlx5/core/resources.c
@@ -256,7 +256,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
mlx5_vdpa_warn(mvdev, "resources already allocated\n");
return -EINVAL;
}
-   mutex_init(>mr.mkey_mtx);
+   mutex_init(>mr_mtx);
res->uar = mlx5_get_uars_page(mdev);
if (IS_ERR(res->uar)) {
err = PTR_ERR(res->uar);
@@ -301,7 +301,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
 err_uctx:
mlx5_put_uars_page(mdev, res->uar);
 err_uars:
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
return err;
 }
 
@@ -318,6 +318,6 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev)
dealloc_pd(mvdev, res->pdn, res->uid);
destroy_uctx(mvdev, res->uid);
mlx5_put_uars_page(mvdev->mdev, res->uar);
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
res->valid = false;
 }
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 09/16] vdpa/mlx5: Rename mr destroy functions

2023-10-09 Thread Dragos Tatulea via Virtualization
Make mlx5_destroy_mr symmetric to mlx5_create_mr.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c|  6 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 12 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 554899a80241..e1e6e7aba50e 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -118,8 +118,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 bool *change_map, unsigned int asid);
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fde00497f4ad..00dcce190a1f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -507,7 +507,7 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -518,9 +518,9 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
mutex_unlock(>mkey_mtx);
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index aa4896662699..ab196c43694c 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2644,7 +2644,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
goto err_mr;
 
teardown_driver(ndev);
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
if (err)
goto err_mr;
@@ -2660,7 +2660,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 
 err_setup:
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
 err_mr:
return err;
 }
@@ -2797,7 +2797,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device 
*vdev, u8 status)
 err_driver:
unregister_link_notifier(ndev);
 err_setup:
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
 err_clear:
up_write(>reslock);
@@ -2824,7 +2824,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
unregister_link_notifier(ndev);
teardown_driver(ndev);
clear_vqs_ready(ndev);
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status = 0;
ndev->mvdev.suspended = false;
ndev->cur_num_vqs = 0;
@@ -2944,7 +2944,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev)
ndev = to_mlx5_vdpa_ndev(mvdev);
 
free_resources(ndev);
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
if (!is_zero_ether_addr(ndev->config.mac)) {
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
@@ -3474,7 +3474,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
 err_res2:
free_resources(ndev);
 err_mr:
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
 err_res:
mlx5_vdpa_free_resources(>mvdev);
 err_mpfs:
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 08/16] vdpa/mlx5: Collapse "dvq" mr add/delete functions

2023-10-09 Thread Dragos Tatulea via Virtualization
Now that the cvq code is out of mlx5_vdpa_create/destroy_mr, the "dvq"
functions can be folded into their callers.

Having "dvq" in the naming will no longer be accurate in the downstream
patches.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 587300e7c18e..fde00497f4ad 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,7 +489,7 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -513,7 +513,7 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
 
mutex_lock(>mkey_mtx);
 
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
+   _mlx5_vdpa_destroy_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
@@ -524,9 +524,9 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
prune_iotlb(mvdev);
 }
 
-static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
+static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
int err;
@@ -550,12 +550,6 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 }
 
-static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb, unsigned int asid)
-{
-   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-}
-
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid)
 {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 05/16] vdpa/mlx5: Create helper function for dma mappings

2023-10-09 Thread Dragos Tatulea via Virtualization
Necessary for upcoming cvq separation from mr allocation.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 1 +
 drivers/vdpa/mlx5/core/mr.c| 5 +
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 4 ++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ca56242972b3..3748f027cfe9 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,7 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, 
__func__, __LINE__, \
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 5a1971fcd87b..7bd0883b8b25 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -619,3 +619,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 
return err;
 }
+
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
+{
+   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+}
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 40a03b08d7cf..65b6a54ad344 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2836,7 +2836,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
++mvdev->generation;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   if (mlx5_vdpa_create_mr(mvdev, NULL, 0))
+   if (mlx5_vdpa_create_dma_mr(mvdev))
mlx5_vdpa_warn(mvdev, "create MR failed\n");
}
up_write(>reslock);
@@ -3441,7 +3441,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
goto err_mpfs;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   err = mlx5_vdpa_create_dma_mr(mvdev);
if (err)
goto err_res;
}
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v3 06/16] vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code

2023-10-09 Thread Dragos Tatulea via Virtualization
The handling of the cvq iotlb is currently coupled with the creation
and destruction of the hardware mkeys (mr).

This patch moves cvq iotlb handling into its own function and shifts it
to a scope that is not related to mr handling. As cvq handling is just a
prune_iotlb + dup_iotlb cycle, put it all in the same "update" function.
Finally, the destruction path is handled by directly pruning the iotlb.

After this move is done the ASID mr code can be collapsed into a single
function.

Acked-by: Jason Wang 
Acked-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  3 ++
 drivers/vdpa/mlx5/core/mr.c| 57 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  7 ++--
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 3748f027cfe9..554899a80241 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,9 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid);
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 7bd0883b8b25..fcb6ae32e9ed 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,14 +489,6 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return;
-
-   prune_iotlb(mvdev);
-}
-
 static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
@@ -522,25 +514,14 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid)
mutex_lock(>mkey_mtx);
 
_mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]);
mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
-}
-
-static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return 0;
-
-   return dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev);
 }
 
 static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
@@ -572,22 +553,7 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb, unsigned int asid)
 {
-   int err;
-
-   err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-   if (err)
-   return err;
-
-   err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
-   if (err)
-   goto out_err;
-
-   return 0;
-
-out_err:
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-
-   return err;
+   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
 }
 
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
@@ -620,7 +586,24 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
return err;
 }
 
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
+{
+   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
+   return 0;
+
+   prune_iotlb(mvdev);
+   return dup_iotlb(mvdev, iotlb);
+}
+
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   int err;
+
+   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   if (err)
+   return err;
+
+   return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
 }
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 65b6a54ad344..aa4896662699 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2884,10 +2884,13 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
return err;
}
 
-   if 

[PATCH vhost v3 07/16] vdpa/mlx5: Take cvq iotlb lock during refresh

2023-10-09 Thread Dragos Tatulea via Virtualization
The reslock is taken while refresh is called but iommu_lock is more
specific to this resource. So take the iommu_lock during cvq iotlb
refresh.

Based on Eugenio's patch [0].

[0] https://lore.kernel.org/lkml/20230112142218.725622-4-epere...@redhat.com/

Acked-by: Jason Wang 
Suggested-by: Eugenio Pérez 
Reviewed-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fcb6ae32e9ed..587300e7c18e 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -590,11 +590,19 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev 
*mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid)
 {
+   int err;
+
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
return 0;
 
+   spin_lock(>cvq.iommu_lock);
+
prune_iotlb(mvdev);
-   return dup_iotlb(mvdev, iotlb);
+   err = dup_iotlb(mvdev, iotlb);
+
+   spin_unlock(>cvq.iommu_lock);
+
+   return err;
 }
 
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 04/16] vhost-vdpa: uAPI to get dedicated descriptor group id

2023-10-09 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

With _F_DESC_ASID backend feature, the device can now support the
VHOST_VDPA_GET_VRING_DESC_GROUP ioctl, and it may expose the descriptor
table (including avail and used ring) in a different group than the
buffers it contains. This new uAPI will fetch the group ID of the
descriptor table.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c   | 10 ++
 include/uapi/linux/vhost.h |  8 
 2 files changed, 18 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 2f21798a37ee..851535f57b95 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -613,6 +613,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, 
unsigned int cmd,
else if (copy_to_user(argp, , sizeof(s)))
return -EFAULT;
return 0;
+   case VHOST_VDPA_GET_VRING_DESC_GROUP:
+   if (!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
+   s.index = idx;
+   s.num = ops->get_vq_desc_group(vdpa, idx);
+   if (s.num >= vdpa->ngroups)
+   return -EIO;
+   else if (copy_to_user(argp, , sizeof(s)))
+   return -EFAULT;
+   return 0;
case VHOST_VDPA_SET_GROUP_ASID:
if (copy_from_user(, argp, sizeof(s)))
return -EFAULT;
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index f5c48b61ab62..649560c685f1 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -219,4 +219,12 @@
  */
 #define VHOST_VDPA_RESUME  _IO(VHOST_VIRTIO, 0x7E)
 
+/* Get the group for the descriptor table including driver & device areas
+ * of a virtqueue: read index, write group in num.
+ * The virtqueue index is stored in the index field of vhost_vring_state.
+ * The group ID of the descriptor table for this specific virtqueue
+ * is returned via num field of vhost_vring_state.
+ */
+#define VHOST_VDPA_GET_VRING_DESC_GROUP_IOWR(VHOST_VIRTIO, 0x7F,   
\
+ struct vhost_vring_state)
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 02/16] vdpa: introduce dedicated descriptor group for virtqueue

2023-10-09 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

In some cases, the access to the virtqueue's descriptor area, device
and driver areas (precluding indirect descriptor table in guest memory)
may have to be confined to a different address space than where its
buffers reside. Without loss of simplicity and generality with already
established terminology, let's fold up these 3 areas and call them
as a whole as descriptor table group, or descriptor group for short.
Specifically, in case of split virtqueues, descriptor group consists of
regions for Descriptor Table, Available Ring and Used Ring; for packed
virtqueues layout, descriptor group contains Descriptor Ring, Driver
and Device Event Suppression structures.

The group ID for a dedicated descriptor group can be obtained through a
new .get_vq_desc_group() op. If driver implements this op, it means that
the descriptor, device and driver areas of the virtqueue may reside
in a dedicated group than where its buffers reside, a.k.a the default
virtqueue group through the .get_vq_group() op.

In principle, the descriptor group may or may not have same group ID
as the default group. Even if the descriptor group has a different ID,
meaning the vq's descriptor group areas can optionally move to a
separate address space than where guest memory resides, the descriptor
group may still start from a default address space, same as where its
buffers reside. To move the descriptor group to a different address
space, .set_group_asid() has to be called to change the ASID binding
for the group, which is no different than what needs to be done on any
other virtqueue group. On the other hand, the .reset() semantics also
applies on descriptor table group, meaning the device reset will clear
all ASID bindings and move all virtqueue groups including descriptor
group back to the default address space, i.e. in ASID 0.

QEMU's shadow virtqueue is going to utilize dedicated descriptor group
to speed up map and unmap operations, yielding tremendous downtime
reduction by avoiding the full and slow remap cycle in SVQ switching.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 include/linux/vdpa.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index 0e652026b776..d376309b99cf 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -204,6 +204,16 @@ struct vdpa_map_file {
  * @vdev: vdpa device
  * @idx: virtqueue index
  * Returns u32: group id for this virtqueue
+ * @get_vq_desc_group: Get the group id for the descriptor table of
+ * a specific virtqueue (optional)
+ * @vdev: vdpa device
+ * @idx: virtqueue index
+ * Returns u32: group id for the descriptor table
+ * portion of this virtqueue. Could be different
+ * than the one from @get_vq_group, in which case
+ * the access to the descriptor table can be
+ * confined to a separate asid, isolating from
+ * the virtqueue's buffer address access.
  * @get_device_features:   Get virtio features supported by the device
  * @vdev: vdpa device
  * Returns the virtio features support by the
@@ -360,6 +370,7 @@ struct vdpa_config_ops {
/* Device ops */
u32 (*get_vq_align)(struct vdpa_device *vdev);
u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
+   u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
u64 (*get_device_features)(struct vdpa_device *vdev);
u64 (*get_backend_features)(const struct vdpa_device *vdev);
int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost v3 03/16] vhost-vdpa: introduce descriptor group backend feature

2023-10-09 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

Userspace knows if the device has dedicated descriptor group or not
by checking this feature bit.

It's only exposed if the vdpa driver backend implements the
.get_vq_desc_group() operation callback. Userspace trying to negotiate
this feature when it or the dependent _F_IOTLB_ASID feature hasn't
been exposed will result in an error.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c | 17 +
 include/uapi/linux/vhost_types.h |  5 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 78379ffd2336..2f21798a37ee 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -389,6 +389,14 @@ static bool vhost_vdpa_can_resume(const struct vhost_vdpa 
*v)
return ops->resume;
 }
 
+static bool vhost_vdpa_has_desc_group(const struct vhost_vdpa *v)
+{
+   struct vdpa_device *vdpa = v->vdpa;
+   const struct vdpa_config_ops *ops = vdpa->config;
+
+   return ops->get_vq_desc_group;
+}
+
 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
 {
struct vdpa_device *vdpa = v->vdpa;
@@ -690,6 +698,7 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if (copy_from_user(, featurep, sizeof(features)))
return -EFAULT;
if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
+BIT_ULL(VHOST_BACKEND_F_DESC_ASID) |
 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
 BIT_ULL(VHOST_BACKEND_F_RESUME) |
 
BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))
@@ -700,6 +709,12 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&
 !vhost_vdpa_can_resume(v))
return -EOPNOTSUPP;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+   !(features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)))
+   return -EINVAL;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
vhost_set_backend_features(>vdev, features);
return 0;
}
@@ -753,6 +768,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
if (vhost_vdpa_can_resume(v))
features |= BIT_ULL(VHOST_BACKEND_F_RESUME);
+   if (vhost_vdpa_has_desc_group(v))
+   features |= BIT_ULL(VHOST_BACKEND_F_DESC_ASID);
features |= vhost_vdpa_get_backend_features(v);
if (copy_to_user(featurep, , sizeof(features)))
r = -EFAULT;
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
index 2d827d22cd99..18ad6ae7ab5c 100644
--- a/include/uapi/linux/vhost_types.h
+++ b/include/uapi/linux/vhost_types.h
@@ -185,5 +185,10 @@ struct vhost_vdpa_iova_range {
  * DRIVER_OK
  */
 #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK  0x6
+/* Device may expose the virtqueue's descriptor area, driver area and
+ * device area to a different group for ASID binding than where its
+ * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID.
+ */
+#define VHOST_BACKEND_F_DESC_ASID0x7
 
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH mlx5-vhost v3 01/16] vdpa/mlx5: Expose descriptor group mkey hw capability

2023-10-09 Thread Dragos Tatulea via Virtualization
Necessary for improved live migration flow. Actual support will be added
in a downstream patch.

Reviewed-by: Gal Pressman 
Signed-off-by: Dragos Tatulea 
---
 include/linux/mlx5/mlx5_ifc.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index dd8421d021cf..ec15330b970d 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1231,7 +1231,13 @@ struct mlx5_ifc_virtio_emulation_cap_bits {
u8 max_emulated_devices[0x8];
u8 max_num_virtio_queues[0x18];
 
-   u8 reserved_at_a0[0x60];
+   u8 reserved_at_a0[0x20];
+
+   u8 reserved_at_c0[0x13];
+   u8 desc_group_mkey_supported[0x1];
+   u8 reserved_at_d4[0xc];
+
+   u8 reserved_at_e0[0x20];
 
u8 umem_1_buffer_param_a[0x20];
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v3 00/16] vdpa: Add support for vq descriptor mappings

2023-10-09 Thread Dragos Tatulea via Virtualization
This patch series adds support for vq descriptor table mappings which
are used to improve vdpa live migration downtime. The improvement comes
from using smaller mappings which take less time to create and destroy
in hw.

The first part adds the vdpa core changes from Si-Wei [0].

The second part adds support in mlx5_vdpa:
- Refactor the mr code to be able to cleanly add descriptor mappings.
- Add hardware descriptor mr support.
- Properly update iotlb for cvq during ASID switch.

Changes in v3:

- dup_iotlb now checks for src == dst case and returns an error.
- Renamed iotlb parameter in dup_iotlb to dst.
- Removed a redundant check of the asid value.
- Fixed a commit message.
- mx5_ifc.h patch has been applied to mlx5-vhost tree. When applying
  this series please pull from that tree first.

Changes in v2:

- The "vdpa/mlx5: Enable hw support for vq descriptor mapping" change
  was split off into two patches to avoid merge conflicts into the tree
  of Linus.

  The first patch contains only changes for mlx5_ifc.h. This must be
  applied into the mlx5-vdpa tree [1] first. Once this patch is applied
  on mlx5-vdpa, the change has to be pulled fom mlx5-vdpa into the vhost
  tree and only then the remaining patches can be applied.

[0] 
https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-vhost

Dragos Tatulea (13):
  vdpa/mlx5: Expose descriptor group mkey hw capability
  vdpa/mlx5: Create helper function for dma mappings
  vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
  vdpa/mlx5: Take cvq iotlb lock during refresh
  vdpa/mlx5: Collapse "dvq" mr add/delete functions
  vdpa/mlx5: Rename mr destroy functions
  vdpa/mlx5: Allow creation/deletion of any given mr struct
  vdpa/mlx5: Move mr mutex out of mr struct
  vdpa/mlx5: Improve mr update flow
  vdpa/mlx5: Introduce mr for vq descriptor
  vdpa/mlx5: Enable hw support for vq descriptor mapping
  vdpa/mlx5: Make iotlb helper functions more generic
  vdpa/mlx5: Update cvq iotlb mapping on ASID change

Si-Wei Liu (3):
  vdpa: introduce dedicated descriptor group for virtqueue
  vhost-vdpa: introduce descriptor group backend feature
  vhost-vdpa: uAPI to get dedicated descriptor group id

 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
 drivers/vdpa/mlx5/core/mr.c| 194 -
 drivers/vdpa/mlx5/core/resources.c |   6 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  98 ++-
 drivers/vhost/vdpa.c   |  27 
 include/linux/mlx5/mlx5_ifc.h  |   8 +-
 include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
 include/linux/vdpa.h   |  11 ++
 include/uapi/linux/vhost.h |   8 ++
 include/uapi/linux/vhost_types.h   |   5 +
 10 files changed, 266 insertions(+), 129 deletions(-)

-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 09/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-10-09 Thread Dragos Tatulea via Virtualization
On Mon, 2023-10-09 at 14:39 +0800, Jason Wang wrote:
> On Sun, Oct 8, 2023 at 8:05 PM Dragos Tatulea  wrote:
> > 
> > On Sun, 2023-10-08 at 12:25 +0800, Jason Wang wrote:
> > > On Tue, Sep 26, 2023 at 3:21 PM Dragos Tatulea 
> > > wrote:
> > > > 
> > > > On Tue, 2023-09-26 at 12:44 +0800, Jason Wang wrote:
> > > > > On Tue, Sep 12, 2023 at 9:02 PM Dragos Tatulea 
> > > > > wrote:
> > > > > > 
> > > > > > This patch adapts the mr creation/deletion code to be able to work
> > > > > > with
> > > > > > any given mr struct pointer. All the APIs are adapted to take an
> > > > > > extra
> > > > > > parameter for the mr.
> > > > > > 
> > > > > > mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore.
> > > > > > The
> > > > > > check is done in the caller instead (mlx5_set_map).
> > > > > > 
> > > > > > This change is needed for a followup patch which will introduce an
> > > > > > additional mr for the vq descriptor data.
> > > > > > 
> > > > > > Signed-off-by: Dragos Tatulea 
> > > > > > ---
> > > > > 
> > > > > Thinking of this decoupling I think I have a question.
> > > > > 
> > > > > We advertise 2 address spaces and 2 groups. So we actually don't know
> > > > > for example which address spaces will be used by dvq.
> > > > > 
> > > > > And actually we allow the user space to do something like
> > > > > 
> > > > > set_group_asid(dvq_group, 0)
> > > > > set_map(0)
> > > > > set_group_asid(dvq_group, 1)
> > > > > set_map(1)
> > > > > 
> > > > > I wonder if the decoupling like this patch can work and why.
> > > > > 
> > > > This scenario could indeed work. Especially if you look at the 13'th
> > > > patch
> > > > [0]
> > > > where hw support is added. Are you wondering if this should work at all
> > > > or
> > > > if it
> > > > should be blocked?
> > > 
> > > It would be great if it can work with the following patches. But at
> > > least for this patch, it seems not:
> > > 
> > > For example, what happens if we switch back to group 0 for dvq?
> > > 
> > > set_group_asid(dvq_group, 0)
> > > set_map(0)
> > > set_group_asid(dvq_group, 1)
> > > set_map(1)
> > > // here we destroy the mr created for asid 0
> > > set_group_asid(dvq_group, 0)
> > > 
> > If by destroy you mean .reset,
> 
> It's not rest. During the second map, the mr is destroyed by
> mlx5_vdpa_change_map().
> 
Oh, now I understand what you mean. This is not the case anymore. This patch
series introduces one mr per asid. mlx5_vdpa_change_map will only destroy the
old mr in the given asid. Before, there was one mr for all asids.

>  I think it works: During .reset the mapping in
> > ASID 0 is reset back to the DMA/pysical map (mlx5_vdpa_create_dma_mr). Am I
> > missing something?
> > 
> > > Btw, if this is a new issue, I haven't checked whether or not it
> > > exists before this series (if yes, we can fix on top).
> > 
> > > > 
> > > > > It looks to me the most easy way is to let each AS be backed by an MR.
> > > > > Then we don't even need to care about the dvq, cvq.
> > > > That's what this patch series dowes.
> > > 
> > > Good to know this, I will review the series.
> > > 
> > I was planning to spin a v3 with Eugenio's suggestions. Should I wait for
> > your
> > feedback before doing that?
> 
> You can post v3 and we can move the discussion there if you wish.
> 
Ack.

Thanks,
Dragos
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH 09/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-10-08 Thread Dragos Tatulea via Virtualization
On Sun, 2023-10-08 at 12:25 +0800, Jason Wang wrote:
> On Tue, Sep 26, 2023 at 3:21 PM Dragos Tatulea  wrote:
> > 
> > On Tue, 2023-09-26 at 12:44 +0800, Jason Wang wrote:
> > > On Tue, Sep 12, 2023 at 9:02 PM Dragos Tatulea 
> > > wrote:
> > > > 
> > > > This patch adapts the mr creation/deletion code to be able to work with
> > > > any given mr struct pointer. All the APIs are adapted to take an extra
> > > > parameter for the mr.
> > > > 
> > > > mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
> > > > check is done in the caller instead (mlx5_set_map).
> > > > 
> > > > This change is needed for a followup patch which will introduce an
> > > > additional mr for the vq descriptor data.
> > > > 
> > > > Signed-off-by: Dragos Tatulea 
> > > > ---
> > > 
> > > Thinking of this decoupling I think I have a question.
> > > 
> > > We advertise 2 address spaces and 2 groups. So we actually don't know
> > > for example which address spaces will be used by dvq.
> > > 
> > > And actually we allow the user space to do something like
> > > 
> > > set_group_asid(dvq_group, 0)
> > > set_map(0)
> > > set_group_asid(dvq_group, 1)
> > > set_map(1)
> > > 
> > > I wonder if the decoupling like this patch can work and why.
> > > 
> > This scenario could indeed work. Especially if you look at the 13'th patch
> > [0]
> > where hw support is added. Are you wondering if this should work at all or
> > if it
> > should be blocked?
> 
> It would be great if it can work with the following patches. But at
> least for this patch, it seems not:
> 
> For example, what happens if we switch back to group 0 for dvq?
> 
> set_group_asid(dvq_group, 0)
> set_map(0)
> set_group_asid(dvq_group, 1)
> set_map(1)
> // here we destroy the mr created for asid 0
> set_group_asid(dvq_group, 0)
> 
If by destroy you mean .reset, I think it works: During .reset the mapping in
ASID 0 is reset back to the DMA/pysical map (mlx5_vdpa_create_dma_mr). Am I
missing something?

> Btw, if this is a new issue, I haven't checked whether or not it
> exists before this series (if yes, we can fix on top).

> > 
> > > It looks to me the most easy way is to let each AS be backed by an MR.
> > > Then we don't even need to care about the dvq, cvq.
> > That's what this patch series dowes.
> 
> Good to know this, I will review the series.
> 
I was planning to spin a v3 with Eugenio's suggestions. Should I wait for your
feedback before doing that?

Thanks,
Dragos
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH vhost v2 00/16] vdpa: Add support for vq descriptor mappings

2023-10-05 Thread Dragos Tatulea via Virtualization
On Thu, 2023-10-05 at 13:31 -0400, Michael S. Tsirkin wrote:
> On Thu, Sep 28, 2023 at 07:45:11PM +0300, Dragos Tatulea wrote:
> > This patch series adds support for vq descriptor table mappings which
> > are used to improve vdpa live migration downtime. The improvement comes
> > from using smaller mappings which take less time to create and destroy
> > in hw.
> > 
> > The first part adds the vdpa core changes from Si-Wei [0].
> > 
> > The second part adds support in mlx5_vdpa:
> > - Refactor the mr code to be able to cleanly add descriptor mappings.
> > - Add hardware descriptor mr support.
> > - Properly update iotlb for cvq during ASID switch.
> > 
> > Changes in v2:
> > 
> > - The "vdpa/mlx5: Enable hw support for vq descriptor mapping" change
> >   was split off into two patches to avoid merge conflicts into the tree
> >   of Linus.
> > 
> >   The first patch contains only changes for mlx5_ifc.h. This must be
> >   applied into the mlx5-next tree [1] first. Once this patch is applied
> >   on mlx5-next, the change has to be pulled fom mlx5-next into the vhost
> >   tree and only then the remaining patches can be applied.
> 
> 
> I get it you plan v3?
There are some very small improvements (commit message in 13/16 and fix in
16/16) that could make a v3. The latter can be addressed as a separate patch
when moving dup_iotlb to vhost/iotlb. What do you think?

> 
> > [0]
> > https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
> > [1]
> > https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-next
> > 
> > Dragos Tatulea (13):
> >   vdpa/mlx5: Expose descriptor group mkey hw capability
> >   vdpa/mlx5: Create helper function for dma mappings
> >   vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
> >   vdpa/mlx5: Take cvq iotlb lock during refresh
> >   vdpa/mlx5: Collapse "dvq" mr add/delete functions
> >   vdpa/mlx5: Rename mr destroy functions
> >   vdpa/mlx5: Allow creation/deletion of any given mr struct
> >   vdpa/mlx5: Move mr mutex out of mr struct
> >   vdpa/mlx5: Improve mr update flow
> >   vdpa/mlx5: Introduce mr for vq descriptor
> >   vdpa/mlx5: Enable hw support for vq descriptor mapping
> >   vdpa/mlx5: Make iotlb helper functions more generic
> >   vdpa/mlx5: Update cvq iotlb mapping on ASID change
> > 
> > Si-Wei Liu (3):
> >   vdpa: introduce dedicated descriptor group for virtqueue
> >   vhost-vdpa: introduce descriptor group backend feature
> >   vhost-vdpa: uAPI to get dedicated descriptor group id
> > 
> >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
> >  drivers/vdpa/mlx5/core/mr.c    | 191 -
> >  drivers/vdpa/mlx5/core/resources.c |   6 +-
> >  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 100 ++-
> >  drivers/vhost/vdpa.c   |  27 
> >  include/linux/mlx5/mlx5_ifc.h  |   8 +-
> >  include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
> >  include/linux/vdpa.h   |  11 ++
> >  include/uapi/linux/vhost.h |   8 ++
> >  include/uapi/linux/vhost_types.h   |   5 +
> >  10 files changed, 264 insertions(+), 130 deletions(-)
> > 
> > -- 
> > 2.41.0
> 

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH vhost 16/16] vdpa/mlx5: Update cvq iotlb mapping on ASID change

2023-10-05 Thread Dragos Tatulea via Virtualization
On Thu, 2023-10-05 at 12:41 +0200, Eugenio Perez Martin wrote:
> On Thu, Sep 28, 2023 at 6:50 PM Dragos Tatulea  wrote:
> > 
> > For the following sequence:
> > - cvq group is in ASID 0
> > - .set_map(1, cvq_iotlb)
> > - .set_group_asid(cvq_group, 1)
> > 
> > ... the cvq mapping from ASID 0 will be used. This is not always correct
> > behaviour.
> > 
> > This patch adds support for the above mentioned flow by saving the iotlb
> > on each .set_map and updating the cvq iotlb with it on a cvq group change.
> > 
> > Signed-off-by: Dragos Tatulea 
> > ---
> >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  2 ++
> >  drivers/vdpa/mlx5/core/mr.c    | 26 ++
> >  drivers/vdpa/mlx5/net/mlx5_vnet.c  |  9 -
> >  3 files changed, 36 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > index ae09296f4270..db988ced5a5d 100644
> > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > @@ -32,6 +32,8 @@ struct mlx5_vdpa_mr {
> >     unsigned long num_directs;
> >     unsigned long num_klms;
> > 
> > +   struct vhost_iotlb *iotlb;
> > +
> >     bool user_mr;
> >  };
> > 
> > diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> > index a4135c16b5bf..403c08271489 100644
> > --- a/drivers/vdpa/mlx5/core/mr.c
> > +++ b/drivers/vdpa/mlx5/core/mr.c
> > @@ -499,6 +499,8 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev
> > *mvdev, struct mlx5_vdpa_
> >     destroy_user_mr(mvdev, mr);
> >     else
> >     destroy_dma_mr(mvdev, mr);
> > +
> > +   vhost_iotlb_free(mr->iotlb);
> >  }
> > 
> >  void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
> > @@ -558,6 +560,30 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev
> > *mvdev,
> >     else
> >     err = create_dma_mr(mvdev, mr);
> > 
> > +   if (err)
> > +   return err;
> > +
> > +   mr->iotlb = vhost_iotlb_alloc(0, 0);
> > +   if (!mr->iotlb) {
> > +   err = -ENOMEM;
> > +   goto err_mr;
> > +   }
> > +
> > +   err = dup_iotlb(mr->iotlb, iotlb);
> > +   if (err)
> > +   goto err_iotlb;
> > +
> > +   return 0;
> > +
> > +err_iotlb:
> > +   vhost_iotlb_free(mr->iotlb);
> > +
> > +err_mr:
> > +   if (iotlb)
> > +   destroy_user_mr(mvdev, mr);
> > +   else
> > +   destroy_dma_mr(mvdev, mr);
> > +
> >     return err;
> >  }
> > 
> > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > index 46441e41892c..fc5d6b989a5a 100644
> > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > @@ -3154,12 +3154,19 @@ static int mlx5_set_group_asid(struct vdpa_device
> > *vdev, u32 group,
> >    unsigned int asid)
> >  {
> >     struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > +   int err = 0;
> > 
> >     if (group >= MLX5_VDPA_NUMVQ_GROUPS || asid >= MLX5_VDPA_NUM_AS)
> >     return -EINVAL;
> > 
> >     mvdev->group2asid[group] = asid;
> > -   return 0;
> > +
> > +   mutex_lock(>mr_mtx);
> > +   if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid])
> > +   err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]-
> > >iotlb, asid);
> 
> Do we need to protect here in case userspace sets the same ASID twice?
> mlx5_vdpa_update_cvq_iotlb shouldn't call dup_iotlb with the same src
> and dst.

Why would src and dst be identical? Doesn't dup_iotlb create a copy of src?

That being said, there should be a check in dup_iotlb for dst == src. Not sure
if this is an error or success though...

Thanks,
Dragos
- 
> Apart from that:
> 
> Acked-by: Eugenio Pérez 
> 
> > +   mutex_unlock(>mr_mtx);
> > +
> > +   return err;
> >  }
> > 
> >  static const struct vdpa_config_ops mlx5_vdpa_ops = {
> > --
> > 2.41.0
> > 
> 

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH vhost 15/16] vdpa/mlx5: Make iotlb helper functions more generic

2023-10-05 Thread Dragos Tatulea via Virtualization
On Thu, 2023-10-05 at 12:14 +0200, Eugenio Perez Martin wrote:
> On Thu, Sep 28, 2023 at 6:50 PM Dragos Tatulea  wrote:
> > 
> > They will be used in a followup patch.
> > 
> > Signed-off-by: Dragos Tatulea 
> > ---
> >  drivers/vdpa/mlx5/core/mr.c | 16 
> >  1 file changed, 8 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> > index 3dee6d9bed6b..a4135c16b5bf 100644
> > --- a/drivers/vdpa/mlx5/core/mr.c
> > +++ b/drivers/vdpa/mlx5/core/mr.c
> > @@ -454,20 +454,20 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev
> > *mvdev, struct mlx5_vdpa_mr *mr)
> >     mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
> >  }
> > 
> > -static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
> > +static int dup_iotlb(struct vhost_iotlb *iotlb, struct vhost_iotlb *src)
> 
> It would be great to move this patch to vhost/iotlb, especially
> because it can be reused by vdpa_sim. But it can be done on top for
> sure,
> 
Ack. Will create a separate patch for this after the series.

Thanks,
Dragos

> Acked-by: Eugenio Pérez 
> 
> >  {
> >     struct vhost_iotlb_map *map;
> >     u64 start = 0, last = ULLONG_MAX;
> >     int err;
> > 
> >     if (!src) {
> > -   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last,
> > start, VHOST_ACCESS_RW);
> > +   err = vhost_iotlb_add_range(iotlb, start, last, start,
> > VHOST_ACCESS_RW);
> >     return err;
> >     }
> > 
> >     for (map = vhost_iotlb_itree_first(src, start, last); map;
> >     map = vhost_iotlb_itree_next(map, start, last)) {
> > -   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start,
> > map->last,
> > +   err = vhost_iotlb_add_range(iotlb, map->start, map->last,
> >     map->addr, map->perm);
> >     if (err)
> >     return err;
> > @@ -475,9 +475,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct
> > vhost_iotlb *src)
> >     return 0;
> >  }
> > 
> > -static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
> > +static void prune_iotlb(struct vhost_iotlb *iotlb)
> >  {
> > -   vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
> > +   vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
> >  }
> > 
> >  static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct
> > mlx5_vdpa_mr *mr)
> > @@ -544,7 +544,7 @@ void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev
> > *mvdev)
> >     for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
> >     mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
> > 
> > -   prune_iotlb(mvdev);
> > +   prune_iotlb(mvdev->cvq.iotlb);
> >  }
> > 
> >  static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> > @@ -596,8 +596,8 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev
> > *mvdev,
> > 
> >     spin_lock(>cvq.iommu_lock);
> > 
> > -   prune_iotlb(mvdev);
> > -   err = dup_iotlb(mvdev, iotlb);
> > +   prune_iotlb(mvdev->cvq.iotlb);
> > +   err = dup_iotlb(mvdev->cvq.iotlb, iotlb);
> > 
> >     spin_unlock(>cvq.iommu_lock);
> > 
> > --
> > 2.41.0
> > 
> 

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH vhost 14/16] vdpa/mlx5: Enable hw support for vq descriptor mapping

2023-10-05 Thread Dragos Tatulea via Virtualization
On Thu, 2023-10-05 at 11:42 +0200, Eugenio Perez Martin wrote:
> On Thu, Sep 28, 2023 at 6:50 PM Dragos Tatulea  wrote:
> > 
> > Vq descriptor mappings are supported in hardware by filling in an
> > additional mkey which contains the descriptor mappings to the hw vq.
> > 
> > A previous patch in this series added support for hw mkey (mr) creation
> > for ASID 1.
> > 
> > This patch fills in both the vq data and vq descriptor mkeys based on
> > group ASID mapping.
> > 
> > The feature is signaled to the vdpa core through the presence of the
> > .get_vq_desc_group op.
> > 
> > Signed-off-by: Dragos Tatulea 
> > ---
> >  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 26 --
> >  include/linux/mlx5/mlx5_ifc_vdpa.h |  7 ++-
> >  2 files changed, 30 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > index 25bd2c324f5b..46441e41892c 100644
> > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > @@ -823,6 +823,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev,
> > struct mlx5_vdpa_virtque
> >     u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
> >     struct mlx5_vdpa_dev *mvdev = >mvdev;
> >     struct mlx5_vdpa_mr *vq_mr;
> > +   struct mlx5_vdpa_mr *vq_desc_mr;
> >     void *obj_context;
> >     u16 mlx_features;
> >     void *cmd_hdr;
> > @@ -878,6 +879,11 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev,
> > struct mlx5_vdpa_virtque
> >     vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
> >     if (vq_mr)
> >     MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
> > +
> > +   vq_desc_mr = mvdev->mr[mvdev-
> > >group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
> > +   if (vq_desc_mr)
> > +   MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr-
> > >mkey);
> > +
> >     MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
> >     MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
> >     MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
> > @@ -2265,6 +2271,16 @@ static u32 mlx5_vdpa_get_vq_group(struct vdpa_device
> > *vdev, u16 idx)
> >     return MLX5_VDPA_DATAVQ_GROUP;
> >  }
> > 
> > +static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
> > +{
> > +   struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > +
> > +   if (is_ctrl_vq_idx(mvdev, idx))
> > +   return MLX5_VDPA_CVQ_GROUP;
> > +
> > +   return MLX5_VDPA_DATAVQ_DESC_GROUP;
> > +}
> > +
> >  static u64 mlx_to_vritio_features(u16 dev_features)
> >  {
> >     u64 result = 0;
> > @@ -3139,7 +3155,7 @@ static int mlx5_set_group_asid(struct vdpa_device
> > *vdev, u32 group,
> >  {
> >     struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
> > 
> > -   if (group >= MLX5_VDPA_NUMVQ_GROUPS)
> > +   if (group >= MLX5_VDPA_NUMVQ_GROUPS || asid >= MLX5_VDPA_NUM_AS)
> 
> Nit: the check for asid >= MLX5_VDPA_NUM_AS is redundant, as it will
> be already checked by VHOST_VDPA_SET_GROUP_ASID handler in
> drivers/vhost/vdpa.c:vhost_vdpa_vring_ioctl. Not a big deal.
Ack.

> 
> >     return -EINVAL;
> > 
> >     mvdev->group2asid[group] = asid;
> > @@ -3160,6 +3176,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
> >     .get_vq_irq = mlx5_get_vq_irq,
> >     .get_vq_align = mlx5_vdpa_get_vq_align,
> >     .get_vq_group = mlx5_vdpa_get_vq_group,
> > +   .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if
> > not supported. */
> >     .get_device_features = mlx5_vdpa_get_device_features,
> >     .set_driver_features = mlx5_vdpa_set_driver_features,
> >     .get_driver_features = mlx5_vdpa_get_driver_features,
> > @@ -3258,6 +3275,7 @@ struct mlx5_vdpa_mgmtdev {
> >     struct vdpa_mgmt_dev mgtdev;
> >     struct mlx5_adev *madev;
> >     struct mlx5_vdpa_net *ndev;
> > +   struct vdpa_config_ops vdpa_ops;
> >  };
> > 
> >  static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
> > @@ -3371,7 +3389,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev
> > *v_mdev, const char *name,
> >     max_vqs = 2;
> >     }
> > 
> > -   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev-
> > >device, _vdpa_ops,
> > +   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev-
> > >device, >vdpa_ops,
> >  MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS,
> > name, false);
> >     if (IS_ERR(ndev))
> >     return PTR_ERR(ndev);
> > @@ -3546,6 +3564,10 @@ static int mlx5v_probe(struct auxiliary_device *adev,
> >     MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) +
> > 1;
> >     mgtdev->mgtdev.supported_features = get_supported_features(mdev);
> >     mgtdev->madev = madev;
> > +   mgtdev->vdpa_ops = mlx5_vdpa_ops;
> > +
> > +   if 

Re: [PATCH vhost 13/16] vdpa/mlx5: Introduce mr for vq descriptor

2023-10-05 Thread Dragos Tatulea via Virtualization
On Wed, 2023-10-04 at 20:53 +0200, Eugenio Perez Martin wrote:
> On Thu, Sep 28, 2023 at 6:50 PM Dragos Tatulea  wrote:
> > 
> > Introduce the vq descriptor group and ASID 1. Until now .set_map on ASID
> 
> s/ASID/vq group/?
> 
Oh, indeed.

> > 1 was only updating the cvq iotlb. From now on it also creates a mkey
> > for it. The current patch doesn't use it but follow-up patches will
> > add hardware support for mapping the vq descriptors.
> > 
> > Signed-off-by: Dragos Tatulea 
> > ---
> >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  5 +++--
> >  drivers/vdpa/mlx5/core/mr.c    | 14 +-
> >  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 20 +---
> >  3 files changed, 25 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > index bbe4335106bd..ae09296f4270 100644
> > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > @@ -70,11 +70,12 @@ struct mlx5_vdpa_wq_ent {
> >  enum {
> >     MLX5_VDPA_DATAVQ_GROUP,
> >     MLX5_VDPA_CVQ_GROUP,
> > +   MLX5_VDPA_DATAVQ_DESC_GROUP,
> >     MLX5_VDPA_NUMVQ_GROUPS
> >  };
> > 
> >  enum {
> > -   MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
> > +   MLX5_VDPA_NUM_AS = 2
> >  };
> > 
> >  struct mlx5_vdpa_dev {
> > @@ -89,7 +90,7 @@ struct mlx5_vdpa_dev {
> >     u16 max_idx;
> >     u32 generation;
> > 
> > -   struct mlx5_vdpa_mr *mr;
> > +   struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS];
> 
> I'm wondering if it makes sense to squash all of this patch with the
> previous one, as I think *mr[MLX5_VDPA_NUM_AS] makes way more sense
> than just *mr.
> 
I've been on the fence about this one. It seemed cleaner to have two patches.

> Whatever you choose, for both patches:
> 
> Acked-by: Eugenio Pérez 
> 
> >     /* serialize mr access */
> >     struct mutex mr_mtx;
> >     struct mlx5_control_vq cvq;
> > diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> > index 00eff5a07152..3dee6d9bed6b 100644
> > --- a/drivers/vdpa/mlx5/core/mr.c
> > +++ b/drivers/vdpa/mlx5/core/mr.c
> > @@ -511,8 +511,10 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
> > 
> >     _mlx5_vdpa_destroy_mr(mvdev, mr);
> > 
> > -   if (mvdev->mr == mr)
> > -   mvdev->mr = NULL;
> > +   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
> > +   if (mvdev->mr[i] == mr)
> > +   mvdev->mr[i] = NULL;
> > +   }
> > 
> >     mutex_unlock(>mr_mtx);
> > 
> > @@ -523,11 +525,11 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
> >  struct mlx5_vdpa_mr *new_mr,
> >  unsigned int asid)
> >  {
> > -   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
> > +   struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
> > 
> >     mutex_lock(>mr_mtx);
> > 
> > -   mvdev->mr = new_mr;
> > +   mvdev->mr[asid] = new_mr;
> >     if (old_mr) {
> >     _mlx5_vdpa_destroy_mr(mvdev, old_mr);
> >     kfree(old_mr);
> > @@ -539,7 +541,9 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
> > 
> >  void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
> >  {
> > -   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
> > +   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
> > +   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
> > +
> >     prune_iotlb(mvdev);
> >  }
> > 
> > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > index 4a87f9119fca..25bd2c324f5b 100644
> > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > @@ -821,6 +821,8 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev,
> > struct mlx5_vdpa_virtque
> >  {
> >     int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
> >     u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
> > +   struct mlx5_vdpa_dev *mvdev = >mvdev;
> > +   struct mlx5_vdpa_mr *vq_mr;
> >     void *obj_context;
> >     u16 mlx_features;
> >     void *cmd_hdr;
> > @@ -873,7 +875,9 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev,
> > struct mlx5_vdpa_virtque
> >     MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
> >     MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
> >     MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
> > -   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
> > +   vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
> > +   if (vq_mr)
> > +   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
> >     MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
> >     MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
> >     MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
> > @@ -2633,7 +2637,8 @@ static void restore_channels_info(struct mlx5_vdpa_net
> > *ndev)
> >  }
> > 

Re: [PATCH vhost 10/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-10-03 Thread Dragos Tatulea via Virtualization
On Thu, 2023-09-28 at 19:45 +0300, Dragos Tatulea wrote:
> This patch adapts the mr creation/deletion code to be able to work with
> any given mr struct pointer. All the APIs are adapted to take an extra
> parameter for the mr.
> 
> mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
> check is done in the caller instead (mlx5_set_map).
> 
> This change is needed for a followup patch which will introduce an
> additional mr for the vq descriptor data.
> 
> Signed-off-by: Dragos Tatulea 
Gentle ping for the remaining patches in this series.
 
> ---
>  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  8 +++--
>  drivers/vdpa/mlx5/core/mr.c    | 53 ++
>  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 10 --
>  3 files changed, 36 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> index e1e6e7aba50e..01d4ee58ccb1 100644
> --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> @@ -116,10 +116,12 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev,
> u32 *mkey, u32 *in,
>  int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
>  int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
> *iotlb,
>  bool *change_map, unsigned int asid);
> -int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
> *iotlb,
> -   unsigned int asid);
> +int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> +   struct mlx5_vdpa_mr *mr,
> +   struct vhost_iotlb *iotlb);
>  void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
> -void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
> +void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
> + struct mlx5_vdpa_mr *mr);
>  int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
> struct vhost_iotlb *iotlb,
> unsigned int asid);
> diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> index 00dcce190a1f..6f29e8eaabb1 100644
> --- a/drivers/vdpa/mlx5/core/mr.c
> +++ b/drivers/vdpa/mlx5/core/mr.c
> @@ -301,10 +301,13 @@ static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev,
> struct mlx5_vdpa_direct
> sg_free_table(>sg_head);
>  }
>  
> -static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size,
> u8 perm,
> +static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
> +   struct mlx5_vdpa_mr *mr,
> +   u64 start,
> +   u64 size,
> +   u8 perm,
>     struct vhost_iotlb *iotlb)
>  {
> -   struct mlx5_vdpa_mr *mr = >mr;
> struct mlx5_vdpa_direct_mr *dmr;
> struct mlx5_vdpa_direct_mr *n;
> LIST_HEAD(tmp);
> @@ -354,9 +357,10 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
> u64 start, u64 size, u8
>   * indirect memory key that provides access to the enitre address space given
>   * by iotlb.
>   */
> -static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
> *iotlb)
> +static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
> + struct mlx5_vdpa_mr *mr,
> + struct vhost_iotlb *iotlb)
>  {
> -   struct mlx5_vdpa_mr *mr = >mr;
> struct mlx5_vdpa_direct_mr *dmr;
> struct mlx5_vdpa_direct_mr *n;
> struct vhost_iotlb_map *map;
> @@ -384,7 +388,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
> struct vhost_iotlb *iotlb
>   
> LOG_MAX_KLM_SIZE);
> mr->num_klms += nnuls;
> }
> -   err = add_direct_chain(mvdev, ps, pe - ps,
> pperm, iotlb);
> +   err = add_direct_chain(mvdev, mr, ps, pe - ps,
> pperm, iotlb);
> if (err)
> goto err_chain;
> }
> @@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
> struct vhost_iotlb *iotlb
> pperm = map->perm;
> }
> }
> -   err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
> +   err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
> if (err)
> goto err_chain;
>  
> @@ -489,13 +493,8 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev,
> struct mlx5_vdpa_mr *mr
> }
>  }
>  
> -static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int
> asid)
> +static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct
> mlx5_vdpa_mr *mr)
>  {
> -   struct mlx5_vdpa_mr *mr = >mr;
> -
> -   if 

[PATCH vhost 15/16] vdpa/mlx5: Make iotlb helper functions more generic

2023-09-28 Thread Dragos Tatulea via Virtualization
They will be used in a followup patch.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 3dee6d9bed6b..a4135c16b5bf 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -454,20 +454,20 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr)
mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
 }
 
-static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
+static int dup_iotlb(struct vhost_iotlb *iotlb, struct vhost_iotlb *src)
 {
struct vhost_iotlb_map *map;
u64 start = 0, last = ULLONG_MAX;
int err;
 
if (!src) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, 
start, VHOST_ACCESS_RW);
+   err = vhost_iotlb_add_range(iotlb, start, last, start, 
VHOST_ACCESS_RW);
return err;
}
 
for (map = vhost_iotlb_itree_first(src, start, last); map;
map = vhost_iotlb_itree_next(map, start, last)) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, 
map->last,
+   err = vhost_iotlb_add_range(iotlb, map->start, map->last,
map->addr, map->perm);
if (err)
return err;
@@ -475,9 +475,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *src)
return 0;
 }
 
-static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
+static void prune_iotlb(struct vhost_iotlb *iotlb)
 {
-   vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
+   vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
 }
 
 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr 
*mr)
@@ -544,7 +544,7 @@ void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev 
*mvdev)
for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
 
-   prune_iotlb(mvdev);
+   prune_iotlb(mvdev->cvq.iotlb);
 }
 
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
@@ -596,8 +596,8 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
 
spin_lock(>cvq.iommu_lock);
 
-   prune_iotlb(mvdev);
-   err = dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev->cvq.iotlb);
+   err = dup_iotlb(mvdev->cvq.iotlb, iotlb);
 
spin_unlock(>cvq.iommu_lock);
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost 16/16] vdpa/mlx5: Update cvq iotlb mapping on ASID change

2023-09-28 Thread Dragos Tatulea via Virtualization
For the following sequence:
- cvq group is in ASID 0
- .set_map(1, cvq_iotlb)
- .set_group_asid(cvq_group, 1)

... the cvq mapping from ASID 0 will be used. This is not always correct
behaviour.

This patch adds support for the above mentioned flow by saving the iotlb
on each .set_map and updating the cvq iotlb with it on a cvq group change.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  2 ++
 drivers/vdpa/mlx5/core/mr.c| 26 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  9 -
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ae09296f4270..db988ced5a5d 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -32,6 +32,8 @@ struct mlx5_vdpa_mr {
unsigned long num_directs;
unsigned long num_klms;
 
+   struct vhost_iotlb *iotlb;
+
bool user_mr;
 };
 
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index a4135c16b5bf..403c08271489 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -499,6 +499,8 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
+
+   vhost_iotlb_free(mr->iotlb);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
@@ -558,6 +560,30 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
else
err = create_dma_mr(mvdev, mr);
 
+   if (err)
+   return err;
+
+   mr->iotlb = vhost_iotlb_alloc(0, 0);
+   if (!mr->iotlb) {
+   err = -ENOMEM;
+   goto err_mr;
+   }
+
+   err = dup_iotlb(mr->iotlb, iotlb);
+   if (err)
+   goto err_iotlb;
+
+   return 0;
+
+err_iotlb:
+   vhost_iotlb_free(mr->iotlb);
+
+err_mr:
+   if (iotlb)
+   destroy_user_mr(mvdev, mr);
+   else
+   destroy_dma_mr(mvdev, mr);
+
return err;
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 46441e41892c..fc5d6b989a5a 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -3154,12 +3154,19 @@ static int mlx5_set_group_asid(struct vdpa_device 
*vdev, u32 group,
   unsigned int asid)
 {
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+   int err = 0;
 
if (group >= MLX5_VDPA_NUMVQ_GROUPS || asid >= MLX5_VDPA_NUM_AS)
return -EINVAL;
 
mvdev->group2asid[group] = asid;
-   return 0;
+
+   mutex_lock(>mr_mtx);
+   if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid])
+   err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, 
asid);
+   mutex_unlock(>mr_mtx);
+
+   return err;
 }
 
 static const struct vdpa_config_ops mlx5_vdpa_ops = {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost 14/16] vdpa/mlx5: Enable hw support for vq descriptor mapping

2023-09-28 Thread Dragos Tatulea via Virtualization
Vq descriptor mappings are supported in hardware by filling in an
additional mkey which contains the descriptor mappings to the hw vq.

A previous patch in this series added support for hw mkey (mr) creation
for ASID 1.

This patch fills in both the vq data and vq descriptor mkeys based on
group ASID mapping.

The feature is signaled to the vdpa core through the presence of the
.get_vq_desc_group op.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 26 --
 include/linux/mlx5/mlx5_ifc_vdpa.h |  7 ++-
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 25bd2c324f5b..46441e41892c 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -823,6 +823,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
struct mlx5_vdpa_dev *mvdev = >mvdev;
struct mlx5_vdpa_mr *vq_mr;
+   struct mlx5_vdpa_mr *vq_desc_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -878,6 +879,11 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
if (vq_mr)
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
+
+   vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
+   if (vq_desc_mr)
+   MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey);
+
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2265,6 +2271,16 @@ static u32 mlx5_vdpa_get_vq_group(struct vdpa_device 
*vdev, u16 idx)
return MLX5_VDPA_DATAVQ_GROUP;
 }
 
+static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
+{
+   struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+
+   if (is_ctrl_vq_idx(mvdev, idx))
+   return MLX5_VDPA_CVQ_GROUP;
+
+   return MLX5_VDPA_DATAVQ_DESC_GROUP;
+}
+
 static u64 mlx_to_vritio_features(u16 dev_features)
 {
u64 result = 0;
@@ -3139,7 +3155,7 @@ static int mlx5_set_group_asid(struct vdpa_device *vdev, 
u32 group,
 {
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
 
-   if (group >= MLX5_VDPA_NUMVQ_GROUPS)
+   if (group >= MLX5_VDPA_NUMVQ_GROUPS || asid >= MLX5_VDPA_NUM_AS)
return -EINVAL;
 
mvdev->group2asid[group] = asid;
@@ -3160,6 +3176,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
.get_vq_irq = mlx5_get_vq_irq,
.get_vq_align = mlx5_vdpa_get_vq_align,
.get_vq_group = mlx5_vdpa_get_vq_group,
+   .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not 
supported. */
.get_device_features = mlx5_vdpa_get_device_features,
.set_driver_features = mlx5_vdpa_set_driver_features,
.get_driver_features = mlx5_vdpa_get_driver_features,
@@ -3258,6 +3275,7 @@ struct mlx5_vdpa_mgmtdev {
struct vdpa_mgmt_dev mgtdev;
struct mlx5_adev *madev;
struct mlx5_vdpa_net *ndev;
+   struct vdpa_config_ops vdpa_ops;
 };
 
 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
@@ -3371,7 +3389,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
max_vqs = 2;
}
 
-   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, _vdpa_ops,
+   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, >vdpa_ops,
 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, 
name, false);
if (IS_ERR(ndev))
return PTR_ERR(ndev);
@@ -3546,6 +3564,10 @@ static int mlx5v_probe(struct auxiliary_device *adev,
MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
mgtdev->mgtdev.supported_features = get_supported_features(mdev);
mgtdev->madev = madev;
+   mgtdev->vdpa_ops = mlx5_vdpa_ops;
+
+   if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported))
+   mgtdev->vdpa_ops.get_vq_desc_group = NULL;
 
err = vdpa_mgmtdev_register(>mgtdev);
if (err)
diff --git a/include/linux/mlx5/mlx5_ifc_vdpa.h 
b/include/linux/mlx5/mlx5_ifc_vdpa.h
index 9becdc3fa503..b86d51a855f6 100644
--- a/include/linux/mlx5/mlx5_ifc_vdpa.h
+++ b/include/linux/mlx5/mlx5_ifc_vdpa.h
@@ -74,7 +74,11 @@ struct mlx5_ifc_virtio_q_bits {
u8reserved_at_320[0x8];
u8pd[0x18];
 
-   u8reserved_at_340[0xc0];
+   u8reserved_at_340[0x20];
+
+   u8desc_group_mkey[0x20];
+
+   u8reserved_at_380[0x80];
 };
 
 struct mlx5_ifc_virtio_net_q_object_bits {
@@ -141,6 +145,7 @@ enum {
MLX5_VIRTQ_MODIFY_MASK_STATE= 

[PATCH vhost 13/16] vdpa/mlx5: Introduce mr for vq descriptor

2023-09-28 Thread Dragos Tatulea via Virtualization
Introduce the vq descriptor group and ASID 1. Until now .set_map on ASID
1 was only updating the cvq iotlb. From now on it also creates a mkey
for it. The current patch doesn't use it but follow-up patches will
add hardware support for mapping the vq descriptors.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  5 +++--
 drivers/vdpa/mlx5/core/mr.c| 14 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 20 +---
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index bbe4335106bd..ae09296f4270 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -70,11 +70,12 @@ struct mlx5_vdpa_wq_ent {
 enum {
MLX5_VDPA_DATAVQ_GROUP,
MLX5_VDPA_CVQ_GROUP,
+   MLX5_VDPA_DATAVQ_DESC_GROUP,
MLX5_VDPA_NUMVQ_GROUPS
 };
 
 enum {
-   MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
+   MLX5_VDPA_NUM_AS = 2
 };
 
 struct mlx5_vdpa_dev {
@@ -89,7 +90,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr *mr;
+   struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS];
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00eff5a07152..3dee6d9bed6b 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -511,8 +511,10 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   if (mvdev->mr == mr)
-   mvdev->mr = NULL;
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
+   if (mvdev->mr[i] == mr)
+   mvdev->mr[i] = NULL;
+   }
 
mutex_unlock(>mr_mtx);
 
@@ -523,11 +525,11 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 struct mlx5_vdpa_mr *new_mr,
 unsigned int asid)
 {
-   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
 
mutex_lock(>mr_mtx);
 
-   mvdev->mr = new_mr;
+   mvdev->mr[asid] = new_mr;
if (old_mr) {
_mlx5_vdpa_destroy_mr(mvdev, old_mr);
kfree(old_mr);
@@ -539,7 +541,9 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
+
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 4a87f9119fca..25bd2c324f5b 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -821,6 +821,8 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
 {
int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
+   struct mlx5_vdpa_dev *mvdev = >mvdev;
+   struct mlx5_vdpa_mr *vq_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -873,7 +875,9 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
-   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
+   vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
+   if (vq_mr)
+   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2633,7 +2637,8 @@ static void restore_channels_info(struct mlx5_vdpa_net 
*ndev)
 }
 
 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *new_mr, unsigned int asid)
+   struct mlx5_vdpa_mr *new_mr,
+   unsigned int asid)
 {
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
int err;
@@ -2652,8 +2657,10 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
 
restore_channels_info(ndev);
err = setup_driver(mvdev);
+   if (err)
+   return err;
 
-   return err;
+   return 0;
 }
 
 /* reslock must be held for this function */
@@ -2869,8 +2876,8 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
struct mlx5_vdpa_mr *new_mr;
int err;
 
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   goto end;
+   if (asid >= 

[PATCH vhost 11/16] vdpa/mlx5: Move mr mutex out of mr struct

2023-09-28 Thread Dragos Tatulea via Virtualization
The mutex is named like it is supposed to protect only the mkey but in
reality it is a global lock for all mr resources.

Shift the mutex to it's rightful location (struct mlx5_vdpa_dev) and
give it a more appropriate name.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c| 13 +++--
 drivers/vdpa/mlx5/core/resources.c |  6 +++---
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 01d4ee58ccb1..9c6ac42c21e1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -34,8 +34,6 @@ struct mlx5_vdpa_mr {
/* state of dvq mr */
bool initialized;
 
-   /* serialize mkey creation and destruction */
-   struct mutex mkey_mtx;
bool user_mr;
 };
 
@@ -94,6 +92,8 @@ struct mlx5_vdpa_dev {
u32 generation;
 
struct mlx5_vdpa_mr mr;
+   /* serialize mr access */
+   struct mutex mr_mtx;
struct mlx5_control_vq cvq;
struct workqueue_struct *wq;
unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 6f29e8eaabb1..abd6a6fb122f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -509,11 +509,11 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
@@ -550,9 +550,10 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
 {
int err;
 
-   mutex_lock(>mr.mkey_mtx);
+   mutex_lock(>mr_mtx);
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mr.mkey_mtx);
+   mutex_unlock(>mr_mtx);
+
return err;
 }
 
@@ -563,14 +564,14 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
int err = 0;
 
*change_map = false;
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
if (mr->initialized) {
mlx5_vdpa_info(mvdev, "memory map update\n");
*change_map = true;
}
if (!*change_map)
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 
return err;
 }
diff --git a/drivers/vdpa/mlx5/core/resources.c 
b/drivers/vdpa/mlx5/core/resources.c
index d5a59c9035fb..5c5a41b64bfc 100644
--- a/drivers/vdpa/mlx5/core/resources.c
+++ b/drivers/vdpa/mlx5/core/resources.c
@@ -256,7 +256,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
mlx5_vdpa_warn(mvdev, "resources already allocated\n");
return -EINVAL;
}
-   mutex_init(>mr.mkey_mtx);
+   mutex_init(>mr_mtx);
res->uar = mlx5_get_uars_page(mdev);
if (IS_ERR(res->uar)) {
err = PTR_ERR(res->uar);
@@ -301,7 +301,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
 err_uctx:
mlx5_put_uars_page(mdev, res->uar);
 err_uars:
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
return err;
 }
 
@@ -318,6 +318,6 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev)
dealloc_pd(mvdev, res->pdn, res->uid);
destroy_uctx(mvdev, res->uid);
mlx5_put_uars_page(mvdev->mdev, res->uar);
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
res->valid = false;
 }
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost 08/16] vdpa/mlx5: Collapse "dvq" mr add/delete functions

2023-09-28 Thread Dragos Tatulea via Virtualization
Now that the cvq code is out of mlx5_vdpa_create/destroy_mr, the "dvq"
functions can be folded into their callers.

Having "dvq" in the naming will no longer be accurate in the downstream
patches.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 587300e7c18e..fde00497f4ad 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,7 +489,7 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -513,7 +513,7 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
 
mutex_lock(>mkey_mtx);
 
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
+   _mlx5_vdpa_destroy_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
@@ -524,9 +524,9 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
prune_iotlb(mvdev);
 }
 
-static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
+static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
int err;
@@ -550,12 +550,6 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 }
 
-static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb, unsigned int asid)
-{
-   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-}
-
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid)
 {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost 12/16] vdpa/mlx5: Improve mr update flow

2023-09-28 Thread Dragos Tatulea via Virtualization
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.

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.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 14 +++--
 drivers/vdpa/mlx5/core/mr.c| 87 --
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 46 
 3 files changed, 76 insertions(+), 71 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 9c6ac42c21e1..bbe4335106bd 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
struct list_head head;
unsigned long num_directs;
unsigned long num_klms;
-   /* state of dvq mr */
-   bool initialized;
 
bool user_mr;
 };
@@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr mr;
+   struct mlx5_vdpa_mr *mr;
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
@@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev 
*mvdev);
 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
  int inlen);
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
-int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
-bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb);
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr);
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *mr,
+unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index abd6a6fb122f..00eff5a07152 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
 
 static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   if (!mr->initialized)
-   return;
-
if (mr->user_mr)
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
-
-   mr->initialized = false;
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
+   if (!mr)
+   return;
+
mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
+   if (mvdev->mr == mr)
+   mvdev->mr = NULL;
+
+   mutex_unlock(>mr_mtx);
+
+   kfree(mr);
+}
+
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *new_mr,
+unsigned int asid)
+{
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+
+   mutex_lock(>mr_mtx);
+
+   mvdev->mr = new_mr;
+   if (old_mr) {
+   _mlx5_vdpa_destroy_mr(mvdev, old_mr);
+   kfree(old_mr);
+   }
+
mutex_unlock(>mr_mtx);
+
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, >mr);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
prune_iotlb(mvdev);
 }
 
@@ -528,52 +549,36 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
 {
int err;
 
-   if (mr->initialized)
-   return 0;
-
if (iotlb)
err = create_user_mr(mvdev, mr, iotlb);
else
err = create_dma_mr(mvdev, mr);
 
-   if (err)
-   return err;
-
-   mr->initialized = true;
-
-   return 0;
+   return err;
 }
 
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb)
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb)
 {
+   struct mlx5_vdpa_mr *mr;
int 

[PATCH vhost 07/16] vdpa/mlx5: Take cvq iotlb lock during refresh

2023-09-28 Thread Dragos Tatulea via Virtualization
The reslock is taken while refresh is called but iommu_lock is more
specific to this resource. So take the iommu_lock during cvq iotlb
refresh.

Based on Eugenio's patch [0].

[0] https://lore.kernel.org/lkml/20230112142218.725622-4-epere...@redhat.com/

Acked-by: Jason Wang 
Suggested-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fcb6ae32e9ed..587300e7c18e 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -590,11 +590,19 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev 
*mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid)
 {
+   int err;
+
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
return 0;
 
+   spin_lock(>cvq.iommu_lock);
+
prune_iotlb(mvdev);
-   return dup_iotlb(mvdev, iotlb);
+   err = dup_iotlb(mvdev, iotlb);
+
+   spin_unlock(>cvq.iommu_lock);
+
+   return err;
 }
 
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost 10/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-09-28 Thread Dragos Tatulea via Virtualization
This patch adapts the mr creation/deletion code to be able to work with
any given mr struct pointer. All the APIs are adapted to take an extra
parameter for the mr.

mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
check is done in the caller instead (mlx5_set_map).

This change is needed for a followup patch which will introduce an
additional mr for the vq descriptor data.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  8 +++--
 drivers/vdpa/mlx5/core/mr.c| 53 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 10 --
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index e1e6e7aba50e..01d4ee58ccb1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -116,10 +116,12 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, 
u32 *mkey, u32 *in,
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
 int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
 bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
-   unsigned int asid);
+int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00dcce190a1f..6f29e8eaabb1 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -301,10 +301,13 @@ static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_direct
sg_free_table(>sg_head);
 }
 
-static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, 
u8 perm,
+static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   u64 start,
+   u64 size,
+   u8 perm,
struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
LIST_HEAD(tmp);
@@ -354,9 +357,10 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, 
u64 start, u64 size, u8
  * indirect memory key that provides access to the enitre address space given
  * by iotlb.
  */
-static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb)
+static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr,
+ struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
struct vhost_iotlb_map *map;
@@ -384,7 +388,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
   
LOG_MAX_KLM_SIZE);
mr->num_klms += nnuls;
}
-   err = add_direct_chain(mvdev, ps, pe - ps, 
pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, 
pperm, iotlb);
if (err)
goto err_chain;
}
@@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
pperm = map->perm;
}
}
-   err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
if (err)
goto err_chain;
 
@@ -489,13 +493,8 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
-
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   return;
-
if (!mr->initialized)
return;
 
@@ -507,38 +506,33 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
+void 

[PATCH vhost 09/16] vdpa/mlx5: Rename mr destroy functions

2023-09-28 Thread Dragos Tatulea via Virtualization
Make mlx5_destroy_mr symmetric to mlx5_create_mr.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c|  6 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 12 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 554899a80241..e1e6e7aba50e 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -118,8 +118,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 bool *change_map, unsigned int asid);
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fde00497f4ad..00dcce190a1f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -507,7 +507,7 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -518,9 +518,9 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
mutex_unlock(>mkey_mtx);
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index aa4896662699..ab196c43694c 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2644,7 +2644,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
goto err_mr;
 
teardown_driver(ndev);
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
if (err)
goto err_mr;
@@ -2660,7 +2660,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 
 err_setup:
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
 err_mr:
return err;
 }
@@ -2797,7 +2797,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device 
*vdev, u8 status)
 err_driver:
unregister_link_notifier(ndev);
 err_setup:
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
 err_clear:
up_write(>reslock);
@@ -2824,7 +2824,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
unregister_link_notifier(ndev);
teardown_driver(ndev);
clear_vqs_ready(ndev);
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status = 0;
ndev->mvdev.suspended = false;
ndev->cur_num_vqs = 0;
@@ -2944,7 +2944,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev)
ndev = to_mlx5_vdpa_ndev(mvdev);
 
free_resources(ndev);
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
if (!is_zero_ether_addr(ndev->config.mac)) {
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
@@ -3474,7 +3474,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
 err_res2:
free_resources(ndev);
 err_mr:
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
 err_res:
mlx5_vdpa_free_resources(>mvdev);
 err_mpfs:
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost 06/16] vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code

2023-09-28 Thread Dragos Tatulea via Virtualization
The handling of the cvq iotlb is currently coupled with the creation
and destruction of the hardware mkeys (mr).

This patch moves cvq iotlb handling into its own function and shifts it
to a scope that is not related to mr handling. As cvq handling is just a
prune_iotlb + dup_iotlb cycle, put it all in the same "update" function.
Finally, the destruction path is handled by directly pruning the iotlb.

After this move is done the ASID mr code can be collapsed into a single
function.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  3 ++
 drivers/vdpa/mlx5/core/mr.c| 57 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  7 ++--
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 3748f027cfe9..554899a80241 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,9 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid);
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 7bd0883b8b25..fcb6ae32e9ed 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,14 +489,6 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return;
-
-   prune_iotlb(mvdev);
-}
-
 static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
@@ -522,25 +514,14 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid)
mutex_lock(>mkey_mtx);
 
_mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]);
mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
-}
-
-static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return 0;
-
-   return dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev);
 }
 
 static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
@@ -572,22 +553,7 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb, unsigned int asid)
 {
-   int err;
-
-   err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-   if (err)
-   return err;
-
-   err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
-   if (err)
-   goto out_err;
-
-   return 0;
-
-out_err:
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-
-   return err;
+   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
 }
 
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
@@ -620,7 +586,24 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
return err;
 }
 
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
+{
+   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
+   return 0;
+
+   prune_iotlb(mvdev);
+   return dup_iotlb(mvdev, iotlb);
+}
+
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   int err;
+
+   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   if (err)
+   return err;
+
+   return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
 }
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 65b6a54ad344..aa4896662699 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2884,10 +2884,13 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
return err;
}
 
-   if (change_map)
+   if 

[PATCH vhost 04/16] vhost-vdpa: uAPI to get dedicated descriptor group id

2023-09-28 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

With _F_DESC_ASID backend feature, the device can now support the
VHOST_VDPA_GET_VRING_DESC_GROUP ioctl, and it may expose the descriptor
table (including avail and used ring) in a different group than the
buffers it contains. This new uAPI will fetch the group ID of the
descriptor table.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c   | 10 ++
 include/uapi/linux/vhost.h |  8 
 2 files changed, 18 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 2f21798a37ee..851535f57b95 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -613,6 +613,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, 
unsigned int cmd,
else if (copy_to_user(argp, , sizeof(s)))
return -EFAULT;
return 0;
+   case VHOST_VDPA_GET_VRING_DESC_GROUP:
+   if (!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
+   s.index = idx;
+   s.num = ops->get_vq_desc_group(vdpa, idx);
+   if (s.num >= vdpa->ngroups)
+   return -EIO;
+   else if (copy_to_user(argp, , sizeof(s)))
+   return -EFAULT;
+   return 0;
case VHOST_VDPA_SET_GROUP_ASID:
if (copy_from_user(, argp, sizeof(s)))
return -EFAULT;
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index f5c48b61ab62..649560c685f1 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -219,4 +219,12 @@
  */
 #define VHOST_VDPA_RESUME  _IO(VHOST_VIRTIO, 0x7E)
 
+/* Get the group for the descriptor table including driver & device areas
+ * of a virtqueue: read index, write group in num.
+ * The virtqueue index is stored in the index field of vhost_vring_state.
+ * The group ID of the descriptor table for this specific virtqueue
+ * is returned via num field of vhost_vring_state.
+ */
+#define VHOST_VDPA_GET_VRING_DESC_GROUP_IOWR(VHOST_VIRTIO, 0x7F,   
\
+ struct vhost_vring_state)
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost 05/16] vdpa/mlx5: Create helper function for dma mappings

2023-09-28 Thread Dragos Tatulea via Virtualization
Necessary for upcoming cvq separation from mr allocation.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 1 +
 drivers/vdpa/mlx5/core/mr.c| 5 +
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 4 ++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ca56242972b3..3748f027cfe9 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,7 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, 
__func__, __LINE__, \
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 5a1971fcd87b..7bd0883b8b25 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -619,3 +619,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 
return err;
 }
+
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
+{
+   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+}
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 40a03b08d7cf..65b6a54ad344 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2836,7 +2836,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
++mvdev->generation;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   if (mlx5_vdpa_create_mr(mvdev, NULL, 0))
+   if (mlx5_vdpa_create_dma_mr(mvdev))
mlx5_vdpa_warn(mvdev, "create MR failed\n");
}
up_write(>reslock);
@@ -3441,7 +3441,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
goto err_mpfs;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   err = mlx5_vdpa_create_dma_mr(mvdev);
if (err)
goto err_res;
}
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost 03/16] vhost-vdpa: introduce descriptor group backend feature

2023-09-28 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

Userspace knows if the device has dedicated descriptor group or not
by checking this feature bit.

It's only exposed if the vdpa driver backend implements the
.get_vq_desc_group() operation callback. Userspace trying to negotiate
this feature when it or the dependent _F_IOTLB_ASID feature hasn't
been exposed will result in an error.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c | 17 +
 include/uapi/linux/vhost_types.h |  5 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 78379ffd2336..2f21798a37ee 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -389,6 +389,14 @@ static bool vhost_vdpa_can_resume(const struct vhost_vdpa 
*v)
return ops->resume;
 }
 
+static bool vhost_vdpa_has_desc_group(const struct vhost_vdpa *v)
+{
+   struct vdpa_device *vdpa = v->vdpa;
+   const struct vdpa_config_ops *ops = vdpa->config;
+
+   return ops->get_vq_desc_group;
+}
+
 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
 {
struct vdpa_device *vdpa = v->vdpa;
@@ -690,6 +698,7 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if (copy_from_user(, featurep, sizeof(features)))
return -EFAULT;
if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
+BIT_ULL(VHOST_BACKEND_F_DESC_ASID) |
 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
 BIT_ULL(VHOST_BACKEND_F_RESUME) |
 
BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))
@@ -700,6 +709,12 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&
 !vhost_vdpa_can_resume(v))
return -EOPNOTSUPP;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+   !(features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)))
+   return -EINVAL;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
vhost_set_backend_features(>vdev, features);
return 0;
}
@@ -753,6 +768,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
if (vhost_vdpa_can_resume(v))
features |= BIT_ULL(VHOST_BACKEND_F_RESUME);
+   if (vhost_vdpa_has_desc_group(v))
+   features |= BIT_ULL(VHOST_BACKEND_F_DESC_ASID);
features |= vhost_vdpa_get_backend_features(v);
if (copy_to_user(featurep, , sizeof(features)))
r = -EFAULT;
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
index 2d827d22cd99..18ad6ae7ab5c 100644
--- a/include/uapi/linux/vhost_types.h
+++ b/include/uapi/linux/vhost_types.h
@@ -185,5 +185,10 @@ struct vhost_vdpa_iova_range {
  * DRIVER_OK
  */
 #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK  0x6
+/* Device may expose the virtqueue's descriptor area, driver area and
+ * device area to a different group for ASID binding than where its
+ * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID.
+ */
+#define VHOST_BACKEND_F_DESC_ASID0x7
 
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH vhost 02/16] vdpa: introduce dedicated descriptor group for virtqueue

2023-09-28 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

In some cases, the access to the virtqueue's descriptor area, device
and driver areas (precluding indirect descriptor table in guest memory)
may have to be confined to a different address space than where its
buffers reside. Without loss of simplicity and generality with already
established terminology, let's fold up these 3 areas and call them
as a whole as descriptor table group, or descriptor group for short.
Specifically, in case of split virtqueues, descriptor group consists of
regions for Descriptor Table, Available Ring and Used Ring; for packed
virtqueues layout, descriptor group contains Descriptor Ring, Driver
and Device Event Suppression structures.

The group ID for a dedicated descriptor group can be obtained through a
new .get_vq_desc_group() op. If driver implements this op, it means that
the descriptor, device and driver areas of the virtqueue may reside
in a dedicated group than where its buffers reside, a.k.a the default
virtqueue group through the .get_vq_group() op.

In principle, the descriptor group may or may not have same group ID
as the default group. Even if the descriptor group has a different ID,
meaning the vq's descriptor group areas can optionally move to a
separate address space than where guest memory resides, the descriptor
group may still start from a default address space, same as where its
buffers reside. To move the descriptor group to a different address
space, .set_group_asid() has to be called to change the ASID binding
for the group, which is no different than what needs to be done on any
other virtqueue group. On the other hand, the .reset() semantics also
applies on descriptor table group, meaning the device reset will clear
all ASID bindings and move all virtqueue groups including descriptor
group back to the default address space, i.e. in ASID 0.

QEMU's shadow virtqueue is going to utilize dedicated descriptor group
to speed up map and unmap operations, yielding tremendous downtime
reduction by avoiding the full and slow remap cycle in SVQ switching.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 include/linux/vdpa.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index 0e652026b776..d376309b99cf 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -204,6 +204,16 @@ struct vdpa_map_file {
  * @vdev: vdpa device
  * @idx: virtqueue index
  * Returns u32: group id for this virtqueue
+ * @get_vq_desc_group: Get the group id for the descriptor table of
+ * a specific virtqueue (optional)
+ * @vdev: vdpa device
+ * @idx: virtqueue index
+ * Returns u32: group id for the descriptor table
+ * portion of this virtqueue. Could be different
+ * than the one from @get_vq_group, in which case
+ * the access to the descriptor table can be
+ * confined to a separate asid, isolating from
+ * the virtqueue's buffer address access.
  * @get_device_features:   Get virtio features supported by the device
  * @vdev: vdpa device
  * Returns the virtio features support by the
@@ -360,6 +370,7 @@ struct vdpa_config_ops {
/* Device ops */
u32 (*get_vq_align)(struct vdpa_device *vdev);
u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
+   u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
u64 (*get_device_features)(struct vdpa_device *vdev);
u64 (*get_backend_features)(const struct vdpa_device *vdev);
int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH mlx5-next 01/16] vdpa/mlx5: Expose descriptor group mkey hw capability

2023-09-28 Thread Dragos Tatulea via Virtualization
Necessary for improved live migration flow. Actual support will be added
in a downstream patch.

Reviewed-by: Gal Pressman 
Signed-off-by: Dragos Tatulea 
---
 include/linux/mlx5/mlx5_ifc.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index dd8421d021cf..ec15330b970d 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1231,7 +1231,13 @@ struct mlx5_ifc_virtio_emulation_cap_bits {
u8 max_emulated_devices[0x8];
u8 max_num_virtio_queues[0x18];
 
-   u8 reserved_at_a0[0x60];
+   u8 reserved_at_a0[0x20];
+
+   u8 reserved_at_c0[0x13];
+   u8 desc_group_mkey_supported[0x1];
+   u8 reserved_at_d4[0xc];
+
+   u8 reserved_at_e0[0x20];
 
u8 umem_1_buffer_param_a[0x20];
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v2 00/16] vdpa: Add support for vq descriptor mappings

2023-09-28 Thread Dragos Tatulea via Virtualization
This patch series adds support for vq descriptor table mappings which
are used to improve vdpa live migration downtime. The improvement comes
from using smaller mappings which take less time to create and destroy
in hw.

The first part adds the vdpa core changes from Si-Wei [0].

The second part adds support in mlx5_vdpa:
- Refactor the mr code to be able to cleanly add descriptor mappings.
- Add hardware descriptor mr support.
- Properly update iotlb for cvq during ASID switch.

Changes in v2:

- The "vdpa/mlx5: Enable hw support for vq descriptor mapping" change
  was split off into two patches to avoid merge conflicts into the tree
  of Linus.

  The first patch contains only changes for mlx5_ifc.h. This must be
  applied into the mlx5-next tree [1] first. Once this patch is applied
  on mlx5-next, the change has to be pulled fom mlx5-next into the vhost
  tree and only then the remaining patches can be applied.

[0] 
https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-next

Dragos Tatulea (13):
  vdpa/mlx5: Expose descriptor group mkey hw capability
  vdpa/mlx5: Create helper function for dma mappings
  vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
  vdpa/mlx5: Take cvq iotlb lock during refresh
  vdpa/mlx5: Collapse "dvq" mr add/delete functions
  vdpa/mlx5: Rename mr destroy functions
  vdpa/mlx5: Allow creation/deletion of any given mr struct
  vdpa/mlx5: Move mr mutex out of mr struct
  vdpa/mlx5: Improve mr update flow
  vdpa/mlx5: Introduce mr for vq descriptor
  vdpa/mlx5: Enable hw support for vq descriptor mapping
  vdpa/mlx5: Make iotlb helper functions more generic
  vdpa/mlx5: Update cvq iotlb mapping on ASID change

Si-Wei Liu (3):
  vdpa: introduce dedicated descriptor group for virtqueue
  vhost-vdpa: introduce descriptor group backend feature
  vhost-vdpa: uAPI to get dedicated descriptor group id

 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
 drivers/vdpa/mlx5/core/mr.c| 191 -
 drivers/vdpa/mlx5/core/resources.c |   6 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 100 ++-
 drivers/vhost/vdpa.c   |  27 
 include/linux/mlx5/mlx5_ifc.h  |   8 +-
 include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
 include/linux/vdpa.h   |  11 ++
 include/uapi/linux/vhost.h |   8 ++
 include/uapi/linux/vhost_types.h   |   5 +
 10 files changed, 264 insertions(+), 130 deletions(-)

-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH vhost v2 00/16] vdpa: Add support for vq descriptor mappings

2023-09-28 Thread Dragos Tatulea via Virtualization
This patch series adds support for vq descriptor table mappings which
are used to improve vdpa live migration downtime. The improvement comes
from using smaller mappings which take less time to create and destroy
in hw.

The first part adds the vdpa core changes from Si-Wei [0].

The second part adds support in mlx5_vdpa:
- Refactor the mr code to be able to cleanly add descriptor mappings.
- Add hardware descriptor mr support.
- Properly update iotlb for cvq during ASID switch.

Changes in v2:

- The "vdpa/mlx5: Enable hw support for vq descriptor mapping" change
  was split off into two patches to avoid merge conflicts into the tree
  of Linus.

  The first patch contains only changes for mlx5_ifc.h. This must be
  applied into the mlx5-next tree [1] first. Once this patch is applied
  on mlx5-next, the change has to be pulled fom mlx5-next into the vhost
  tree and only then the remaining patches can be applied.

[0] 
https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-next

Dragos Tatulea (13):
  vdpa/mlx5: Expose descriptor group mkey hw capability
  vdpa/mlx5: Create helper function for dma mappings
  vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
  vdpa/mlx5: Take cvq iotlb lock during refresh
  vdpa/mlx5: Collapse "dvq" mr add/delete functions
  vdpa/mlx5: Rename mr destroy functions
  vdpa/mlx5: Allow creation/deletion of any given mr struct
  vdpa/mlx5: Move mr mutex out of mr struct
  vdpa/mlx5: Improve mr update flow
  vdpa/mlx5: Introduce mr for vq descriptor
  vdpa/mlx5: Enable hw support for vq descriptor mapping
  vdpa/mlx5: Make iotlb helper functions more generic
  vdpa/mlx5: Update cvq iotlb mapping on ASID change

Si-Wei Liu (3):
  vdpa: introduce dedicated descriptor group for virtqueue
  vhost-vdpa: introduce descriptor group backend feature
  vhost-vdpa: uAPI to get dedicated descriptor group id

 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
 drivers/vdpa/mlx5/core/mr.c| 191 -
 drivers/vdpa/mlx5/core/resources.c |   6 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 100 ++-
 drivers/vhost/vdpa.c   |  27 
 include/linux/mlx5/mlx5_ifc.h  |   8 +-
 include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
 include/linux/vdpa.h   |  11 ++
 include/uapi/linux/vhost.h |   8 ++
 include/uapi/linux/vhost_types.h   |   5 +
 10 files changed, 264 insertions(+), 130 deletions(-)

-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 00/16] vdpa: Add support for vq descriptor mappings

2023-09-26 Thread Dragos Tatulea via Virtualization
On Tue, 2023-09-26 at 05:22 -0700, Si-Wei Liu wrote:
> 
> 
> On 9/25/2023 12:59 AM, Dragos Tatulea wrote:
> > On Tue, 2023-09-12 at 16:01 +0300, Dragos Tatulea wrote:
> > > This patch series adds support for vq descriptor table mappings which
> > > are used to improve vdpa live migration downtime. The improvement comes
> > > from using smaller mappings which take less time to create and destroy
> > > in hw.
> > > 
> > Gentle ping.
> > 
> > Note that I will have to send a v2. The changes in mlx5_ifc.h will need to
> > be
> > merged first separately into the mlx5-next branch [0] and then pulled from
> > there
> > when the series is applied.
> This separation is unnecessary, as historically the virtio emulation 
> portion of the update to mlx5_ifc.h often had to go through the vhost 
> tree. See commits 1892a3d425bf and e13cd45d352d. Especially the 
> additions from this series (mainly desc group mkey) have nothing to do 
> with any networking or NIC driver feature.
> 
The reason for doing that is to avoid conflicts in Linus's tree on the
mlx5_ifc.h file.

Thanks,
Dragos

> -Siwei
> 
> > 
> > [0]
> > https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-next
> > 
> > Thanks,
> > Dragos
> > 
> > > The first part adds the vdpa core changes from Si-Wei [0].
> > > 
> > > The second part adds support in mlx5_vdpa:
> > > - Refactor the mr code to be able to cleanly add descriptor mappings.
> > > - Add hardware descriptor mr support.
> > > - Properly update iotlb for cvq during ASID switch.
> > > 
> > > [0]
> > > https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
> > > 
> > > Dragos Tatulea (13):
> > >    vdpa/mlx5: Create helper function for dma mappings
> > >    vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
> > >    vdpa/mlx5: Take cvq iotlb lock during refresh
> > >    vdpa/mlx5: Collapse "dvq" mr add/delete functions
> > >    vdpa/mlx5: Rename mr destroy functions
> > >    vdpa/mlx5: Allow creation/deletion of any given mr struct
> > >    vdpa/mlx5: Move mr mutex out of mr struct
> > >    vdpa/mlx5: Improve mr update flow
> > >    vdpa/mlx5: Introduce mr for vq descriptor
> > >    vdpa/mlx5: Enable hw support for vq descriptor mapping
> > >    vdpa/mlx5: Make iotlb helper functions more generic
> > >    vdpa/mlx5: Update cvq iotlb mapping on ASID change
> > >    Cover letter: vdpa/mlx5: Add support for vq descriptor mappings
> > > 
> > > Si-Wei Liu (3):
> > >    vdpa: introduce dedicated descriptor group for virtqueue
> > >    vhost-vdpa: introduce descriptor group backend feature
> > >    vhost-vdpa: uAPI to get dedicated descriptor group id
> > > 
> > >   drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
> > >   drivers/vdpa/mlx5/core/mr.c    | 191 -
> > >   drivers/vdpa/mlx5/core/resources.c |   6 +-
> > >   drivers/vdpa/mlx5/net/mlx5_vnet.c  | 100 ++-
> > >   drivers/vhost/vdpa.c   |  27 
> > >   include/linux/mlx5/mlx5_ifc.h  |   8 +-
> > >   include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
> > >   include/linux/vdpa.h   |  11 ++
> > >   include/uapi/linux/vhost.h |   8 ++
> > >   include/uapi/linux/vhost_types.h   |   5 +
> > >   10 files changed, 264 insertions(+), 130 deletions(-)
> > > 
> 

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH 09/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-09-26 Thread Dragos Tatulea via Virtualization
On Tue, 2023-09-26 at 12:44 +0800, Jason Wang wrote:
> On Tue, Sep 12, 2023 at 9:02 PM Dragos Tatulea  wrote:
> > 
> > This patch adapts the mr creation/deletion code to be able to work with
> > any given mr struct pointer. All the APIs are adapted to take an extra
> > parameter for the mr.
> > 
> > mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
> > check is done in the caller instead (mlx5_set_map).
> > 
> > This change is needed for a followup patch which will introduce an
> > additional mr for the vq descriptor data.
> > 
> > Signed-off-by: Dragos Tatulea 
> > ---
> 
> Thinking of this decoupling I think I have a question.
> 
> We advertise 2 address spaces and 2 groups. So we actually don't know
> for example which address spaces will be used by dvq.
> 
> And actually we allow the user space to do something like
> 
> set_group_asid(dvq_group, 0)
> set_map(0)
> set_group_asid(dvq_group, 1)
> set_map(1)
> 
> I wonder if the decoupling like this patch can work and why.
> 
This scenario could indeed work. Especially if you look at the 13'th patch [0]
where hw support is added. Are you wondering if this should work at all or if it
should be blocked?

> It looks to me the most easy way is to let each AS be backed by an MR.
> Then we don't even need to care about the dvq, cvq.
That's what this patch series dowes.

Thanks,
Dragos

[0]https://lore.kernel.org/virtualization/20230912130132.561193-14-dtatu...@nvidia.com/T/#u
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH v2] MAINTAINERS: Add myself as mlx5_vdpa driver

2023-09-25 Thread Dragos Tatulea via Virtualization
As Eli Cohen moved to other work, I'll be the contact point for
mlx5_vdpa.

Acked-by: Jason Wang 
Signed-off-by: Dragos Tatulea 
---
Changes since v1:
- Fix alphabetical sorting.
- Make naming consistent with other MELLANOX entries.
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 3dde038545d8..611c31b3b9c9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13677,6 +13677,12 @@ F: drivers/infiniband/hw/mlx5/
 F: include/linux/mlx5/
 F: include/uapi/rdma/mlx5-abi.h
 
+MELLANOX MLX5 VDPA DRIVER
+M: Dragos Tatulea 
+L: virtualization@lists.linux-foundation.org
+S: Supported
+F: drivers/vdpa/mlx5/
+
 MELLANOX MLXCPLD I2C AND MUX DRIVER
 M: Vadim Pasternak 
 M: Michael Shych 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 00/16] vdpa: Add support for vq descriptor mappings

2023-09-25 Thread Dragos Tatulea via Virtualization
On Tue, 2023-09-12 at 16:01 +0300, Dragos Tatulea wrote:
> This patch series adds support for vq descriptor table mappings which
> are used to improve vdpa live migration downtime. The improvement comes
> from using smaller mappings which take less time to create and destroy
> in hw.
> 
Gentle ping.

Note that I will have to send a v2. The changes in mlx5_ifc.h will need to be
merged first separately into the mlx5-next branch [0] and then pulled from there
when the series is applied.

[0]
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/log/?h=mlx5-next

Thanks,
Dragos

> The first part adds the vdpa core changes from Si-Wei [0].
> 
> The second part adds support in mlx5_vdpa:
> - Refactor the mr code to be able to cleanly add descriptor mappings.
> - Add hardware descriptor mr support.
> - Properly update iotlb for cvq during ASID switch.
> 
> [0]
> https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com
> 
> Dragos Tatulea (13):
>   vdpa/mlx5: Create helper function for dma mappings
>   vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
>   vdpa/mlx5: Take cvq iotlb lock during refresh
>   vdpa/mlx5: Collapse "dvq" mr add/delete functions
>   vdpa/mlx5: Rename mr destroy functions
>   vdpa/mlx5: Allow creation/deletion of any given mr struct
>   vdpa/mlx5: Move mr mutex out of mr struct
>   vdpa/mlx5: Improve mr update flow
>   vdpa/mlx5: Introduce mr for vq descriptor
>   vdpa/mlx5: Enable hw support for vq descriptor mapping
>   vdpa/mlx5: Make iotlb helper functions more generic
>   vdpa/mlx5: Update cvq iotlb mapping on ASID change
>   Cover letter: vdpa/mlx5: Add support for vq descriptor mappings
> 
> Si-Wei Liu (3):
>   vdpa: introduce dedicated descriptor group for virtqueue
>   vhost-vdpa: introduce descriptor group backend feature
>   vhost-vdpa: uAPI to get dedicated descriptor group id
> 
>  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
>  drivers/vdpa/mlx5/core/mr.c    | 191 -
>  drivers/vdpa/mlx5/core/resources.c |   6 +-
>  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 100 ++-
>  drivers/vhost/vdpa.c   |  27 
>  include/linux/mlx5/mlx5_ifc.h  |   8 +-
>  include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
>  include/linux/vdpa.h   |  11 ++
>  include/uapi/linux/vhost.h |   8 ++
>  include/uapi/linux/vhost_types.h   |   5 +
>  10 files changed, 264 insertions(+), 130 deletions(-)
> 

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH] vdpa/mlx5: Fix double release of debugfs entry

2023-09-14 Thread Dragos Tatulea via Virtualization
On Tue, 2023-08-29 at 20:40 +0300, Dragos Tatulea wrote:
> The error path in setup_driver deletes the debugfs entry but doesn't
> clear the pointer. During .dev_del the invalid pointer will be released
> again causing a crash.
> 
> This patch fixes the issue by always clearing the debugfs entry in
> mlx5_vdpa_remove_debugfs. Also, stop removing the debugfs entry in
> .dev_del op: the debugfs entry is already handled within the
> setup_driver/teardown_driver scope.
> 
> Fixes: f0417e72add5 ("vdpa/mlx5: Add and remove debugfs in setup/teardown
> driver")
> Signed-off-by: Dragos Tatulea 
> Reviewed-by: Gal Pressman 

Gentle ping. Are there any comments on this patch?

Thanks,
Dragos
> ---
>  drivers/vdpa/mlx5/net/debug.c | 5 +++--
>  drivers/vdpa/mlx5/net/mlx5_vnet.c | 7 ++-
>  drivers/vdpa/mlx5/net/mlx5_vnet.h | 2 +-
>  3 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/vdpa/mlx5/net/debug.c b/drivers/vdpa/mlx5/net/debug.c
> index 60d6ac68cdc4..9c85162c19fc 100644
> --- a/drivers/vdpa/mlx5/net/debug.c
> +++ b/drivers/vdpa/mlx5/net/debug.c
> @@ -146,7 +146,8 @@ void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev)
> ndev->rx_dent = debugfs_create_dir("rx", ndev->debugfs);
>  }
>  
> -void mlx5_vdpa_remove_debugfs(struct dentry *dbg)
> +void mlx5_vdpa_remove_debugfs(struct mlx5_vdpa_net *ndev)
>  {
> -   debugfs_remove_recursive(dbg);
> +   debugfs_remove_recursive(ndev->debugfs);
> +   ndev->debugfs = NULL;
>  }
> diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> index 37be945a0230..f91c938b4be1 100644
> --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> @@ -2713,7 +2713,7 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
>  err_rqt:
> teardown_virtqueues(ndev);
>  err_setup:
> -   mlx5_vdpa_remove_debugfs(ndev->debugfs);
> +   mlx5_vdpa_remove_debugfs(ndev);
>  out:
> return err;
>  }
> @@ -2727,8 +2727,7 @@ static void teardown_driver(struct mlx5_vdpa_net *ndev)
> if (!ndev->setup)
> return;
>  
> -   mlx5_vdpa_remove_debugfs(ndev->debugfs);
> -   ndev->debugfs = NULL;
> +   mlx5_vdpa_remove_debugfs(ndev);
> teardown_steering(ndev);
> destroy_tir(ndev);
> destroy_rqt(ndev);
> @@ -3489,8 +3488,6 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev
> *v_mdev, struct vdpa_device *
> struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
> struct workqueue_struct *wq;
>  
> -   mlx5_vdpa_remove_debugfs(ndev->debugfs);
> -   ndev->debugfs = NULL;
> unregister_link_notifier(ndev);
> _vdpa_unregister_device(dev);
> wq = mvdev->wq;
> diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.h
> b/drivers/vdpa/mlx5/net/mlx5_vnet.h
> index 36c44d9fdd16..60cdbc903037 100644
> --- a/drivers/vdpa/mlx5/net/mlx5_vnet.h
> +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.h
> @@ -88,7 +88,7 @@ struct macvlan_node {
>  };
>  
>  void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev);
> -void mlx5_vdpa_remove_debugfs(struct dentry *dbg);
> +void mlx5_vdpa_remove_debugfs(struct mlx5_vdpa_net *ndev);
>  void mlx5_vdpa_add_rx_flow_table(struct mlx5_vdpa_net *ndev);
>  void mlx5_vdpa_remove_rx_flow_table(struct mlx5_vdpa_net *ndev);
>  void mlx5_vdpa_add_tirn(struct mlx5_vdpa_net *ndev);

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v2] vdpa/mlx5: Fix firmware error on creation of 1k VQs

2023-09-14 Thread Dragos Tatulea via Virtualization
On Thu, 2023-08-31 at 18:50 +0300, Dragos Tatulea wrote:
> A firmware error is triggered when configuring a 9k MTU on the PF after
> switching to switchdev mode and then using a vdpa device with larger
> (1k) rings:
> mlx5_cmd_out_err: CREATE_GENERAL_OBJECT(0xa00) op_mod(0xd) failed, status bad
> resource(0x5), syndrome (0xf6db90), err(-22)
> 
> This is due to the fact that the hw VQ size parameters are computed
> based on the umem_1/2/3_buffer_param_a/b capabilities and all
> device capabilities are read only when the driver is moved to switchdev mode.
> 
> The problematic configuration flow looks like this:
> 1) Create VF
> 2) Unbind VF
> 3) Switch PF to switchdev mode.
> 4) Bind VF
> 5) Set PF MTU to 9k
> 6) create vDPA device
> 7) Start VM with vDPA device and 1K queue size
> 
> Note that setting the MTU before step 3) doesn't trigger this issue.
> 
> This patch reads the forementioned umem parameters at the latest point
> possible before the VQs of the device are created.
> 
> v2:
> - Allocate output with kmalloc to reduce stack frame size.
> - Removed stable from cc.
> 
Gentle ping. Any thoughts on this fix?

Thanks,
Dragos
> Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices")
> Signed-off-by: Dragos Tatulea 
> 
> ---
>  drivers/vdpa/mlx5/net/mlx5_vnet.c | 63 ++-
>  drivers/vdpa/mlx5/net/mlx5_vnet.h |  9 +
>  2 files changed, 63 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> index 40a03b08d7cf..ef5907b1d513 100644
> --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> @@ -625,30 +625,70 @@ static void cq_destroy(struct mlx5_vdpa_net *ndev, u16
> idx)
> mlx5_db_free(ndev->mvdev.mdev, >db);
>  }
>  
> +static int read_umem_params(struct mlx5_vdpa_net *ndev)
> +{
> +   u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
> +   u16 opmod = (MLX5_CAP_VDPA_EMULATION << 1) | (HCA_CAP_OPMOD_GET_CUR &
> 0x01);
> +   struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
> +   int out_size;
> +   void *caps;
> +   void *out;
> +   int err;
> +
> +   out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out);
> +   out = kzalloc(out_size, GFP_KERNEL);
> +   if (!out)
> +   return -ENOMEM;
> +
> +   MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
> +   MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
> +   err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out);
> +   if (err) {
> +   mlx5_vdpa_warn(>mvdev,
> +   "Failed reading vdpa umem capabilities with err %d\n",
> err);
> +   goto out;
> +   }
> +
> +   caps =  MLX5_ADDR_OF(query_hca_cap_out, out, capability);
> +
> +   ndev->umem_1_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps,
> umem_1_buffer_param_a);
> +   ndev->umem_1_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps,
> umem_1_buffer_param_b);
> +
> +   ndev->umem_2_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps,
> umem_2_buffer_param_a);
> +   ndev->umem_2_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps,
> umem_2_buffer_param_b);
> +
> +   ndev->umem_3_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps,
> umem_3_buffer_param_a);
> +   ndev->umem_3_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps,
> umem_3_buffer_param_b);
> +
> +out:
> +   kfree(out);
> +   return 0;
> +}
> +
>  static void set_umem_size(struct mlx5_vdpa_net *ndev, struct
> mlx5_vdpa_virtqueue *mvq, int num,
>   struct mlx5_vdpa_umem **umemp)
>  {
> -   struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
> -   int p_a;
> -   int p_b;
> +   u32 p_a;
> +   u32 p_b;
>  
> switch (num) {
> case 1:
> -   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev,
> umem_1_buffer_param_a);
> -   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev,
> umem_1_buffer_param_b);
> +   p_a = ndev->umem_1_buffer_param_a;
> +   p_b = ndev->umem_1_buffer_param_b;
> *umemp = >umem1;
> break;
> case 2:
> -   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev,
> umem_2_buffer_param_a);
> -   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev,
> umem_2_buffer_param_b);
> +   p_a = ndev->umem_2_buffer_param_a;
> +   p_b = ndev->umem_2_buffer_param_b;
> *umemp = >umem2;
> break;
> case 3:
> -   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev,
> umem_3_buffer_param_a);
> -   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev,
> umem_3_buffer_param_b);
> +   p_a = ndev->umem_3_buffer_param_a;
> +   p_b = ndev->umem_3_buffer_param_b;
> *umemp = >umem3;
> break;
> }
> +
> (*umemp)->size = p_a * mvq->num_ent + p_b;
>  }
>  
> @@ -2679,6 +2719,11 @@ static int setup_driver(struct 

[PATCH 13/16] vdpa/mlx5: Enable hw support for vq descriptor mapping

2023-09-12 Thread Dragos Tatulea via Virtualization
Vq descriptor mappings are supported in hardware by filling in an
additional mkey which contains the descriptor mappings to the hw vq.

A previous patch in this series added support for hw mkey (mr) creation
for ASID 1.

This patch fills in both the vq data and vq descriptor mkeys based on
group ASID mapping.

The feature is signaled to the vdpa core through the presence of the
.get_vq_desc_group op.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 26 --
 include/linux/mlx5/mlx5_ifc.h  |  8 +++-
 include/linux/mlx5/mlx5_ifc_vdpa.h |  7 ++-
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 5bb9a7528b08..c5e9c84988cc 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -823,6 +823,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
struct mlx5_vdpa_dev *mvdev = >mvdev;
struct mlx5_vdpa_mr *vq_mr;
+   struct mlx5_vdpa_mr *vq_desc_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -878,6 +879,11 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
if (vq_mr)
MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
+
+   vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]];
+   if (vq_desc_mr)
+   MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey);
+
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2265,6 +2271,16 @@ static u32 mlx5_vdpa_get_vq_group(struct vdpa_device 
*vdev, u16 idx)
return MLX5_VDPA_DATAVQ_GROUP;
 }
 
+static u32 mlx5_vdpa_get_vq_desc_group(struct vdpa_device *vdev, u16 idx)
+{
+   struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+
+   if (is_ctrl_vq_idx(mvdev, idx))
+   return MLX5_VDPA_CVQ_GROUP;
+
+   return MLX5_VDPA_DATAVQ_DESC_GROUP;
+}
+
 static u64 mlx_to_vritio_features(u16 dev_features)
 {
u64 result = 0;
@@ -3139,7 +3155,7 @@ static int mlx5_set_group_asid(struct vdpa_device *vdev, 
u32 group,
 {
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
 
-   if (group >= MLX5_VDPA_NUMVQ_GROUPS)
+   if (group >= MLX5_VDPA_NUMVQ_GROUPS || asid >= MLX5_VDPA_NUM_AS)
return -EINVAL;
 
mvdev->group2asid[group] = asid;
@@ -3160,6 +3176,7 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
.get_vq_irq = mlx5_get_vq_irq,
.get_vq_align = mlx5_vdpa_get_vq_align,
.get_vq_group = mlx5_vdpa_get_vq_group,
+   .get_vq_desc_group = mlx5_vdpa_get_vq_desc_group, /* Op disabled if not 
supported. */
.get_device_features = mlx5_vdpa_get_device_features,
.set_driver_features = mlx5_vdpa_set_driver_features,
.get_driver_features = mlx5_vdpa_get_driver_features,
@@ -3258,6 +3275,7 @@ struct mlx5_vdpa_mgmtdev {
struct vdpa_mgmt_dev mgtdev;
struct mlx5_adev *madev;
struct mlx5_vdpa_net *ndev;
+   struct vdpa_config_ops vdpa_ops;
 };
 
 static int config_func_mtu(struct mlx5_core_dev *mdev, u16 mtu)
@@ -3371,7 +3389,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
max_vqs = 2;
}
 
-   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, _vdpa_ops,
+   ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, >vdpa_ops,
 MLX5_VDPA_NUMVQ_GROUPS, MLX5_VDPA_NUM_AS, 
name, false);
if (IS_ERR(ndev))
return PTR_ERR(ndev);
@@ -3546,6 +3564,10 @@ static int mlx5v_probe(struct auxiliary_device *adev,
MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues) + 1;
mgtdev->mgtdev.supported_features = get_supported_features(mdev);
mgtdev->madev = madev;
+   mgtdev->vdpa_ops = mlx5_vdpa_ops;
+
+   if (!MLX5_CAP_DEV_VDPA_EMULATION(mdev, desc_group_mkey_supported))
+   mgtdev->vdpa_ops.get_vq_desc_group = NULL;
 
err = vdpa_mgmtdev_register(>mgtdev);
if (err)
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 33344a71c3e3..db21c96e5407 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1229,7 +1229,13 @@ struct mlx5_ifc_virtio_emulation_cap_bits {
u8 max_emulated_devices[0x8];
u8 max_num_virtio_queues[0x18];
 
-   u8 reserved_at_a0[0x60];
+   u8 reserved_at_a0[0x20];
+
+   u8 reserved_at_c0[0x14];
+   u8 desc_group_mkey_supported[0x1];
+   u8 

[PATCH 12/16] vdpa/mlx5: Introduce mr for vq descriptor

2023-09-12 Thread Dragos Tatulea via Virtualization
Introduce the vq descriptor group and ASID 1. Until now .set_map on ASID
1 was only updating the cvq iotlb. From now on it also creates a mkey
for it. The current patch doesn't use it but follow-up patches will
add hardware support for mapping the vq descriptors.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  5 +++--
 drivers/vdpa/mlx5/core/mr.c| 14 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 20 +---
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index bbe4335106bd..ae09296f4270 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -70,11 +70,12 @@ struct mlx5_vdpa_wq_ent {
 enum {
MLX5_VDPA_DATAVQ_GROUP,
MLX5_VDPA_CVQ_GROUP,
+   MLX5_VDPA_DATAVQ_DESC_GROUP,
MLX5_VDPA_NUMVQ_GROUPS
 };
 
 enum {
-   MLX5_VDPA_NUM_AS = MLX5_VDPA_NUMVQ_GROUPS
+   MLX5_VDPA_NUM_AS = 2
 };
 
 struct mlx5_vdpa_dev {
@@ -89,7 +90,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr *mr;
+   struct mlx5_vdpa_mr *mr[MLX5_VDPA_NUM_AS];
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00eff5a07152..3dee6d9bed6b 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -511,8 +511,10 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   if (mvdev->mr == mr)
-   mvdev->mr = NULL;
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++) {
+   if (mvdev->mr[i] == mr)
+   mvdev->mr[i] = NULL;
+   }
 
mutex_unlock(>mr_mtx);
 
@@ -523,11 +525,11 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 struct mlx5_vdpa_mr *new_mr,
 unsigned int asid)
 {
-   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr[asid];
 
mutex_lock(>mr_mtx);
 
-   mvdev->mr = new_mr;
+   mvdev->mr[asid] = new_mr;
if (old_mr) {
_mlx5_vdpa_destroy_mr(mvdev, old_mr);
kfree(old_mr);
@@ -539,7 +541,9 @@ void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
+   for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
+
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 376581f4a750..5bb9a7528b08 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -821,6 +821,8 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
 {
int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in);
u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {};
+   struct mlx5_vdpa_dev *mvdev = >mvdev;
+   struct mlx5_vdpa_mr *vq_mr;
void *obj_context;
u16 mlx_features;
void *cmd_hdr;
@@ -873,7 +875,9 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, 
struct mlx5_vdpa_virtque
MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr);
MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr);
MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr);
-   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, ndev->mvdev.mr->mkey);
+   vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]];
+   if (vq_mr)
+   MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey);
MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id);
MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size);
MLX5_SET(virtio_q, vq_ctx, umem_2_id, mvq->umem2.id);
@@ -2633,7 +2637,8 @@ static void restore_channels_info(struct mlx5_vdpa_net 
*ndev)
 }
 
 static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *new_mr, unsigned int asid)
+   struct mlx5_vdpa_mr *new_mr,
+   unsigned int asid)
 {
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
int err;
@@ -2652,8 +2657,10 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
 
restore_channels_info(ndev);
err = setup_driver(mvdev);
+   if (err)
+   return err;
 
-   return err;
+   return 0;
 }
 
 /* reslock must be held for this function */
@@ -2869,8 +2876,8 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
struct mlx5_vdpa_mr *new_mr;
int err;
 
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   goto end;
+   if (asid >= 

[PATCH 11/16] vdpa/mlx5: Improve mr update flow

2023-09-12 Thread Dragos Tatulea via Virtualization
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.

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.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 14 +++--
 drivers/vdpa/mlx5/core/mr.c| 87 --
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 46 
 3 files changed, 76 insertions(+), 71 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 9c6ac42c21e1..bbe4335106bd 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -31,8 +31,6 @@ struct mlx5_vdpa_mr {
struct list_head head;
unsigned long num_directs;
unsigned long num_klms;
-   /* state of dvq mr */
-   bool initialized;
 
bool user_mr;
 };
@@ -91,7 +89,7 @@ struct mlx5_vdpa_dev {
u16 max_idx;
u32 generation;
 
-   struct mlx5_vdpa_mr mr;
+   struct mlx5_vdpa_mr *mr;
/* serialize mr access */
struct mutex mr_mtx;
struct mlx5_control_vq cvq;
@@ -114,14 +112,14 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev 
*mvdev);
 int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, u32 *mkey, u32 *in,
  int inlen);
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
-int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
-bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb);
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr);
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *mr,
+unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index abd6a6fb122f..00eff5a07152 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -495,30 +495,51 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
 
 static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   if (!mr->initialized)
-   return;
-
if (mr->user_mr)
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
-
-   mr->initialized = false;
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
+   if (!mr)
+   return;
+
mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
+   if (mvdev->mr == mr)
+   mvdev->mr = NULL;
+
+   mutex_unlock(>mr_mtx);
+
+   kfree(mr);
+}
+
+void mlx5_vdpa_update_mr(struct mlx5_vdpa_dev *mvdev,
+struct mlx5_vdpa_mr *new_mr,
+unsigned int asid)
+{
+   struct mlx5_vdpa_mr *old_mr = mvdev->mr;
+
+   mutex_lock(>mr_mtx);
+
+   mvdev->mr = new_mr;
+   if (old_mr) {
+   _mlx5_vdpa_destroy_mr(mvdev, old_mr);
+   kfree(old_mr);
+   }
+
mutex_unlock(>mr_mtx);
+
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr(mvdev, >mr);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->mr);
prune_iotlb(mvdev);
 }
 
@@ -528,52 +549,36 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
 {
int err;
 
-   if (mr->initialized)
-   return 0;
-
if (iotlb)
err = create_user_mr(mvdev, mr, iotlb);
else
err = create_dma_mr(mvdev, mr);
 
-   if (err)
-   return err;
-
-   mr->initialized = true;
-
-   return 0;
+   return err;
 }
 
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct mlx5_vdpa_mr *mr,
-   struct vhost_iotlb *iotlb)
+struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+struct vhost_iotlb *iotlb)
 {
+   struct mlx5_vdpa_mr *mr;
int 

[PATCH 14/16] vdpa/mlx5: Make iotlb helper functions more generic

2023-09-12 Thread Dragos Tatulea via Virtualization
They will be used in a followup patch.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 3dee6d9bed6b..a4135c16b5bf 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -454,20 +454,20 @@ static void destroy_dma_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr)
mlx5_vdpa_destroy_mkey(mvdev, mr->mkey);
 }
 
-static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *src)
+static int dup_iotlb(struct vhost_iotlb *iotlb, struct vhost_iotlb *src)
 {
struct vhost_iotlb_map *map;
u64 start = 0, last = ULLONG_MAX;
int err;
 
if (!src) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, start, last, 
start, VHOST_ACCESS_RW);
+   err = vhost_iotlb_add_range(iotlb, start, last, start, 
VHOST_ACCESS_RW);
return err;
}
 
for (map = vhost_iotlb_itree_first(src, start, last); map;
map = vhost_iotlb_itree_next(map, start, last)) {
-   err = vhost_iotlb_add_range(mvdev->cvq.iotlb, map->start, 
map->last,
+   err = vhost_iotlb_add_range(iotlb, map->start, map->last,
map->addr, map->perm);
if (err)
return err;
@@ -475,9 +475,9 @@ static int dup_iotlb(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *src)
return 0;
 }
 
-static void prune_iotlb(struct mlx5_vdpa_dev *mvdev)
+static void prune_iotlb(struct vhost_iotlb *iotlb)
 {
-   vhost_iotlb_del_range(mvdev->cvq.iotlb, 0, ULLONG_MAX);
+   vhost_iotlb_del_range(iotlb, 0, ULLONG_MAX);
 }
 
 static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr 
*mr)
@@ -544,7 +544,7 @@ void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev 
*mvdev)
for (int i = 0; i < MLX5_VDPA_NUM_AS; i++)
mlx5_vdpa_destroy_mr(mvdev, mvdev->mr[i]);
 
-   prune_iotlb(mvdev);
+   prune_iotlb(mvdev->cvq.iotlb);
 }
 
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
@@ -596,8 +596,8 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
 
spin_lock(>cvq.iommu_lock);
 
-   prune_iotlb(mvdev);
-   err = dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev->cvq.iotlb);
+   err = dup_iotlb(mvdev->cvq.iotlb, iotlb);
 
spin_unlock(>cvq.iommu_lock);
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 15/16] vdpa/mlx5: Update cvq iotlb mapping on ASID change

2023-09-12 Thread Dragos Tatulea via Virtualization
For the following sequence:
- cvq group is in ASID 0
- .set_map(1, cvq_iotlb)
- .set_group_asid(cvq_group, 1)

... the cvq mapping from ASID 0 will be used. This is not always correct
behaviour.

This patch adds support for the above mentioned flow by saving the iotlb
on each .set_map and updating the cvq iotlb with it on a cvq group change.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  2 ++
 drivers/vdpa/mlx5/core/mr.c| 26 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  9 -
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ae09296f4270..db988ced5a5d 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -32,6 +32,8 @@ struct mlx5_vdpa_mr {
unsigned long num_directs;
unsigned long num_klms;
 
+   struct vhost_iotlb *iotlb;
+
bool user_mr;
 };
 
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index a4135c16b5bf..403c08271489 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -499,6 +499,8 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
destroy_user_mr(mvdev, mr);
else
destroy_dma_mr(mvdev, mr);
+
+   vhost_iotlb_free(mr->iotlb);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
@@ -558,6 +560,30 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 
*mvdev,
else
err = create_dma_mr(mvdev, mr);
 
+   if (err)
+   return err;
+
+   mr->iotlb = vhost_iotlb_alloc(0, 0);
+   if (!mr->iotlb) {
+   err = -ENOMEM;
+   goto err_mr;
+   }
+
+   err = dup_iotlb(mr->iotlb, iotlb);
+   if (err)
+   goto err_iotlb;
+
+   return 0;
+
+err_iotlb:
+   vhost_iotlb_free(mr->iotlb);
+
+err_mr:
+   if (iotlb)
+   destroy_user_mr(mvdev, mr);
+   else
+   destroy_dma_mr(mvdev, mr);
+
return err;
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index c5e9c84988cc..606938e2acbc 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -3154,12 +3154,19 @@ static int mlx5_set_group_asid(struct vdpa_device 
*vdev, u32 group,
   unsigned int asid)
 {
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
+   int err = 0;
 
if (group >= MLX5_VDPA_NUMVQ_GROUPS || asid >= MLX5_VDPA_NUM_AS)
return -EINVAL;
 
mvdev->group2asid[group] = asid;
-   return 0;
+
+   mutex_lock(>mr_mtx);
+   if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid])
+   err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, 
asid);
+   mutex_unlock(>mr_mtx);
+
+   return err;
 }
 
 static const struct vdpa_config_ops mlx5_vdpa_ops = {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 10/16] vdpa/mlx5: Move mr mutex out of mr struct

2023-09-12 Thread Dragos Tatulea via Virtualization
The mutex is named like it is supposed to protect only the mkey but in
reality it is a global lock for all mr resources.

Shift the mutex to it's rightful location (struct mlx5_vdpa_dev) and
give it a more appropriate name.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c| 13 +++--
 drivers/vdpa/mlx5/core/resources.c |  6 +++---
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 01d4ee58ccb1..9c6ac42c21e1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -34,8 +34,6 @@ struct mlx5_vdpa_mr {
/* state of dvq mr */
bool initialized;
 
-   /* serialize mkey creation and destruction */
-   struct mutex mkey_mtx;
bool user_mr;
 };
 
@@ -94,6 +92,8 @@ struct mlx5_vdpa_dev {
u32 generation;
 
struct mlx5_vdpa_mr mr;
+   /* serialize mr access */
+   struct mutex mr_mtx;
struct mlx5_control_vq cvq;
struct workqueue_struct *wq;
unsigned int group2asid[MLX5_VDPA_NUMVQ_GROUPS];
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 6f29e8eaabb1..abd6a6fb122f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -509,11 +509,11 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, struct mlx5_vdpa_
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
  struct mlx5_vdpa_mr *mr)
 {
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
 
_mlx5_vdpa_destroy_mr(mvdev, mr);
 
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 }
 
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
@@ -550,9 +550,10 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
 {
int err;
 
-   mutex_lock(>mr.mkey_mtx);
+   mutex_lock(>mr_mtx);
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mr.mkey_mtx);
+   mutex_unlock(>mr_mtx);
+
return err;
 }
 
@@ -563,14 +564,14 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
int err = 0;
 
*change_map = false;
-   mutex_lock(>mkey_mtx);
+   mutex_lock(>mr_mtx);
if (mr->initialized) {
mlx5_vdpa_info(mvdev, "memory map update\n");
*change_map = true;
}
if (!*change_map)
err = _mlx5_vdpa_create_mr(mvdev, mr, iotlb);
-   mutex_unlock(>mkey_mtx);
+   mutex_unlock(>mr_mtx);
 
return err;
 }
diff --git a/drivers/vdpa/mlx5/core/resources.c 
b/drivers/vdpa/mlx5/core/resources.c
index d5a59c9035fb..5c5a41b64bfc 100644
--- a/drivers/vdpa/mlx5/core/resources.c
+++ b/drivers/vdpa/mlx5/core/resources.c
@@ -256,7 +256,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
mlx5_vdpa_warn(mvdev, "resources already allocated\n");
return -EINVAL;
}
-   mutex_init(>mr.mkey_mtx);
+   mutex_init(>mr_mtx);
res->uar = mlx5_get_uars_page(mdev);
if (IS_ERR(res->uar)) {
err = PTR_ERR(res->uar);
@@ -301,7 +301,7 @@ int mlx5_vdpa_alloc_resources(struct mlx5_vdpa_dev *mvdev)
 err_uctx:
mlx5_put_uars_page(mdev, res->uar);
 err_uars:
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
return err;
 }
 
@@ -318,6 +318,6 @@ void mlx5_vdpa_free_resources(struct mlx5_vdpa_dev *mvdev)
dealloc_pd(mvdev, res->pdn, res->uid);
destroy_uctx(mvdev, res->uid);
mlx5_put_uars_page(mvdev->mdev, res->uar);
-   mutex_destroy(>mr.mkey_mtx);
+   mutex_destroy(>mr_mtx);
res->valid = false;
 }
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 05/16] vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code

2023-09-12 Thread Dragos Tatulea via Virtualization
The handling of the cvq iotlb is currently coupled with the creation
and destruction of the hardware mkeys (mr).

This patch moves cvq iotlb handling into its own function and shifts it
to a scope that is not related to mr handling. As cvq handling is just a
prune_iotlb + dup_iotlb cycle, put it all in the same "update" function.
Finally, the destruction path is handled by directly pruning the iotlb.

After this move is done the ASID mr code can be collapsed into a single
function.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  3 ++
 drivers/vdpa/mlx5/core/mr.c| 57 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  |  7 ++--
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 3748f027cfe9..554899a80241 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,9 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid);
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 7bd0883b8b25..fcb6ae32e9ed 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,14 +489,6 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return;
-
-   prune_iotlb(mvdev);
-}
-
 static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
@@ -522,25 +514,14 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid)
mutex_lock(>mkey_mtx);
 
_mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
 
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]);
mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
-}
-
-static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
-{
-   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
-   return 0;
-
-   return dup_iotlb(mvdev, iotlb);
+   prune_iotlb(mvdev);
 }
 
 static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
@@ -572,22 +553,7 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
 static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb, unsigned int asid)
 {
-   int err;
-
-   err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-   if (err)
-   return err;
-
-   err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
-   if (err)
-   goto out_err;
-
-   return 0;
-
-out_err:
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
-
-   return err;
+   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
 }
 
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
@@ -620,7 +586,24 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
return err;
 }
 
+int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
+{
+   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
+   return 0;
+
+   prune_iotlb(mvdev);
+   return dup_iotlb(mvdev, iotlb);
+}
+
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
 {
-   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   int err;
+
+   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   if (err)
+   return err;
+
+   return mlx5_vdpa_update_cvq_iotlb(mvdev, NULL, 0);
 }
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index d34c19b4e139..061d8f7a661a 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2884,10 +2884,13 @@ static int set_map_data(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb,
return err;
}
 
-   if (change_map)
+   if (change_map) {
 

[PATCH 08/16] vdpa/mlx5: Rename mr destroy functions

2023-09-12 Thread Dragos Tatulea via Virtualization
Make mlx5_destroy_mr symmetric to mlx5_create_mr.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  4 ++--
 drivers/vdpa/mlx5/core/mr.c|  6 +++---
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 12 ++--
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index 554899a80241..e1e6e7aba50e 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -118,8 +118,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 bool *change_map, unsigned int asid);
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fde00497f4ad..00dcce190a1f 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -507,7 +507,7 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -518,9 +518,9 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
mutex_unlock(>mkey_mtx);
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
+void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev)
 {
-   mlx5_vdpa_destroy_mr_asid(mvdev, 
mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
+   mlx5_vdpa_destroy_mr(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
prune_iotlb(mvdev);
 }
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 061d8f7a661a..4d759ab96319 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2644,7 +2644,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
goto err_mr;
 
teardown_driver(ndev);
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
if (err)
goto err_mr;
@@ -2660,7 +2660,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 
 err_setup:
-   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
+   mlx5_vdpa_destroy_mr(mvdev, asid);
 err_mr:
return err;
 }
@@ -2797,7 +2797,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device 
*vdev, u8 status)
 err_driver:
unregister_link_notifier(ndev);
 err_setup:
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
 err_clear:
up_write(>reslock);
@@ -2824,7 +2824,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
unregister_link_notifier(ndev);
teardown_driver(ndev);
clear_vqs_ready(ndev);
-   mlx5_vdpa_destroy_mr(>mvdev);
+   mlx5_vdpa_destroy_mr_resources(>mvdev);
ndev->mvdev.status = 0;
ndev->mvdev.suspended = false;
ndev->cur_num_vqs = 0;
@@ -2944,7 +2944,7 @@ static void mlx5_vdpa_free(struct vdpa_device *vdev)
ndev = to_mlx5_vdpa_ndev(mvdev);
 
free_resources(ndev);
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
if (!is_zero_ether_addr(ndev->config.mac)) {
pfmdev = pci_get_drvdata(pci_physfn(mvdev->mdev->pdev));
mlx5_mpfs_del_mac(pfmdev, ndev->config.mac);
@@ -3474,7 +3474,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
 err_res2:
free_resources(ndev);
 err_mr:
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_resources(mvdev);
 err_res:
mlx5_vdpa_free_resources(>mvdev);
 err_mpfs:
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 07/16] vdpa/mlx5: Collapse "dvq" mr add/delete functions

2023-09-12 Thread Dragos Tatulea via Virtualization
Now that the cvq code is out of mlx5_vdpa_create/destroy_mr, the "dvq"
functions can be folded into their callers.

Having "dvq" in the naming will no longer be accurate in the downstream
patches.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 16 +---
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 587300e7c18e..fde00497f4ad 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -489,7 +489,7 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
@@ -513,7 +513,7 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, 
unsigned int asid)
 
mutex_lock(>mkey_mtx);
 
-   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
+   _mlx5_vdpa_destroy_mr(mvdev, asid);
 
mutex_unlock(>mkey_mtx);
 }
@@ -524,9 +524,9 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
prune_iotlb(mvdev);
 }
 
-static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb,
-   unsigned int asid)
+static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct vhost_iotlb *iotlb,
+   unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
int err;
@@ -550,12 +550,6 @@ static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 }
 
-static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
-   struct vhost_iotlb *iotlb, unsigned int asid)
-{
-   return _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
-}
-
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid)
 {
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 09/16] vdpa/mlx5: Allow creation/deletion of any given mr struct

2023-09-12 Thread Dragos Tatulea via Virtualization
This patch adapts the mr creation/deletion code to be able to work with
any given mr struct pointer. All the APIs are adapted to take an extra
parameter for the mr.

mlx5_vdpa_create/delete_mr doesn't need a ASID parameter anymore. The
check is done in the caller instead (mlx5_set_map).

This change is needed for a followup patch which will introduce an
additional mr for the vq descriptor data.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  8 +++--
 drivers/vdpa/mlx5/core/mr.c| 53 ++
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 10 --
 3 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index e1e6e7aba50e..01d4ee58ccb1 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -116,10 +116,12 @@ int mlx5_vdpa_create_mkey(struct mlx5_vdpa_dev *mvdev, 
u32 *mkey, u32 *in,
 int mlx5_vdpa_destroy_mkey(struct mlx5_vdpa_dev *mvdev, u32 mkey);
 int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb,
 bool *change_map, unsigned int asid);
-int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
-   unsigned int asid);
+int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   struct vhost_iotlb *iotlb);
 void mlx5_vdpa_destroy_mr_resources(struct mlx5_vdpa_dev *mvdev);
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr);
 int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev *mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid);
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 00dcce190a1f..6f29e8eaabb1 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -301,10 +301,13 @@ static void unmap_direct_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_direct
sg_free_table(>sg_head);
 }
 
-static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, u64 start, u64 size, 
u8 perm,
+static int add_direct_chain(struct mlx5_vdpa_dev *mvdev,
+   struct mlx5_vdpa_mr *mr,
+   u64 start,
+   u64 size,
+   u8 perm,
struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
LIST_HEAD(tmp);
@@ -354,9 +357,10 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, 
u64 start, u64 size, u8
  * indirect memory key that provides access to the enitre address space given
  * by iotlb.
  */
-static int create_user_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb 
*iotlb)
+static int create_user_mr(struct mlx5_vdpa_dev *mvdev,
+ struct mlx5_vdpa_mr *mr,
+ struct vhost_iotlb *iotlb)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
struct mlx5_vdpa_direct_mr *dmr;
struct mlx5_vdpa_direct_mr *n;
struct vhost_iotlb_map *map;
@@ -384,7 +388,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
   
LOG_MAX_KLM_SIZE);
mr->num_klms += nnuls;
}
-   err = add_direct_chain(mvdev, ps, pe - ps, 
pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, 
pperm, iotlb);
if (err)
goto err_chain;
}
@@ -393,7 +397,7 @@ static int create_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *iotlb
pperm = map->perm;
}
}
-   err = add_direct_chain(mvdev, ps, pe - ps, pperm, iotlb);
+   err = add_direct_chain(mvdev, mr, ps, pe - ps, pperm, iotlb);
if (err)
goto err_chain;
 
@@ -489,13 +493,8 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, 
struct mlx5_vdpa_mr *mr
}
 }
 
-static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int 
asid)
+static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct 
mlx5_vdpa_mr *mr)
 {
-   struct mlx5_vdpa_mr *mr = >mr;
-
-   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
-   return;
-
if (!mr->initialized)
return;
 
@@ -507,38 +506,33 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int asid
mr->initialized = false;
 }
 
-void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
+void 

[PATCH 06/16] vdpa/mlx5: Take cvq iotlb lock during refresh

2023-09-12 Thread Dragos Tatulea via Virtualization
The reslock is taken while refresh is called but iommu_lock is more
specific to this resource. So take the iommu_lock during cvq iotlb
refresh.

Based on Eugenio's patch [0].

[0] https://lore.kernel.org/lkml/20230112142218.725622-4-epere...@redhat.com/

Suggested-by: Eugenio Pérez 
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mr.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index fcb6ae32e9ed..587300e7c18e 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -590,11 +590,19 @@ int mlx5_vdpa_update_cvq_iotlb(struct mlx5_vdpa_dev 
*mvdev,
struct vhost_iotlb *iotlb,
unsigned int asid)
 {
+   int err;
+
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
return 0;
 
+   spin_lock(>cvq.iommu_lock);
+
prune_iotlb(mvdev);
-   return dup_iotlb(mvdev, iotlb);
+   err = dup_iotlb(mvdev, iotlb);
+
+   spin_unlock(>cvq.iommu_lock);
+
+   return err;
 }
 
 int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 01/16] vdpa: introduce dedicated descriptor group for virtqueue

2023-09-12 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

In some cases, the access to the virtqueue's descriptor area, device
and driver areas (precluding indirect descriptor table in guest memory)
may have to be confined to a different address space than where its
buffers reside. Without loss of simplicity and generality with already
established terminology, let's fold up these 3 areas and call them
as a whole as descriptor table group, or descriptor group for short.
Specifically, in case of split virtqueues, descriptor group consists of
regions for Descriptor Table, Available Ring and Used Ring; for packed
virtqueues layout, descriptor group contains Descriptor Ring, Driver
and Device Event Suppression structures.

The group ID for a dedicated descriptor group can be obtained through a
new .get_vq_desc_group() op. If driver implements this op, it means that
the descriptor, device and driver areas of the virtqueue may reside
in a dedicated group than where its buffers reside, a.k.a the default
virtqueue group through the .get_vq_group() op.

In principle, the descriptor group may or may not have same group ID
as the default group. Even if the descriptor group has a different ID,
meaning the vq's descriptor group areas can optionally move to a
separate address space than where guest memory resides, the descriptor
group may still start from a default address space, same as where its
buffers reside. To move the descriptor group to a different address
space, .set_group_asid() has to be called to change the ASID binding
for the group, which is no different than what needs to be done on any
other virtqueue group. On the other hand, the .reset() semantics also
applies on descriptor table group, meaning the device reset will clear
all ASID bindings and move all virtqueue groups including descriptor
group back to the default address space, i.e. in ASID 0.

QEMU's shadow virtqueue is going to utilize dedicated descriptor group
to speed up map and unmap operations, yielding tremendous downtime
reduction by avoiding the full and slow remap cycle in SVQ switching.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 include/linux/vdpa.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
index 0e652026b776..d376309b99cf 100644
--- a/include/linux/vdpa.h
+++ b/include/linux/vdpa.h
@@ -204,6 +204,16 @@ struct vdpa_map_file {
  * @vdev: vdpa device
  * @idx: virtqueue index
  * Returns u32: group id for this virtqueue
+ * @get_vq_desc_group: Get the group id for the descriptor table of
+ * a specific virtqueue (optional)
+ * @vdev: vdpa device
+ * @idx: virtqueue index
+ * Returns u32: group id for the descriptor table
+ * portion of this virtqueue. Could be different
+ * than the one from @get_vq_group, in which case
+ * the access to the descriptor table can be
+ * confined to a separate asid, isolating from
+ * the virtqueue's buffer address access.
  * @get_device_features:   Get virtio features supported by the device
  * @vdev: vdpa device
  * Returns the virtio features support by the
@@ -360,6 +370,7 @@ struct vdpa_config_ops {
/* Device ops */
u32 (*get_vq_align)(struct vdpa_device *vdev);
u32 (*get_vq_group)(struct vdpa_device *vdev, u16 idx);
+   u32 (*get_vq_desc_group)(struct vdpa_device *vdev, u16 idx);
u64 (*get_device_features)(struct vdpa_device *vdev);
u64 (*get_backend_features)(const struct vdpa_device *vdev);
int (*set_driver_features)(struct vdpa_device *vdev, u64 features);
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 02/16] vhost-vdpa: introduce descriptor group backend feature

2023-09-12 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

Userspace knows if the device has dedicated descriptor group or not
by checking this feature bit.

It's only exposed if the vdpa driver backend implements the
.get_vq_desc_group() operation callback. Userspace trying to negotiate
this feature when it or the dependent _F_IOTLB_ASID feature hasn't
been exposed will result in an error.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c | 17 +
 include/uapi/linux/vhost_types.h |  5 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 78379ffd2336..2f21798a37ee 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -389,6 +389,14 @@ static bool vhost_vdpa_can_resume(const struct vhost_vdpa 
*v)
return ops->resume;
 }
 
+static bool vhost_vdpa_has_desc_group(const struct vhost_vdpa *v)
+{
+   struct vdpa_device *vdpa = v->vdpa;
+   const struct vdpa_config_ops *ops = vdpa->config;
+
+   return ops->get_vq_desc_group;
+}
+
 static long vhost_vdpa_get_features(struct vhost_vdpa *v, u64 __user *featurep)
 {
struct vdpa_device *vdpa = v->vdpa;
@@ -690,6 +698,7 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if (copy_from_user(, featurep, sizeof(features)))
return -EFAULT;
if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
+BIT_ULL(VHOST_BACKEND_F_DESC_ASID) |
 BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
 BIT_ULL(VHOST_BACKEND_F_RESUME) |
 
BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))
@@ -700,6 +709,12 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
if ((features & BIT_ULL(VHOST_BACKEND_F_RESUME)) &&
 !vhost_vdpa_can_resume(v))
return -EOPNOTSUPP;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+   !(features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)))
+   return -EINVAL;
+   if ((features & BIT_ULL(VHOST_BACKEND_F_DESC_ASID)) &&
+!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
vhost_set_backend_features(>vdev, features);
return 0;
}
@@ -753,6 +768,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
features |= BIT_ULL(VHOST_BACKEND_F_SUSPEND);
if (vhost_vdpa_can_resume(v))
features |= BIT_ULL(VHOST_BACKEND_F_RESUME);
+   if (vhost_vdpa_has_desc_group(v))
+   features |= BIT_ULL(VHOST_BACKEND_F_DESC_ASID);
features |= vhost_vdpa_get_backend_features(v);
if (copy_to_user(featurep, , sizeof(features)))
r = -EFAULT;
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
index 2d827d22cd99..18ad6ae7ab5c 100644
--- a/include/uapi/linux/vhost_types.h
+++ b/include/uapi/linux/vhost_types.h
@@ -185,5 +185,10 @@ struct vhost_vdpa_iova_range {
  * DRIVER_OK
  */
 #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK  0x6
+/* Device may expose the virtqueue's descriptor area, driver area and
+ * device area to a different group for ASID binding than where its
+ * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID.
+ */
+#define VHOST_BACKEND_F_DESC_ASID0x7
 
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 04/16] vdpa/mlx5: Create helper function for dma mappings

2023-09-12 Thread Dragos Tatulea via Virtualization
Necessary for upcoming cvq separation from mr allocation.

Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 1 +
 drivers/vdpa/mlx5/core/mr.c| 5 +
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 4 ++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index ca56242972b3..3748f027cfe9 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -120,6 +120,7 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct 
vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
 void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, 
__func__, __LINE__, \
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 5a1971fcd87b..7bd0883b8b25 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -619,3 +619,8 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 
return err;
 }
+
+int mlx5_vdpa_create_dma_mr(struct mlx5_vdpa_dev *mvdev)
+{
+   return mlx5_vdpa_create_mr(mvdev, NULL, 0);
+}
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 37be945a0230..d34c19b4e139 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2836,7 +2836,7 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev)
++mvdev->generation;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   if (mlx5_vdpa_create_mr(mvdev, NULL, 0))
+   if (mlx5_vdpa_create_dma_mr(mvdev))
mlx5_vdpa_warn(mvdev, "create MR failed\n");
}
up_write(>reslock);
@@ -3441,7 +3441,7 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev 
*v_mdev, const char *name,
goto err_mpfs;
 
if (MLX5_CAP_GEN(mvdev->mdev, umem_uid_0)) {
-   err = mlx5_vdpa_create_mr(mvdev, NULL, 0);
+   err = mlx5_vdpa_create_dma_mr(mvdev);
if (err)
goto err_res;
}
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 03/16] vhost-vdpa: uAPI to get dedicated descriptor group id

2023-09-12 Thread Dragos Tatulea via Virtualization
From: Si-Wei Liu 

With _F_DESC_ASID backend feature, the device can now support the
VHOST_VDPA_GET_VRING_DESC_GROUP ioctl, and it may expose the descriptor
table (including avail and used ring) in a different group than the
buffers it contains. This new uAPI will fetch the group ID of the
descriptor table.

Signed-off-by: Si-Wei Liu 
Acked-by: Eugenio Pérez 
Acked-by: Jason Wang 
---
 drivers/vhost/vdpa.c   | 10 ++
 include/uapi/linux/vhost.h |  8 
 2 files changed, 18 insertions(+)

diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 2f21798a37ee..851535f57b95 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -613,6 +613,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, 
unsigned int cmd,
else if (copy_to_user(argp, , sizeof(s)))
return -EFAULT;
return 0;
+   case VHOST_VDPA_GET_VRING_DESC_GROUP:
+   if (!vhost_vdpa_has_desc_group(v))
+   return -EOPNOTSUPP;
+   s.index = idx;
+   s.num = ops->get_vq_desc_group(vdpa, idx);
+   if (s.num >= vdpa->ngroups)
+   return -EIO;
+   else if (copy_to_user(argp, , sizeof(s)))
+   return -EFAULT;
+   return 0;
case VHOST_VDPA_SET_GROUP_ASID:
if (copy_from_user(, argp, sizeof(s)))
return -EFAULT;
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index f5c48b61ab62..649560c685f1 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -219,4 +219,12 @@
  */
 #define VHOST_VDPA_RESUME  _IO(VHOST_VIRTIO, 0x7E)
 
+/* Get the group for the descriptor table including driver & device areas
+ * of a virtqueue: read index, write group in num.
+ * The virtqueue index is stored in the index field of vhost_vring_state.
+ * The group ID of the descriptor table for this specific virtqueue
+ * is returned via num field of vhost_vring_state.
+ */
+#define VHOST_VDPA_GET_VRING_DESC_GROUP_IOWR(VHOST_VIRTIO, 0x7F,   
\
+ struct vhost_vring_state)
 #endif
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 00/16] vdpa: Add support for vq descriptor mappings

2023-09-12 Thread Dragos Tatulea via Virtualization
This patch series adds support for vq descriptor table mappings which
are used to improve vdpa live migration downtime. The improvement comes
from using smaller mappings which take less time to create and destroy
in hw.

The first part adds the vdpa core changes from Si-Wei [0].

The second part adds support in mlx5_vdpa:
- Refactor the mr code to be able to cleanly add descriptor mappings.
- Add hardware descriptor mr support.
- Properly update iotlb for cvq during ASID switch.

[0] 
https://lore.kernel.org/virtualization/1694248959-13369-1-git-send-email-si-wei@oracle.com

Dragos Tatulea (13):
  vdpa/mlx5: Create helper function for dma mappings
  vdpa/mlx5: Decouple cvq iotlb handling from hw mapping code
  vdpa/mlx5: Take cvq iotlb lock during refresh
  vdpa/mlx5: Collapse "dvq" mr add/delete functions
  vdpa/mlx5: Rename mr destroy functions
  vdpa/mlx5: Allow creation/deletion of any given mr struct
  vdpa/mlx5: Move mr mutex out of mr struct
  vdpa/mlx5: Improve mr update flow
  vdpa/mlx5: Introduce mr for vq descriptor
  vdpa/mlx5: Enable hw support for vq descriptor mapping
  vdpa/mlx5: Make iotlb helper functions more generic
  vdpa/mlx5: Update cvq iotlb mapping on ASID change
  Cover letter: vdpa/mlx5: Add support for vq descriptor mappings

Si-Wei Liu (3):
  vdpa: introduce dedicated descriptor group for virtqueue
  vhost-vdpa: introduce descriptor group backend feature
  vhost-vdpa: uAPI to get dedicated descriptor group id

 drivers/vdpa/mlx5/core/mlx5_vdpa.h |  31 +++--
 drivers/vdpa/mlx5/core/mr.c| 191 -
 drivers/vdpa/mlx5/core/resources.c |   6 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 100 ++-
 drivers/vhost/vdpa.c   |  27 
 include/linux/mlx5/mlx5_ifc.h  |   8 +-
 include/linux/mlx5/mlx5_ifc_vdpa.h |   7 +-
 include/linux/vdpa.h   |  11 ++
 include/uapi/linux/vhost.h |   8 ++
 include/uapi/linux/vhost_types.h   |   5 +
 10 files changed, 264 insertions(+), 130 deletions(-)

-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH RFC v2 0/3] vdpa: dedicated descriptor table group

2023-09-11 Thread Dragos Tatulea via Virtualization
Hi Jason,

On Mon, 2023-09-11 at 14:43 +0800, Jason Wang wrote:
> On Sat, Sep 9, 2023 at 4:45 PM Si-Wei Liu  wrote:
> > 
> > Following patchset introduces dedicated group for descriptor table to
> > reduce live migration downtime when passthrough VQ is being switched
> > to shadow VQ. This RFC v2 is sent to incorporate the early feedback
> > from reviewers on the uAPI and driver API part of changes, the
> > associated driver patch set consuming ths API will come around
> > soon along with formal submission of this series.
> > 
> > Some initial performance data will be gathered using the real
> > hardware device with mlx5_vdpa. The target goal of this series is to
> > reduce the SVQ switching overhead to less than 300ms on a ~100GB
> > guest with 2 non-mq vhost-vdpa devices. The reduction in the downtime
> > is thanks to avoiding the full remap in the switching.
> > 
> > The plan of the intended driver implementation is to use a dedicated
> > group (specifically, 2 in below table) to host the descriptor tables
> > for data vqs, different from where buffer addresses are contained (in
> > group 0 as below). cvq does not have to allocate dedicated group for
> > descriptor table, so its buffers and descriptor table would always
> > belong to the same group (1 in table below).
> > 
> > 
> >   |  data vq | ctrl vq
> > ==+==+===
> > vq_group  |    0 |    1
> > vq_desc_group |    2 |    1
> > 
> > 
> > ---
> > 
> > Si-Wei Liu (3):
> >   vdpa: introduce dedicated descriptor group for virtqueue
> >   vhost-vdpa: introduce descriptor group backend feature
> >   vhost-vdpa: uAPI to get dedicated descriptor group id
> 
> Looks good to me but I'd expect example implementations in the parent.
> 
We (Si-Wei and I) will send a non-RFC series with the mlx5_vdpa implementation
as soon as the submission window opens.

Can we add your Acked-by for these core patches?

Thanks,
Dragos
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH v2] vdpa/mlx5: Fix firmware error on creation of 1k VQs

2023-08-31 Thread Dragos Tatulea via Virtualization
A firmware error is triggered when configuring a 9k MTU on the PF after
switching to switchdev mode and then using a vdpa device with larger
(1k) rings:
mlx5_cmd_out_err: CREATE_GENERAL_OBJECT(0xa00) op_mod(0xd) failed, status bad 
resource(0x5), syndrome (0xf6db90), err(-22)

This is due to the fact that the hw VQ size parameters are computed
based on the umem_1/2/3_buffer_param_a/b capabilities and all
device capabilities are read only when the driver is moved to switchdev mode.

The problematic configuration flow looks like this:
1) Create VF
2) Unbind VF
3) Switch PF to switchdev mode.
4) Bind VF
5) Set PF MTU to 9k
6) create vDPA device
7) Start VM with vDPA device and 1K queue size

Note that setting the MTU before step 3) doesn't trigger this issue.

This patch reads the forementioned umem parameters at the latest point
possible before the VQs of the device are created.

v2:
- Allocate output with kmalloc to reduce stack frame size.
- Removed stable from cc.

Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices")
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c | 63 ++-
 drivers/vdpa/mlx5/net/mlx5_vnet.h |  9 +
 2 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 40a03b08d7cf..ef5907b1d513 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -625,30 +625,70 @@ static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 
idx)
mlx5_db_free(ndev->mvdev.mdev, >db);
 }
 
+static int read_umem_params(struct mlx5_vdpa_net *ndev)
+{
+   u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
+   u16 opmod = (MLX5_CAP_VDPA_EMULATION << 1) | (HCA_CAP_OPMOD_GET_CUR & 
0x01);
+   struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
+   int out_size;
+   void *caps;
+   void *out;
+   int err;
+
+   out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out);
+   out = kzalloc(out_size, GFP_KERNEL);
+   if (!out)
+   return -ENOMEM;
+
+   MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
+   MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
+   err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out);
+   if (err) {
+   mlx5_vdpa_warn(>mvdev,
+   "Failed reading vdpa umem capabilities with err %d\n", 
err);
+   goto out;
+   }
+
+   caps =  MLX5_ADDR_OF(query_hca_cap_out, out, capability);
+
+   ndev->umem_1_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, 
umem_1_buffer_param_a);
+   ndev->umem_1_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, 
umem_1_buffer_param_b);
+
+   ndev->umem_2_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, 
umem_2_buffer_param_a);
+   ndev->umem_2_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, 
umem_2_buffer_param_b);
+
+   ndev->umem_3_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, 
umem_3_buffer_param_a);
+   ndev->umem_3_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, 
umem_3_buffer_param_b);
+
+out:
+   kfree(out);
+   return 0;
+}
+
 static void set_umem_size(struct mlx5_vdpa_net *ndev, struct 
mlx5_vdpa_virtqueue *mvq, int num,
  struct mlx5_vdpa_umem **umemp)
 {
-   struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
-   int p_a;
-   int p_b;
+   u32 p_a;
+   u32 p_b;
 
switch (num) {
case 1:
-   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_a);
-   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_b);
+   p_a = ndev->umem_1_buffer_param_a;
+   p_b = ndev->umem_1_buffer_param_b;
*umemp = >umem1;
break;
case 2:
-   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_a);
-   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_b);
+   p_a = ndev->umem_2_buffer_param_a;
+   p_b = ndev->umem_2_buffer_param_b;
*umemp = >umem2;
break;
case 3:
-   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_a);
-   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_b);
+   p_a = ndev->umem_3_buffer_param_a;
+   p_b = ndev->umem_3_buffer_param_b;
*umemp = >umem3;
break;
}
+
(*umemp)->size = p_a * mvq->num_ent + p_b;
 }
 
@@ -2679,6 +2719,11 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
goto out;
}
mlx5_vdpa_add_debugfs(ndev);
+
+   err = read_umem_params(ndev);
+   if (err)
+   goto err_setup;
+
err = setup_virtqueues(mvdev);
if (err) {
mlx5_vdpa_warn(mvdev, "setup_virtqueues\n");
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.h 

[PATCH] vdpa/mlx5: Fix firmware error on creation of 1k VQs

2023-08-29 Thread Dragos Tatulea via Virtualization
A firmware error is triggered when configuring a 9k MTU on the PF after
switching to switchdev mode and then using a vdpa device with larger
(1k) rings:
mlx5_cmd_out_err: CREATE_GENERAL_OBJECT(0xa00) op_mod(0xd) failed, status bad 
resource(0x5), syndrome (0xf6db90), err(-22)

This is due to the fact that the hw VQ size parameters are computed
based on the umem_1/2/3_buffer_param_a/b capabilities and all
device capabilities are read only when the driver is moved to switchdev mode.

The problematic configuration flow looks like this:
1) Create VF
2) Unbind VF
3) Switch PF to switchdev mode.
4) Bind VF
5) Set PF MTU to 9k
6) create vDPA device
7) Start VM with vDPA device and 1K queue size

Note that setting the MTU before step 3) doesn't trigger this issue.

This patch reads the forementioned umem parameters at the latest point
possible before the VQs of the device are created.

Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices")
Signed-off-by: Dragos Tatulea 
Reviewed-by: Saeed Mahameed 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c | 55 ++-
 drivers/vdpa/mlx5/net/mlx5_vnet.h |  9 +
 2 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 37be945a0230..85855680b24c 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -625,30 +625,62 @@ static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 
idx)
mlx5_db_free(ndev->mvdev.mdev, >db);
 }
 
+static int read_umem_params(struct mlx5_vdpa_net *ndev)
+{
+   u32 out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {};
+   u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {};
+   u16 opmod = (MLX5_CAP_VDPA_EMULATION << 1) | (HCA_CAP_OPMOD_GET_CUR & 
0x01);
+   struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
+   void *caps;
+   int err;
+
+   MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
+   MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
+   err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out);
+   if (err) {
+   mlx5_vdpa_warn(>mvdev,
+   "Failed reading vdpa umem capabilities with err %d\n", 
err);
+   return err;
+   }
+
+   caps =  MLX5_ADDR_OF(query_hca_cap_out, out, capability);
+
+   ndev->umem_1_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, 
umem_1_buffer_param_a);
+   ndev->umem_1_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, 
umem_1_buffer_param_b);
+
+   ndev->umem_2_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, 
umem_2_buffer_param_a);
+   ndev->umem_2_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, 
umem_2_buffer_param_b);
+
+   ndev->umem_3_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, 
umem_3_buffer_param_a);
+   ndev->umem_3_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, 
umem_3_buffer_param_b);
+
+   return 0;
+}
+
 static void set_umem_size(struct mlx5_vdpa_net *ndev, struct 
mlx5_vdpa_virtqueue *mvq, int num,
  struct mlx5_vdpa_umem **umemp)
 {
-   struct mlx5_core_dev *mdev = ndev->mvdev.mdev;
-   int p_a;
-   int p_b;
+   u32 p_a;
+   u32 p_b;
 
switch (num) {
case 1:
-   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_a);
-   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_b);
+   p_a = ndev->umem_1_buffer_param_a;
+   p_b = ndev->umem_1_buffer_param_b;
*umemp = >umem1;
break;
case 2:
-   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_a);
-   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_b);
+   p_a = ndev->umem_2_buffer_param_a;
+   p_b = ndev->umem_2_buffer_param_b;
*umemp = >umem2;
break;
case 3:
-   p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_a);
-   p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_b);
+   p_a = ndev->umem_3_buffer_param_a;
+   p_b = ndev->umem_3_buffer_param_b;
*umemp = >umem3;
break;
}
+
(*umemp)->size = p_a * mvq->num_ent + p_b;
 }
 
@@ -2679,6 +2711,11 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
goto out;
}
mlx5_vdpa_add_debugfs(ndev);
+
+   err = read_umem_params(ndev);
+   if (err)
+   goto err_setup;
+
err = setup_virtqueues(mvdev);
if (err) {
mlx5_vdpa_warn(mvdev, "setup_virtqueues\n");
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.h 
b/drivers/vdpa/mlx5/net/mlx5_vnet.h
index 36c44d9fdd16..65ebbba20662 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.h
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.h
@@ -65,6 +65,15 @@ struct mlx5_vdpa_net {
struct hlist_head 

[PATCH] vdpa/mlx5: Fix double release of debugfs entry

2023-08-29 Thread Dragos Tatulea via Virtualization
The error path in setup_driver deletes the debugfs entry but doesn't
clear the pointer. During .dev_del the invalid pointer will be released
again causing a crash.

This patch fixes the issue by always clearing the debugfs entry in
mlx5_vdpa_remove_debugfs. Also, stop removing the debugfs entry in
.dev_del op: the debugfs entry is already handled within the
setup_driver/teardown_driver scope.

Fixes: f0417e72add5 ("vdpa/mlx5: Add and remove debugfs in setup/teardown 
driver")
Signed-off-by: Dragos Tatulea 
Reviewed-by: Gal Pressman 
---
 drivers/vdpa/mlx5/net/debug.c | 5 +++--
 drivers/vdpa/mlx5/net/mlx5_vnet.c | 7 ++-
 drivers/vdpa/mlx5/net/mlx5_vnet.h | 2 +-
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/debug.c b/drivers/vdpa/mlx5/net/debug.c
index 60d6ac68cdc4..9c85162c19fc 100644
--- a/drivers/vdpa/mlx5/net/debug.c
+++ b/drivers/vdpa/mlx5/net/debug.c
@@ -146,7 +146,8 @@ void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev)
ndev->rx_dent = debugfs_create_dir("rx", ndev->debugfs);
 }
 
-void mlx5_vdpa_remove_debugfs(struct dentry *dbg)
+void mlx5_vdpa_remove_debugfs(struct mlx5_vdpa_net *ndev)
 {
-   debugfs_remove_recursive(dbg);
+   debugfs_remove_recursive(ndev->debugfs);
+   ndev->debugfs = NULL;
 }
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 37be945a0230..f91c938b4be1 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2713,7 +2713,7 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev)
 err_rqt:
teardown_virtqueues(ndev);
 err_setup:
-   mlx5_vdpa_remove_debugfs(ndev->debugfs);
+   mlx5_vdpa_remove_debugfs(ndev);
 out:
return err;
 }
@@ -2727,8 +2727,7 @@ static void teardown_driver(struct mlx5_vdpa_net *ndev)
if (!ndev->setup)
return;
 
-   mlx5_vdpa_remove_debugfs(ndev->debugfs);
-   ndev->debugfs = NULL;
+   mlx5_vdpa_remove_debugfs(ndev);
teardown_steering(ndev);
destroy_tir(ndev);
destroy_rqt(ndev);
@@ -3489,8 +3488,6 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev 
*v_mdev, struct vdpa_device *
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
struct workqueue_struct *wq;
 
-   mlx5_vdpa_remove_debugfs(ndev->debugfs);
-   ndev->debugfs = NULL;
unregister_link_notifier(ndev);
_vdpa_unregister_device(dev);
wq = mvdev->wq;
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.h 
b/drivers/vdpa/mlx5/net/mlx5_vnet.h
index 36c44d9fdd16..60cdbc903037 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.h
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.h
@@ -88,7 +88,7 @@ struct macvlan_node {
 };
 
 void mlx5_vdpa_add_debugfs(struct mlx5_vdpa_net *ndev);
-void mlx5_vdpa_remove_debugfs(struct dentry *dbg);
+void mlx5_vdpa_remove_debugfs(struct mlx5_vdpa_net *ndev);
 void mlx5_vdpa_add_rx_flow_table(struct mlx5_vdpa_net *ndev);
 void mlx5_vdpa_remove_rx_flow_table(struct mlx5_vdpa_net *ndev);
 void mlx5_vdpa_add_tirn(struct mlx5_vdpa_net *ndev);
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH] MAINTAINERS: Add myself as mlx5_vdpa driver

2023-08-15 Thread Dragos Tatulea via Virtualization
As Eli Cohen moved to other work, I'll be the contact point for
mlx5_vdpa.

Signed-off-by: Dragos Tatulea 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9a5863f1b016..c9a9259f4d37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13555,6 +13555,12 @@ F: Documentation/leds/leds-mlxcpld.rst
 F: drivers/leds/leds-mlxcpld.c
 F: drivers/leds/leds-mlxreg.c
 
+MELLANOX MLX5_VDPA DRIVER
+M: Dragos Tatulea 
+L: virtualization@lists.linux-foundation.org
+S: Supported
+F: drivers/vdpa/mlx5/
+
 MELLANOX PLATFORM DRIVER
 M: Vadim Pasternak 
 L: platform-driver-...@vger.kernel.org
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH RFC 2/4] vdpa/mlx5: implement .reset_map driver op

2023-08-15 Thread Dragos Tatulea via Virtualization
On Mon, 2023-08-14 at 18:43 -0700, Si-Wei Liu wrote:
> This patch is based on top of the "vdpa/mlx5: Fixes
> for ASID handling" series [1].
> 
> [1] vdpa/mlx5: Fixes for ASID handling
> https://lore.kernel.org/virtualization/20230802171231.11001-1-dtatu...@nvidia.com/
> 
> Signed-off-by: Si-Wei Liu 
> ---
>  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  1 +
>  drivers/vdpa/mlx5/core/mr.c    | 72 +
> -
>  drivers/vdpa/mlx5/net/mlx5_vnet.c  | 18 +++---
>  3 files changed, 54 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> index b53420e..5c9a25a 100644
> --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> @@ -123,6 +123,7 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> struct vhost_iotlb *iotlb,
> unsigned int asid);
>  void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
>  void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int
> asid);
> +int mlx5_vdpa_reset_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
>  
>  #define mlx5_vdpa_warn(__dev, format,
> ...) \
> dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format,
> __func__, __LINE__, \
> diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> index 5a1971fc..c8d64fc 100644
> --- a/drivers/vdpa/mlx5/core/mr.c
> +++ b/drivers/vdpa/mlx5/core/mr.c
> @@ -489,21 +489,15 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev,
> struct mlx5_vdpa_mr *mr
> }
>  }
>  
> -static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned
> int asid)
> +static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev)
>  {
> -   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> -   return;
> -
> prune_iotlb(mvdev);
>  }
>  
> -static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned
> int asid)
> +static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev)
>  {
> struct mlx5_vdpa_mr *mr = >mr;
>  
> -   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
> -   return;
> -
> if (!mr->initialized)
> return;
>  
> @@ -521,8 +515,10 @@ void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev
> *mvdev, unsigned int asid)
>  
> mutex_lock(>mkey_mtx);
>  
> -   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
> -   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
> +   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid)
> +   _mlx5_vdpa_destroy_dvq_mr(mvdev);
> +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid)
> +   _mlx5_vdpa_destroy_cvq_mr(mvdev);
>  
> mutex_unlock(>mkey_mtx);
>  }
> @@ -534,25 +530,17 @@ void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
>  }
>  
>  static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
> -   struct vhost_iotlb *iotlb,
> -   unsigned int asid)
> +   struct vhost_iotlb *iotlb)
>  {
> -   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> -   return 0;
> -
> return dup_iotlb(mvdev, iotlb);
>  }
>  
>  static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
> -   struct vhost_iotlb *iotlb,
> -   unsigned int asid)
> +   struct vhost_iotlb *iotlb)
>  {
> struct mlx5_vdpa_mr *mr = >mr;
> int err;
>  
> -   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
> -   return 0;
> -
> if (mr->initialized)
> return 0;
>  
> @@ -574,20 +562,18 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev
> *mvdev,
>  {
> int err;
>  
> -   err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
> -   if (err)
> -   return err;
> -
> -   err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
> -   if (err)
> -   goto out_err;
> +   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) {
> +   err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
> +   if (err)
> +   return err;
> +   }
> +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) {
> +   err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb);
> +   if (err)
> +   return err;
I think you still need the goto here, when CVQ and DVQ fall in same asid and
there's a CVQ mr creation error, you are left stuck with the DVQ mr.

> +   }
>  
> return 0;
> -
> -out_err:
> -   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
> -
> -   return err;
>  }
>  
>  int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb
> *iotlb,
> @@ -601,6 +587,28 @@ int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev 

Re: [PATCH 1/2] vdpa/mlx5: Fix mr->initialized semantics

2023-08-14 Thread Dragos Tatulea via Virtualization
On Wed, 2023-08-09 at 09:42 +0800, Jason Wang wrote:
> On Tue, Aug 8, 2023 at 3:24 PM Dragos Tatulea  wrote:
> > 
> > On Tue, 2023-08-08 at 10:57 +0800, Jason Wang wrote:
> > > On Thu, Aug 3, 2023 at 7:40 PM Dragos Tatulea  wrote:
> > > > 
> > > > On Thu, 2023-08-03 at 16:03 +0800, Jason Wang wrote:
> > > > > On Thu, Aug 3, 2023 at 1:13 AM Dragos Tatulea 
> > > > > wrote:
> > > > > > 
> > > > > > The mr->initialized flag is shared between the control vq and data
> > > > > > vq
> > > > > > part of the mr init/uninit. But if the control vq and data vq get
> > > > > > placed
> > > > > > in different ASIDs, it can happen that initializing the control vq
> > > > > > will
> > > > > > prevent the data vq mr from being initialized.
> > > > > > 
> > > > > > This patch consolidates the control and data vq init parts into
> > > > > > their
> > > > > > own init functions. The mr->initialized will now be used for the
> > > > > > data vq
> > > > > > only. The control vq currently doesn't need a flag.
> > > > > > 
> > > > > > The uninitializing part is also taken care of: mlx5_vdpa_destroy_mr
> > > > > > got
> > > > > > split into data and control vq functions which are now also ASID
> > > > > > aware.
> > > > > > 
> > > > > > Fixes: 8fcd20c30704 ("vdpa/mlx5: Support different address spaces
> > > > > > for
> > > > > > control and data")
> > > > > > Signed-off-by: Dragos Tatulea 
> > > > > > Reviewed-by: Eugenio Pérez 
> > > > > > Reviewed-by: Gal Pressman 
> > > > > > ---
> > > > > >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  1 +
> > > > > >  drivers/vdpa/mlx5/core/mr.c    | 97 +--
> > > > > > ---
> > > > > >  2 files changed, 71 insertions(+), 27 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > > > b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > > > index 25fc4120b618..a0420be5059f 100644
> > > > > > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > > > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > > > @@ -31,6 +31,7 @@ struct mlx5_vdpa_mr {
> > > > > >     struct list_head head;
> > > > > >     unsigned long num_directs;
> > > > > >     unsigned long num_klms;
> > > > > > +   /* state of dvq mr */
> > > > > >     bool initialized;
> > > > > > 
> > > > > >     /* serialize mkey creation and destruction */
> > > > > > diff --git a/drivers/vdpa/mlx5/core/mr.c
> > > > > > b/drivers/vdpa/mlx5/core/mr.c
> > > > > > index 03e543229791..4ae14a248a4b 100644
> > > > > > --- a/drivers/vdpa/mlx5/core/mr.c
> > > > > > +++ b/drivers/vdpa/mlx5/core/mr.c
> > > > > > @@ -489,60 +489,103 @@ static void destroy_user_mr(struct
> > > > > > mlx5_vdpa_dev
> > > > > > *mvdev, struct mlx5_vdpa_mr *mr
> > > > > >     }
> > > > > >  }
> > > > > > 
> > > > > > -void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
> > > > > > +static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev,
> > > > > > unsigned
> > > > > > int asid)
> > > > > > +{
> > > > > > +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> > > > > > +   return;
> > > > > > +
> > > > > > +   prune_iotlb(mvdev);
> > > > > > +}
> > > > > > +
> > > > > > +static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev,
> > > > > > unsigned
> > > > > > int asid)
> > > > > >  {
> > > > > >     struct mlx5_vdpa_mr *mr = >mr;
> > > > > > 
> > > > > > -   mutex_lock(>mkey_mtx);
> > > > > > +   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
> > > > > > +   return;
> > > > > > +
> > > > > >     if (!mr->initialized)
> > > > > > -   goto out;
> > > > > > +   return;
> > > > > > 
> > > > > > -   prune_iotlb(mvdev);
> > > > > >     if (mr->user_mr)
> > > > > >     destroy_user_mr(mvdev, mr);
> > > > > >     else
> > > > > >     destroy_dma_mr(mvdev, mr);
> > > > > > 
> > > > > >     mr->initialized = false;
> > > > > > -out:
> > > > > > +}
> > > > > > +
> > > > > > +static void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev,
> > > > > > unsigned
> > > > > > int asid)
> > > > > > +{
> > > > > > +   struct mlx5_vdpa_mr *mr = >mr;
> > > > > > +
> > > > > > +   mutex_lock(>mkey_mtx);
> > > > > > +
> > > > > > +   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
> > > > > > +   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
> > > > > > +
> > > > > >     mutex_unlock(>mkey_mtx);
> > > > > >  }
> > > > > > 
> > > > > > -static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> > > > > > -   struct vhost_iotlb *iotlb, unsigned
> > > > > > int
> > > > > > asid)
> > > > > > +void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
> > > > > > +{
> > > > > > +   mlx5_vdpa_destroy_mr_asid(mvdev, mvdev-
> > > > > > > group2asid[MLX5_VDPA_CVQ_GROUP]);
> > > > > > +   mlx5_vdpa_destroy_mr_asid(mvdev, mvdev-
> > > > > > > group2asid[MLX5_VDPA_DATAVQ_GROUP]);
> > > > > > +}
> > > > > > +
> > > > > > +static int 

Re: [PATCH 0/2] vdpa/mlx5: Fixes for ASID handling

2023-08-10 Thread Dragos Tatulea via Virtualization
On Thu, 2023-08-10 at 04:54 -0400, Michael S. Tsirkin wrote:
> On Wed, Aug 02, 2023 at 08:12:16PM +0300, Dragos Tatulea wrote:
> > This patch series is based on Eugenio's fix for handling CVQs in
> > a different ASID [0].
> > 
> > The first patch is the actual fix.
> > 
> > The next 2 patches are fixing a possible issue that I found while
> > implementing patch 1. The patches are ordered like this for clarity.
> > 
> > [0]
> > https://lore.kernel.org/lkml/20230112142218.725622-1-epere...@redhat.com/
> 
> 
> So what are we doing with this patchset? If we are merging anything
> for this release it has to happen now.
> 
Jason mentioned that wanted an additional cleanup patch to move the cvq specific
code to the net part of mlx5_vdpa. That's quite a refactoring though and would
like to take my time to do an RFC for that first.

It would be good if this got merged now as it fixes an actual problem ...

> > Dragos Tatulea (1):
> >   vdpa/mlx5: Fix mr->initialized semantics
> > 
> > Eugenio Pérez (1):
> >   vdpa/mlx5: Delete control vq iotlb in destroy_mr only when necessary
> > 
> >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  2 +
> >  drivers/vdpa/mlx5/core/mr.c    | 97 +-
> >  drivers/vdpa/mlx5/net/mlx5_vnet.c  |  4 +-
> >  3 files changed, 74 insertions(+), 29 deletions(-)
> > 
> > -- 
> > 2.41.0
> 

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH net] virtio-net: set queues after driver_ok

2023-08-09 Thread Dragos Tatulea via Virtualization
On Tue, 2023-08-08 at 23:13 -0400, Jason Wang wrote:
> Commit 25266128fe16 ("virtio-net: fix race between set queues and
> probe") tries to fix the race between set queues and probe by calling
> _virtnet_set_queues() before DRIVER_OK is set. This violates virtio
> spec. Fixing this by setting queues after virtio_device_ready().
> 
> Fixes: 25266128fe16 ("virtio-net: fix race between set queues and probe")
> Reported-by: Dragos Tatulea 
> Signed-off-by: Jason Wang 
> ---
> The patch is needed for -stable.
> ---
>  drivers/net/virtio_net.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 1270c8d23463..ff03921e46df 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -4219,8 +4219,6 @@ static int virtnet_probe(struct virtio_device *vdev)
> if (vi->has_rss || vi->has_rss_hash_report)
> virtnet_init_default_rss(vi);
>  
> -   _virtnet_set_queues(vi, vi->curr_queue_pairs);
> -
> /* serialize netdev register + virtio_device_ready() with ndo_open()
> */
> rtnl_lock();
>  
> @@ -4233,6 +4231,8 @@ static int virtnet_probe(struct virtio_device *vdev)
>  
> virtio_device_ready(vdev);
>  
> +   _virtnet_set_queues(vi, vi->curr_queue_pairs);
> +
> /* a random MAC address has been assigned, notify the device.
>  * We don't fail probe if VIRTIO_NET_F_CTRL_MAC_ADDR is not there
>  * because many devices work fine without getting MAC explicitly

Thanks for the quick fix. Doesn't this fix though bring back the original race
that was fixed in commit 25266128fe16 ("virtio-net: fix race between set queues
and probe")? Or is being under the same rntl_lock session as register_netdev
enough to avoid the race?

Thanks,
Dragos
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH net] virtio-net: fix race between set queues and probe

2023-08-08 Thread Dragos Tatulea via Virtualization
On Tue, 2023-07-25 at 03:20 -0400, Jason Wang wrote:
> A race were found where set_channels could be called after registering
> but before virtnet_set_queues() in virtnet_probe(). Fixing this by
> moving the virtnet_set_queues() before netdevice registering. While at
> it, use _virtnet_set_queues() to avoid holding rtnl as the device is
> not even registered at that time.
> 
> Fixes: a220871be66f ("virtio-net: correctly enable multiqueue")
> Signed-off-by: Jason Wang 
> ---
>  drivers/net/virtio_net.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 0db14f6b87d3..1270c8d23463 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -4219,6 +4219,8 @@ static int virtnet_probe(struct virtio_device *vdev)
> if (vi->has_rss || vi->has_rss_hash_report)
> virtnet_init_default_rss(vi);
>  
> +   _virtnet_set_queues(vi, vi->curr_queue_pairs);
> +
> /* serialize netdev register + virtio_device_ready() with ndo_open()
> */
> rtnl_lock();
>  
> @@ -4257,8 +4259,6 @@ static int virtnet_probe(struct virtio_device *vdev)
> goto free_unregister_netdev;
> }
>  
> -   virtnet_set_queues(vi, vi->curr_queue_pairs);
> -
> /* Assume link up if device can't report link status,
>    otherwise get link status from config. */
> netif_carrier_off(dev);

This change seems to break mlx5_vdpa when using virtio_vdpa.
_virtnet_set_queues() hangs. Because DRIVER_OK has not yet been set, mlx5_vdpa
cvq kick handler will ignore any commands.

Output:
[  199.681445] mlx5_core :08:00.0: E-Switch: Enable: mode(OFFLOADS),
nvfs(1), necvfs(0), active vports(2)
[  199.690154] mlx5_core :08:00.2: firmware version: 22.38.458
[  199.862816] mlx5_core :08:00.2: Rate limit: 127 rates are supported,
range: 0Mbps to 97656Mbps
[  199.895653] mlx5_core :08:00.2: Assigned random MAC address
b2:a1:71:c0:28:a2
[  200.036900] mlx5_core :08:00.2: MLX5E: StrdRq(1) RqSz(8) StrdSz(2048)
RxCqeCmprss(0 enhanced)
[  202.215022] mlx5_core :08:00.2: mlx5_vdpa_reset:2813:(pid 1294):
performing device reset
[  223.228309] rcu: INFO: rcu_sched self-detected stall on CPU
[  223.228870] rcu:3-: (5250 ticks this GP)
idle=1cdc/1/0x4000 softirq=1981/1981 fqs=2064
[  223.229686] rcu:(t=5251 jiffies g=7061 q=4365 ncpus=10)
[  223.230165] CPU: 3 PID: 1294 Comm: modprobe Not tainted 6.5.0-rc4+ #32
[  223.230725] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-
1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
[  223.231657] RIP: 0010:virtqueue_get_buf_ctx+0x7/0x290
[  223.232141] Code: ...
[  223.233639] RSP: 0018:888144fe7898 EFLAGS: 0246
[  223.234108] RAX:  RBX: 888103327940 RCX: 888100eca000
[  223.234711] RDX:  RSI: 888144fe78ac RDI: 888108c3b300
[  223.235315] RBP: 888144fe78d0 R08: 0001 R09: 888103327940
[  223.235921] R10: 0003 R11: 0008 R12: 0002
[  223.236536] R13: 0004 R14: 8881037c1400 R15: 88810337f740
[  223.237144] FS:  7f55572f8740() GS:88846f98()
knlGS:
[  223.237877] CS:  0010 DS:  ES:  CR0: 80050033
[  223.238401] CR2: 7f5556d05c00 CR3: 00012df3a002 CR4: 00370ea0
[  223.239016] DR0:  DR1:  DR2: 
[  223.239630] DR3:  DR6: fffe0ff0 DR7: 0400
[  223.240265] Call Trace:
[  223.240570]  
[  223.240823]  ? rcu_dump_cpu_stacks+0xc4/0x100
[  223.241250]  ? rcu_sched_clock_irq+0x407/0xaf0
[  223.241677]  ? trigger_load_balance+0x62/0x380
[  223.242105]  ? update_process_times+0x5b/0x90
[  223.242527]  ? tick_sched_timer+0x8b/0xa0
[  223.242926]  ? tick_sched_do_timer+0x80/0x80
[  223.243346]  ? __hrtimer_run_queues+0x121/0x270
[  223.243777]  ? hrtimer_interrupt+0xf4/0x230
[  223.244193]  ? __sysvec_apic_timer_interrupt+0x52/0xf0
[  223.244684]  ? sysvec_apic_timer_interrupt+0x69/0x90
[  223.245150]  
[  223.245412]  
[  223.245668]  ? asm_sysvec_apic_timer_interrupt+0x16/0x20
[  223.246160]  ? virtqueue_get_buf_ctx+0x7/0x290
[  223.246588]  virtnet_send_command+0x113/0x170
[  223.247008]  ? virtnet_set_affinity+0x166/0x1b0
[  223.247441]  _virtnet_set_queues+0x9f/0x100
[  223.247850]  virtnet_probe+0xa27/0x1270
[  223.248242]  ? vdpa_get_config+0x5b/0x70 [vdpa]
[  223.248699]  ? virtio_vdpa_notify_with_data+0x30/0x30 [virtio_vdpa]
[  223.249251]  virtio_dev_probe+0x196/0x300
[  223.249646]  really_probe+0xc3/0x3d0
[  223.250012]  ? driver_probe_device+0x90/0x90
[  223.250425]  __driver_probe_device+0x80/0x160
[  223.250846]  driver_probe_device+0x1f/0x90
[  223.251247]  __device_attach_driver+0x7d/0x100
[  223.251674]  bus_for_each_drv+0x7d/0xd0
[  223.252055]  __device_attach+0xb2/0x1c0
[  223.252455]  

Re: [PATCH 1/2] vdpa/mlx5: Fix mr->initialized semantics

2023-08-08 Thread Dragos Tatulea via Virtualization
On Tue, 2023-08-08 at 10:57 +0800, Jason Wang wrote:
> On Thu, Aug 3, 2023 at 7:40 PM Dragos Tatulea  wrote:
> > 
> > On Thu, 2023-08-03 at 16:03 +0800, Jason Wang wrote:
> > > On Thu, Aug 3, 2023 at 1:13 AM Dragos Tatulea  wrote:
> > > > 
> > > > The mr->initialized flag is shared between the control vq and data vq
> > > > part of the mr init/uninit. But if the control vq and data vq get placed
> > > > in different ASIDs, it can happen that initializing the control vq will
> > > > prevent the data vq mr from being initialized.
> > > > 
> > > > This patch consolidates the control and data vq init parts into their
> > > > own init functions. The mr->initialized will now be used for the data vq
> > > > only. The control vq currently doesn't need a flag.
> > > > 
> > > > The uninitializing part is also taken care of: mlx5_vdpa_destroy_mr got
> > > > split into data and control vq functions which are now also ASID aware.
> > > > 
> > > > Fixes: 8fcd20c30704 ("vdpa/mlx5: Support different address spaces for
> > > > control and data")
> > > > Signed-off-by: Dragos Tatulea 
> > > > Reviewed-by: Eugenio Pérez 
> > > > Reviewed-by: Gal Pressman 
> > > > ---
> > > >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  1 +
> > > >  drivers/vdpa/mlx5/core/mr.c    | 97 +-
> > > >  2 files changed, 71 insertions(+), 27 deletions(-)
> > > > 
> > > > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > index 25fc4120b618..a0420be5059f 100644
> > > > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > > > @@ -31,6 +31,7 @@ struct mlx5_vdpa_mr {
> > > >     struct list_head head;
> > > >     unsigned long num_directs;
> > > >     unsigned long num_klms;
> > > > +   /* state of dvq mr */
> > > >     bool initialized;
> > > > 
> > > >     /* serialize mkey creation and destruction */
> > > > diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> > > > index 03e543229791..4ae14a248a4b 100644
> > > > --- a/drivers/vdpa/mlx5/core/mr.c
> > > > +++ b/drivers/vdpa/mlx5/core/mr.c
> > > > @@ -489,60 +489,103 @@ static void destroy_user_mr(struct mlx5_vdpa_dev
> > > > *mvdev, struct mlx5_vdpa_mr *mr
> > > >     }
> > > >  }
> > > > 
> > > > -void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
> > > > +static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev,
> > > > unsigned
> > > > int asid)
> > > > +{
> > > > +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> > > > +   return;
> > > > +
> > > > +   prune_iotlb(mvdev);
> > > > +}
> > > > +
> > > > +static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev,
> > > > unsigned
> > > > int asid)
> > > >  {
> > > >     struct mlx5_vdpa_mr *mr = >mr;
> > > > 
> > > > -   mutex_lock(>mkey_mtx);
> > > > +   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
> > > > +   return;
> > > > +
> > > >     if (!mr->initialized)
> > > > -   goto out;
> > > > +   return;
> > > > 
> > > > -   prune_iotlb(mvdev);
> > > >     if (mr->user_mr)
> > > >     destroy_user_mr(mvdev, mr);
> > > >     else
> > > >     destroy_dma_mr(mvdev, mr);
> > > > 
> > > >     mr->initialized = false;
> > > > -out:
> > > > +}
> > > > +
> > > > +static void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev,
> > > > unsigned
> > > > int asid)
> > > > +{
> > > > +   struct mlx5_vdpa_mr *mr = >mr;
> > > > +
> > > > +   mutex_lock(>mkey_mtx);
> > > > +
> > > > +   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
> > > > +   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
> > > > +
> > > >     mutex_unlock(>mkey_mtx);
> > > >  }
> > > > 
> > > > -static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> > > > -   struct vhost_iotlb *iotlb, unsigned int
> > > > asid)
> > > > +void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
> > > > +{
> > > > +   mlx5_vdpa_destroy_mr_asid(mvdev, mvdev-
> > > > > group2asid[MLX5_VDPA_CVQ_GROUP]);
> > > > +   mlx5_vdpa_destroy_mr_asid(mvdev, mvdev-
> > > > > group2asid[MLX5_VDPA_DATAVQ_GROUP]);
> > > > +}
> > > > +
> > > > +static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
> > > > +   struct vhost_iotlb *iotlb,
> > > > +   unsigned int asid)
> > > > +{
> > > > +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> > > > +   return 0;
> > > > +
> > > > +   return dup_iotlb(mvdev, iotlb);
> > > 
> > > This worries me as conceptually, there should be no difference between
> > > dvq mr and cvq mr. The virtqueue should be loosely coupled with mr.
> > > 
> > Are you worried by the changes in this patch or about the possibility of
> > having
> > 
> > The reason for this change is that I noticed if you create one mr in one
> > asid
> > you could be blocked out 

[PATCH v2] vdpa/mlx5: Fix crash on shutdown for when no ndev exists

2023-08-03 Thread Dragos Tatulea via Virtualization
The ndev was accessed on shutdown without a check if it actually exists.
This triggered the crash pasted below.

Instead of doing the ndev check, delete the shutdown handler altogether.
The irqs will be released at the parent VF level (mlx5_core).

 BUG: kernel NULL pointer dereference, address: 0300
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
 PGD 0 P4D 0
 Oops:  [#1] SMP
 CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 
6.5.0-rc2_for_upstream_min_debug_2023_07_17_15_05 #1
 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 
rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
 RIP: 0010:mlx5v_shutdown+0xe/0x50 [mlx5_vdpa]
 RSP: 0018:8881003bfdc0 EFLAGS: 00010286
 RAX: 888103befba0 RBX: 888109d28008 RCX: 0017
 RDX: 0001 RSI: 0212 RDI: 888109d28000
 RBP:  R08: 000d3a3a3882 R09: 0001
 R10:  R11:  R12: 888109d28000
 R13: 888109d28080 R14: fee1dead R15: 
 FS:  7f4969e0be40() GS:88852c80() knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 0300 CR3: 0001051cd006 CR4: 00370eb0
 DR0:  DR1:  DR2: 
 DR3:  DR6: fffe0ff0 DR7: 0400
 Call Trace:
  
  ? __die+0x20/0x60
  ? page_fault_oops+0x14c/0x3c0
  ? exc_page_fault+0x75/0x140
  ? asm_exc_page_fault+0x22/0x30
  ? mlx5v_shutdown+0xe/0x50 [mlx5_vdpa]
  device_shutdown+0x13e/0x1e0
  kernel_restart+0x36/0x90
  __do_sys_reboot+0x141/0x210
  ? vfs_writev+0xcd/0x140
  ? handle_mm_fault+0x161/0x260
  ? do_writev+0x6b/0x110
  do_syscall_64+0x3d/0x90
  entry_SYSCALL_64_after_hwframe+0x46/0xb0
 RIP: 0033:0x7f496990fb56
 RSP: 002b:7fffc7bdde88 EFLAGS: 0206 ORIG_RAX: 00a9
 RAX: ffda RBX:  RCX: 7f496990fb56
 RDX: 01234567 RSI: 28121969 RDI: fee1dead
 RBP: 7fffc7bde1d0 R08:  R09: 
 R10:  R11: 0206 R12: 
 R13: 7fffc7bddf10 R14:  R15: 7fffc7bde2b8
  
 CR2: 0300
 ---[ end trace  ]---

Fixes: bc9a2b3e686e ("vdpa/mlx5: Support interrupt bypassing")
Signed-off-by: Dragos Tatulea 
---
 drivers/vdpa/mlx5/net/mlx5_vnet.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 9138ef2fb2c8..047b069a5622 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -3548,17 +3548,6 @@ static void mlx5v_remove(struct auxiliary_device *adev)
kfree(mgtdev);
 }
 
-static void mlx5v_shutdown(struct auxiliary_device *auxdev)
-{
-   struct mlx5_vdpa_mgmtdev *mgtdev;
-   struct mlx5_vdpa_net *ndev;
-
-   mgtdev = auxiliary_get_drvdata(auxdev);
-   ndev = mgtdev->ndev;
-
-   free_irqs(ndev);
-}
-
 static const struct auxiliary_device_id mlx5v_id_table[] = {
{ .name = MLX5_ADEV_NAME ".vnet", },
{},
@@ -3570,7 +3559,6 @@ static struct auxiliary_driver mlx5v_driver = {
.name = "vnet",
.probe = mlx5v_probe,
.remove = mlx5v_remove,
-   .shutdown = mlx5v_shutdown,
.id_table = mlx5v_id_table,
 };
 
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH] vdpa/mlx5: Fix crash on shutdown for when no ndev exists

2023-08-03 Thread Dragos Tatulea via Virtualization
On Wed, 2023-08-02 at 09:56 +0200, Dragos Tatulea wrote:
> On Wed, 2023-08-02 at 10:51 +0800, Jason Wang wrote:
> > On Tue, Aug 1, 2023 at 4:17 PM Dragos Tatulea  wrote:
> > > 
> > > On Tue, 2023-08-01 at 11:59 +0800, Jason Wang wrote:
> > > > On Mon, Jul 31, 2023 at 5:08 PM Michael S. Tsirkin 
> > > > wrote:
> > > > > 
> > > > > On Mon, Jul 31, 2023 at 07:15:31AM +, Dragos Tatulea wrote:
> > > > > > On Thu, 2023-07-27 at 12:28 -0400, Michael S. Tsirkin wrote:
> > > > > > > On Thu, Jul 27, 2023 at 04:02:16PM +, Dragos Tatulea wrote:
> > > > > > > > On Wed, 2023-07-26 at 15:26 -0400, Michael S. Tsirkin wrote:
> > > > > > > > > On Wed, Jul 26, 2023 at 10:07:38PM +0300, Dragos Tatulea
> > > > > > > > > wrote:
> > > > > > > > > > The ndev was accessed on shutdown without a check if it
> > > > > > > > > > actually
> > > > > > > > > > exists.
> > > > > > > > > > This triggered the crash pasted below. This patch simply
> > > > > > > > > > adds
> > > > > > > > > > a
> > > > > > > > > > check
> > > > > > > > > > before using ndev.
> > > > > > > > > > 
> > > > > > > > > >  BUG: kernel NULL pointer dereference, address:
> > > > > > > > > > 0300
> > > > > > > > > >  #PF: supervisor read access in kernel mode
> > > > > > > > > >  #PF: error_code(0x) - not-present page
> > > > > > > > > >  PGD 0 P4D 0
> > > > > > > > > >  Oops:  [#1] SMP
> > > > > > > > > >  CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 6.5.0-
> > > > > > > > > > rc2_for_upstream_min_debug_2023_07_17_15_05 #1
> > > > > > > > > >  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
> > > > > > > > > > rel-
> > > > > > > > > > 1.13.0-0-
> > > > > > > > > > gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
> > > > > > > > > >  RIP: 0010:mlx5v_shutdown+0xe/0x50 [mlx5_vdpa]
> > > > > > > > > >  RSP: 0018:8881003bfdc0 EFLAGS: 00010286
> > > > > > > > > >  RAX: 888103befba0 RBX: 888109d28008 RCX:
> > > > > > > > > > 0017
> > > > > > > > > >  RDX: 0001 RSI: 0212 RDI:
> > > > > > > > > > 888109d28000
> > > > > > > > > >  RBP:  R08: 000d3a3a3882 R09:
> > > > > > > > > > 0001
> > > > > > > > > >  R10:  R11:  R12:
> > > > > > > > > > 888109d28000
> > > > > > > > > >  R13: 888109d28080 R14: fee1dead R15:
> > > > > > > > > > 
> > > > > > > > > >  FS:  7f4969e0be40() GS:88852c80()
> > > > > > > > > > knlGS:
> > > > > > > > > >  CS:  0010 DS:  ES:  CR0: 80050033
> > > > > > > > > >  CR2: 0300 CR3: 0001051cd006 CR4:
> > > > > > > > > > 00370eb0
> > > > > > > > > >  DR0:  DR1:  DR2:
> > > > > > > > > > 
> > > > > > > > > >  DR3:  DR6: fffe0ff0 DR7:
> > > > > > > > > > 0400
> > > > > > > > > >  Call Trace:
> > > > > > > > > >   
> > > > > > > > > >   ? __die+0x20/0x60
> > > > > > > > > >   ? page_fault_oops+0x14c/0x3c0
> > > > > > > > > >   ? exc_page_fault+0x75/0x140
> > > > > > > > > >   ? asm_exc_page_fault+0x22/0x30
> > > > > > > > > >   ? mlx5v_shutdown+0xe/0x50 [mlx5_vdpa]
> > > > > > > > > >   device_shutdown+0x13e/0x1e0
> > > > > > > > > >   kernel_restart+0x36/0x90
> > > > > > > > > >   __do_sys_reboot+0x141/0x210
> > > > > > > > > >   ? vfs_writev+0xcd/0x140
> > > > > > > > > >   ? handle_mm_fault+0x161/0x260
> > > > > > > > > >   ? do_writev+0x6b/0x110
> > > > > > > > > >   do_syscall_64+0x3d/0x90
> > > > > > > > > >   entry_SYSCALL_64_after_hwframe+0x46/0xb0
> > > > > > > > > >  RIP: 0033:0x7f496990fb56
> > > > > > > > > >  RSP: 002b:7fffc7bdde88 EFLAGS: 0206 ORIG_RAX:
> > > > > > > > > > 00a9
> > > > > > > > > >  RAX: ffda RBX:  RCX:
> > > > > > > > > > 7f496990fb56
> > > > > > > > > >  RDX: 01234567 RSI: 28121969 RDI:
> > > > > > > > > > fee1dead
> > > > > > > > > >  RBP: 7fffc7bde1d0 R08:  R09:
> > > > > > > > > > 
> > > > > > > > > >  R10:  R11: 0206 R12:
> > > > > > > > > > 
> > > > > > > > > >  R13: 7fffc7bddf10 R14:  R15:
> > > > > > > > > > 7fffc7bde2b8
> > > > > > > > > >   
> > > > > > > > > >  CR2: 0300
> > > > > > > > > >  ---[ end trace  ]---
> > > > > > > > > > 
> > > > > > > > > > Fixes: bc9a2b3e686e ("vdpa/mlx5: Support interrupt
> > > > > > > > > > bypassing")
> > > > > > > > > > Signed-off-by: Dragos Tatulea 
> > > > > > > > > > ---
> > > > > > > > > >  drivers/vdpa/mlx5/net/mlx5_vnet.c | 3 ++-
> > > > > > > > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > > > > > > > > 
> > > > > > > > > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > > > > b/drivers/vdpa/mlx5/net/mlx5_vnet.c
> > > > > > > > > > index 9138ef2fb2c8..e2e7ebd71798 100644
> > > > > > > > > > --- 

Re: [PATCH 1/2] vdpa/mlx5: Fix mr->initialized semantics

2023-08-03 Thread Dragos Tatulea via Virtualization
On Thu, 2023-08-03 at 16:03 +0800, Jason Wang wrote:
> On Thu, Aug 3, 2023 at 1:13 AM Dragos Tatulea  wrote:
> > 
> > The mr->initialized flag is shared between the control vq and data vq
> > part of the mr init/uninit. But if the control vq and data vq get placed
> > in different ASIDs, it can happen that initializing the control vq will
> > prevent the data vq mr from being initialized.
> > 
> > This patch consolidates the control and data vq init parts into their
> > own init functions. The mr->initialized will now be used for the data vq
> > only. The control vq currently doesn't need a flag.
> > 
> > The uninitializing part is also taken care of: mlx5_vdpa_destroy_mr got
> > split into data and control vq functions which are now also ASID aware.
> > 
> > Fixes: 8fcd20c30704 ("vdpa/mlx5: Support different address spaces for
> > control and data")
> > Signed-off-by: Dragos Tatulea 
> > Reviewed-by: Eugenio Pérez 
> > Reviewed-by: Gal Pressman 
> > ---
> >  drivers/vdpa/mlx5/core/mlx5_vdpa.h |  1 +
> >  drivers/vdpa/mlx5/core/mr.c    | 97 +-
> >  2 files changed, 71 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > index 25fc4120b618..a0420be5059f 100644
> > --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
> > @@ -31,6 +31,7 @@ struct mlx5_vdpa_mr {
> >     struct list_head head;
> >     unsigned long num_directs;
> >     unsigned long num_klms;
> > +   /* state of dvq mr */
> >     bool initialized;
> > 
> >     /* serialize mkey creation and destruction */
> > diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
> > index 03e543229791..4ae14a248a4b 100644
> > --- a/drivers/vdpa/mlx5/core/mr.c
> > +++ b/drivers/vdpa/mlx5/core/mr.c
> > @@ -489,60 +489,103 @@ static void destroy_user_mr(struct mlx5_vdpa_dev
> > *mvdev, struct mlx5_vdpa_mr *mr
> >     }
> >  }
> > 
> > -void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
> > +static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned
> > int asid)
> > +{
> > +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> > +   return;
> > +
> > +   prune_iotlb(mvdev);
> > +}
> > +
> > +static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned
> > int asid)
> >  {
> >     struct mlx5_vdpa_mr *mr = >mr;
> > 
> > -   mutex_lock(>mkey_mtx);
> > +   if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
> > +   return;
> > +
> >     if (!mr->initialized)
> > -   goto out;
> > +   return;
> > 
> > -   prune_iotlb(mvdev);
> >     if (mr->user_mr)
> >     destroy_user_mr(mvdev, mr);
> >     else
> >     destroy_dma_mr(mvdev, mr);
> > 
> >     mr->initialized = false;
> > -out:
> > +}
> > +
> > +static void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned
> > int asid)
> > +{
> > +   struct mlx5_vdpa_mr *mr = >mr;
> > +
> > +   mutex_lock(>mkey_mtx);
> > +
> > +   _mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
> > +   _mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
> > +
> >     mutex_unlock(>mkey_mtx);
> >  }
> > 
> > -static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
> > -   struct vhost_iotlb *iotlb, unsigned int
> > asid)
> > +void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
> > +{
> > +   mlx5_vdpa_destroy_mr_asid(mvdev, mvdev-
> > >group2asid[MLX5_VDPA_CVQ_GROUP]);
> > +   mlx5_vdpa_destroy_mr_asid(mvdev, mvdev-
> > >group2asid[MLX5_VDPA_DATAVQ_GROUP]);
> > +}
> > +
> > +static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
> > +   struct vhost_iotlb *iotlb,
> > +   unsigned int asid)
> > +{
> > +   if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
> > +   return 0;
> > +
> > +   return dup_iotlb(mvdev, iotlb);
> 
> This worries me as conceptually, there should be no difference between
> dvq mr and cvq mr. The virtqueue should be loosely coupled with mr.
> 
Are you worried by the changes in this patch or about the possibility of having 

The reason for this change is that I noticed if you create one mr in one asid
you could be blocked out from creating another one in a different asid due to
mr->initialized being true. To me that seemed problematic. Is it not?

> One example is that, if we only do dup_iotlb() but not try to create
> dma mr here, we will break virtio-vdpa:
> 
How will that be possible? _mlx5_vdpa_create_mr calls _mlx5_vdpa_create_dvq_mr
and _mlx5_vdpa_create_cvq_mr. The only thing that is different in this patch is
that the cvq is not protected by an init flag. My understanding was that it
would be ok to dup_iotlb again. Is it not? If not I could add an additional
initialized flag for the cvq mr.

Thanks,
Dragos

> commit 

[PATCH 2/2] vdpa/mlx5: Delete control vq iotlb in destroy_mr only when necessary

2023-08-02 Thread Dragos Tatulea via Virtualization
From: Eugenio Pérez 

mlx5_vdpa_destroy_mr can be called from .set_map with data ASID after
the control virtqueue ASID iotlb has been populated. The control vq
iotlb must not be cleared, since it will not be populated again.

So call the ASID aware destroy function which makes sure that the
right vq resource is destroyed.

Fixes: 8fcd20c30704 ("vdpa/mlx5: Support different address spaces for control 
and data")
Signed-off-by: Eugenio Pérez 
Reviewed-by: Gal Pressman 
---
 drivers/vdpa/mlx5/core/mlx5_vdpa.h | 1 +
 drivers/vdpa/mlx5/core/mr.c| 2 +-
 drivers/vdpa/mlx5/net/mlx5_vnet.c  | 4 ++--
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h 
b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
index a0420be5059f..b53420e874ac 100644
--- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h
+++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h
@@ -122,6 +122,7 @@ int mlx5_vdpa_handle_set_map(struct mlx5_vdpa_dev *mvdev, 
struct vhost_iotlb *io
 int mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct vhost_iotlb *iotlb,
unsigned int asid);
 void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev);
+void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid);
 
 #define mlx5_vdpa_warn(__dev, format, ...) 
\
dev_warn((__dev)->mdev->device, "%s:%d:(pid %d) warning: " format, 
__func__, __LINE__, \
diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c
index 4ae14a248a4b..5a1971fcd87b 100644
--- a/drivers/vdpa/mlx5/core/mr.c
+++ b/drivers/vdpa/mlx5/core/mr.c
@@ -515,7 +515,7 @@ static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev 
*mvdev, unsigned int
mr->initialized = false;
 }
 
-static void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned 
int asid)
+void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
 {
struct mlx5_vdpa_mr *mr = >mr;
 
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 9138ef2fb2c8..61c10ba5e3f5 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -2636,7 +2636,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
goto err_mr;
 
teardown_driver(ndev);
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
err = mlx5_vdpa_create_mr(mvdev, iotlb, asid);
if (err)
goto err_mr;
@@ -2652,7 +2652,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev 
*mvdev,
return 0;
 
 err_setup:
-   mlx5_vdpa_destroy_mr(mvdev);
+   mlx5_vdpa_destroy_mr_asid(mvdev, asid);
 err_mr:
return err;
 }
-- 
2.41.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

  1   2   >