Thread (36 messages) 36 messages, 5 authors, 2021-03-26

Re: Re: [PATCH v5 07/11] vdpa: Support transferring virtual addressing during DMA mapping

From: Yongji Xie <hidden>
Date: 2021-03-23 07:26:54
Also in: kvm, linux-fsdevel

On Tue, Mar 23, 2021 at 11:13 AM Jason Wang [off-list ref] wrote:

在 2021/3/15 下午1:37, Xie Yongji 写道:
quoted
This patch introduces an attribute for vDPA device to indicate
whether virtual address can be used. If vDPA device driver set
it, vhost-vdpa bus driver will not pin user page and transfer
userspace virtual address instead of physical address during
DMA mapping. And corresponding vma->vm_file and offset will be
also passed as an opaque pointer.

Suggested-by: Jason Wang <redacted>
Signed-off-by: Xie Yongji <redacted>
---
  drivers/vdpa/ifcvf/ifcvf_main.c   |   2 +-
  drivers/vdpa/mlx5/net/mlx5_vnet.c |   2 +-
  drivers/vdpa/vdpa.c               |   9 +++-
  drivers/vdpa/vdpa_sim/vdpa_sim.c  |   2 +-
  drivers/vdpa/virtio_pci/vp_vdpa.c |   2 +-
  drivers/vhost/vdpa.c              | 104 +++++++++++++++++++++++++++++++-------
  include/linux/vdpa.h              |  19 +++++--
  7 files changed, 113 insertions(+), 27 deletions(-)
diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
index d555a6a5d1ba..aee013f3eb5f 100644
--- a/drivers/vdpa/ifcvf/ifcvf_main.c
+++ b/drivers/vdpa/ifcvf/ifcvf_main.c
@@ -431,7 +431,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
      }

      adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa,
-                                 dev, &ifc_vdpa_ops, NULL);
+                                 dev, &ifc_vdpa_ops, NULL, false);
      if (adapter == NULL) {
              IFCVF_ERR(pdev, "Failed to allocate vDPA structure");
              return -ENOMEM;
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index 71397fdafa6a..fb62ebcf464a 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -1982,7 +1982,7 @@ static int mlx5v_probe(struct auxiliary_device *adev,
      max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);

      ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
-                              NULL);
+                              NULL, false);
      if (IS_ERR(ndev))
              return PTR_ERR(ndev);
diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
index 5cffce67cab0..97fbac276c72 100644
--- a/drivers/vdpa/vdpa.c
+++ b/drivers/vdpa/vdpa.c
@@ -71,6 +71,7 @@ static void vdpa_release_dev(struct device *d)
   * @config: the bus operations that is supported by this device
   * @size: size of the parent structure that contains private data
   * @name: name of the vdpa device; optional.
+ * @use_va: indicate whether virtual address must be used by this device
   *
   * Driver should use vdpa_alloc_device() wrapper macro instead of
   * using this directly.
@@ -80,7 +81,8 @@ static void vdpa_release_dev(struct device *d)
   */
  struct vdpa_device *__vdpa_alloc_device(struct device *parent,
                                      const struct vdpa_config_ops *config,
-                                     size_t size, const char *name)
+                                     size_t size, const char *name,
+                                     bool use_va)
  {
      struct vdpa_device *vdev;
      int err = -EINVAL;
@@ -91,6 +93,10 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
      if (!!config->dma_map != !!config->dma_unmap)
              goto err;

+     /* It should only work for the device that use on-chip IOMMU */
+     if (use_va && !(config->dma_map || config->set_map))
+             goto err;
+
      err = -ENOMEM;
      vdev = kzalloc(size, GFP_KERNEL);
      if (!vdev)
@@ -106,6 +112,7 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent,
      vdev->index = err;
      vdev->config = config;
      vdev->features_valid = false;
+     vdev->use_va = use_va;

      if (name)
              err = dev_set_name(&vdev->dev, "%s", name);
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
index ff331f088baf..d26334e9a412 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
@@ -235,7 +235,7 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr)
              ops = &vdpasim_config_ops;

      vdpasim = vdpa_alloc_device(struct vdpasim, vdpa, NULL, ops,
-                                 dev_attr->name);
+                                 dev_attr->name, false);
      if (!vdpasim)
              goto err_alloc;
diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
index 1321a2fcd088..03b36aed48d6 100644
--- a/drivers/vdpa/virtio_pci/vp_vdpa.c
+++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
@@ -377,7 +377,7 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
              return ret;

      vp_vdpa = vdpa_alloc_device(struct vp_vdpa, vdpa,
-                                 dev, &vp_vdpa_ops, NULL);
+                                 dev, &vp_vdpa_ops, NULL, false);
      if (vp_vdpa == NULL) {
              dev_err(dev, "vp_vdpa: Failed to allocate vDPA structure\n");
              return -ENOMEM;
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 7c83fbf3edac..b65c21ae98d1 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -480,21 +480,30 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
  static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v, u64 start, u64 last)
  {
      struct vhost_dev *dev = &v->vdev;
+     struct vdpa_device *vdpa = v->vdpa;
      struct vhost_iotlb *iotlb = dev->iotlb;
      struct vhost_iotlb_map *map;
+     struct vdpa_map_file *map_file;
      struct page *page;
      unsigned long pfn, pinned;

      while ((map = vhost_iotlb_itree_first(iotlb, start, last)) != NULL) {
-             pinned = map->size >> PAGE_SHIFT;
-             for (pfn = map->addr >> PAGE_SHIFT;
-                  pinned > 0; pfn++, pinned--) {
-                     page = pfn_to_page(pfn);
-                     if (map->perm & VHOST_ACCESS_WO)
-                             set_page_dirty_lock(page);
-                     unpin_user_page(page);
+             if (!vdpa->use_va) {
+                     pinned = map->size >> PAGE_SHIFT;
+                     for (pfn = map->addr >> PAGE_SHIFT;
+                          pinned > 0; pfn++, pinned--) {
+                             page = pfn_to_page(pfn);
+                             if (map->perm & VHOST_ACCESS_WO)
+                                     set_page_dirty_lock(page);
+                             unpin_user_page(page);
+                     }
+                     atomic64_sub(map->size >> PAGE_SHIFT,
+                                     &dev->mm->pinned_vm);
+             } else {
+                     map_file = (struct vdpa_map_file *)map->opaque;
+                     fput(map_file->file);
+                     kfree(map_file);

Let's factor out the logic of pa and va separatedly here.
Will do it.

Thanks,
Yongji
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help