[RFC PATCH v7 07/25] vhost: Add reference counting to vhost_iova_tree

Eugenio Pérez posted 25 patches 3 years, 10 months ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>, "Gonglei (Arei)" <arei.gonglei@huawei.com>, Peter Xu <peterx@redhat.com>, Cornelia Huck <cohuck@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>
There is a newer version of this series
[RFC PATCH v7 07/25] vhost: Add reference counting to vhost_iova_tree
Posted by Eugenio Pérez 3 years, 10 months ago
Now that different vqs can have different ASIDs its easier to track them
using reference counters.

QEMU's glib version still does not have them so we've copied g_rc_box,
so the implementation can be converted to glib's one when the minimum
version is raised.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 hw/virtio/vhost-iova-tree.h |  5 +++--
 hw/virtio/vhost-iova-tree.c | 21 +++++++++++++++++++--
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h
index 6a4f24e0f9..2fc825d7b1 100644
--- a/hw/virtio/vhost-iova-tree.h
+++ b/hw/virtio/vhost-iova-tree.h
@@ -16,8 +16,9 @@
 typedef struct VhostIOVATree VhostIOVATree;
 
 VhostIOVATree *vhost_iova_tree_new(uint64_t iova_first, uint64_t iova_last);
-void vhost_iova_tree_delete(VhostIOVATree *iova_tree);
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete);
+VhostIOVATree *vhost_iova_tree_acquire(VhostIOVATree *iova_tree);
+void vhost_iova_tree_release(VhostIOVATree *iova_tree);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_release);
 
 const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree,
                                         const DMAMap *map);
diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c
index 55fed1fefb..31445cbdfc 100644
--- a/hw/virtio/vhost-iova-tree.c
+++ b/hw/virtio/vhost-iova-tree.c
@@ -28,6 +28,9 @@ struct VhostIOVATree {
 
     /* IOVA address to qemu memory maps. */
     IOVATree *iova_taddr_map;
+
+    /* Reference count */
+    size_t refcnt;
 };
 
 /**
@@ -44,14 +47,28 @@ VhostIOVATree *vhost_iova_tree_new(hwaddr iova_first, hwaddr iova_last)
     tree->iova_last = iova_last;
 
     tree->iova_taddr_map = iova_tree_new();
+    tree->refcnt = 1;
     return tree;
 }
 
 /**
- * Delete an iova tree
+ * Increases the reference count of the iova tree
+ */
+VhostIOVATree *vhost_iova_tree_acquire(VhostIOVATree *iova_tree)
+{
+    ++iova_tree->refcnt;
+    return iova_tree;
+}
+
+/**
+ * Decrease reference counter of iova tree, freeing if it reaches 0
  */
-void vhost_iova_tree_delete(VhostIOVATree *iova_tree)
+void vhost_iova_tree_release(VhostIOVATree *iova_tree)
 {
+    if (--iova_tree->refcnt) {
+        return;
+    }
+
     iova_tree_destroy(iova_tree->iova_taddr_map);
     g_free(iova_tree);
 }
-- 
2.27.0


Re: [RFC PATCH v7 07/25] vhost: Add reference counting to vhost_iova_tree
Posted by Jason Wang 3 years, 10 months ago
在 2022/4/14 00:31, Eugenio Pérez 写道:
> Now that different vqs can have different ASIDs its easier to track them
> using reference counters.
>
> QEMU's glib version still does not have them so we've copied g_rc_box,
> so the implementation can be converted to glib's one when the minimum
> version is raised.
>
> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> ---


I'm not sure if it's too early to introduce things like this since we 
have at most 2 ASIDs. This is probably only needed when we want to 
expose ASIDs to guest.

Let's see how it goes for the following patch anyhow.

Thanks


>   hw/virtio/vhost-iova-tree.h |  5 +++--
>   hw/virtio/vhost-iova-tree.c | 21 +++++++++++++++++++--
>   2 files changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h
> index 6a4f24e0f9..2fc825d7b1 100644
> --- a/hw/virtio/vhost-iova-tree.h
> +++ b/hw/virtio/vhost-iova-tree.h
> @@ -16,8 +16,9 @@
>   typedef struct VhostIOVATree VhostIOVATree;
>   
>   VhostIOVATree *vhost_iova_tree_new(uint64_t iova_first, uint64_t iova_last);
> -void vhost_iova_tree_delete(VhostIOVATree *iova_tree);
> -G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete);
> +VhostIOVATree *vhost_iova_tree_acquire(VhostIOVATree *iova_tree);
> +void vhost_iova_tree_release(VhostIOVATree *iova_tree);
> +G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_release);
>   
>   const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree,
>                                           const DMAMap *map);
> diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c
> index 55fed1fefb..31445cbdfc 100644
> --- a/hw/virtio/vhost-iova-tree.c
> +++ b/hw/virtio/vhost-iova-tree.c
> @@ -28,6 +28,9 @@ struct VhostIOVATree {
>   
>       /* IOVA address to qemu memory maps. */
>       IOVATree *iova_taddr_map;
> +
> +    /* Reference count */
> +    size_t refcnt;
>   };
>   
>   /**
> @@ -44,14 +47,28 @@ VhostIOVATree *vhost_iova_tree_new(hwaddr iova_first, hwaddr iova_last)
>       tree->iova_last = iova_last;
>   
>       tree->iova_taddr_map = iova_tree_new();
> +    tree->refcnt = 1;
>       return tree;
>   }
>   
>   /**
> - * Delete an iova tree
> + * Increases the reference count of the iova tree
> + */
> +VhostIOVATree *vhost_iova_tree_acquire(VhostIOVATree *iova_tree)
> +{
> +    ++iova_tree->refcnt;
> +    return iova_tree;
> +}
> +
> +/**
> + * Decrease reference counter of iova tree, freeing if it reaches 0
>    */
> -void vhost_iova_tree_delete(VhostIOVATree *iova_tree)
> +void vhost_iova_tree_release(VhostIOVATree *iova_tree)
>   {
> +    if (--iova_tree->refcnt) {
> +        return;
> +    }
> +
>       iova_tree_destroy(iova_tree->iova_taddr_map);
>       g_free(iova_tree);
>   }