Skip to content

Commit

Permalink
drm/i915/gvt: Handle orphan dmabuf_objs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tina Zhang authored and Zhenyu Wang committed Dec 4, 2017
1 parent e546e28 commit dfb6ae4
Showing 1 changed file with 35 additions and 21 deletions.
56 changes: 35 additions & 21 deletions drivers/gpu/drm/i915/gvt/dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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 = {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}

0 comments on commit dfb6ae4

Please sign in to comment.