summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTina Zhang2017-11-23 09:26:37 +0100
committerZhenyu Wang2017-12-04 04:24:34 +0100
commitdfb6ae4e14bd6542ee6caa8f661f269c94e19a9f (patch)
tree0bd6378ed5d75945d776c4ed2299aba88a447793
parentdrm/i915/gvt: Dmabuf support for GVT-g (diff)
downloadkernel-qcow2-linux-dfb6ae4e14bd6542ee6caa8f661f269c94e19a9f.tar.gz
kernel-qcow2-linux-dfb6ae4e14bd6542ee6caa8f661f269c94e19a9f.tar.xz
kernel-qcow2-linux-dfb6ae4e14bd6542ee6caa8f661f269c94e19a9f.zip
drm/i915/gvt: Handle orphan dmabuf_objs
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> Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/gvt/dmabuf.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 190710c8d3e5..50215b26b6c8 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);
}