diff mbox

[v19,6/6] drm/i915/gvt: Handle orphan dmabuf_objs

Message ID 1511425598-2437-7-git-send-email-tina.zhang@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zhang, Tina Nov. 23, 2017, 8:26 a.m. UTC
dmabuf_obj's destruction relys on GEM release operation, which is managed
in i915 driver. And there is a time window between vgpu's destruction and
its dmabuf_objs' destruction. This patch is to free the orphan dmabuf_objs
correctly after the vgpu passes away.

Signed-off-by: Tina Zhang <tina.zhang@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
---
 drivers/gpu/drm/i915/gvt/dmabuf.c | 56 ++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 21 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 190710c..50215b2 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -88,19 +88,26 @@  static void dmabuf_gem_object_free(struct kref *kref)
 		container_of(kref, struct intel_vgpu_dmabuf_obj, kref);
 	struct intel_vgpu *vgpu = obj->vgpu;
 	struct list_head *pos;
-
 	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
 
-	list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
-		dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
-						list);
-		if (dmabuf_obj == obj) {
-			idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id);
-			kfree(dmabuf_obj->info);
-			kfree(dmabuf_obj);
-			list_del(pos);
-			break;
+	if (vgpu) {
+		list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
+			dmabuf_obj = container_of(pos,
+					struct intel_vgpu_dmabuf_obj, list);
+			if (dmabuf_obj == obj) {
+				intel_gvt_hypervisor_put_vfio_device(vgpu);
+				idr_remove(&vgpu->object_idr,
+					   dmabuf_obj->dmabuf_id);
+				kfree(dmabuf_obj->info);
+				kfree(dmabuf_obj);
+				list_del(pos);
+				break;
+			}
 		}
+	} else {
+		/* Free the orphan dmabuf_objs here */
+		kfree(obj->info);
+		kfree(obj);
 	}
 }
 
@@ -122,11 +129,16 @@  static void vgpu_gem_release(struct drm_i915_gem_object *gem_obj)
 	struct intel_vgpu_dmabuf_obj *obj = fb_info->obj;
 	struct intel_vgpu *vgpu = obj->vgpu;
 
-	mutex_lock(&vgpu->dmabuf_lock);
-	gem_obj->base.dma_buf = NULL;
-	dmabuf_obj_put(obj);
-	intel_gvt_hypervisor_put_vfio_device(vgpu);
-	mutex_unlock(&vgpu->dmabuf_lock);
+	if (vgpu) {
+		mutex_lock(&vgpu->dmabuf_lock);
+		gem_obj->base.dma_buf = NULL;
+		dmabuf_obj_put(obj);
+		mutex_unlock(&vgpu->dmabuf_lock);
+	} else {
+		/* vgpu is NULL, as it has been removed already */
+		gem_obj->base.dma_buf = NULL;
+		dmabuf_obj_put(obj);
+	}
 }
 
 static const struct drm_i915_gem_object_ops intel_vgpu_gem_ops = {
@@ -471,12 +483,6 @@  int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, unsigned int dmabuf_id)
 	}
 	dmabuf_fd = ret;
 
-	if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
-		gvt_vgpu_err("get vfio device failed\n");
-		put_unused_fd(ret);
-		goto out_free_dmabuf;
-	}
-
 	dmabuf_obj_get(dmabuf_obj);
 
 	if (dmabuf_obj->initref) {
@@ -518,6 +524,14 @@  void intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu)
 			dmabuf_obj->initref = false;
 			dmabuf_obj_put(dmabuf_obj);
 		}
+
+		idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id);
+
+		if (dmabuf_obj->vgpu)
+			intel_gvt_hypervisor_put_vfio_device(vgpu);
+
+		dmabuf_obj->vgpu = NULL;
+
 	}
 	mutex_unlock(&vgpu->dmabuf_lock);
 }