In order to prevent reaping of the object whilst setting it up to handle the pagefault, we need to mark it as pinned. This has the nice side-effect of eliminating some special cases from the pagefault handler as well! Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_gem.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b4eb3ee..2e84ae13 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1452,23 +1452,16 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) trace_i915_gem_object_fault(obj, page_offset, true, write); /* Now bind it into the GTT if needed */ - if (!obj->map_and_fenceable) { - ret = i915_gem_object_unbind(obj); - if (ret) - goto unlock; - } - if (!obj->gtt_space) { - ret = i915_gem_object_bind_to_gtt(obj, 0, true, false); - if (ret) - goto unlock; - } + ret = i915_gem_object_pin(obj, 0, true, false); + if (ret) + goto unlock; if (!obj->has_global_gtt_mapping) i915_gem_gtt_bind_object(obj, obj->cache_level); ret = i915_gem_object_get_fence(obj); if (ret) - goto unlock; + goto unpin; if (i915_gem_object_is_inactive(obj)) list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); @@ -1481,7 +1474,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Finally, remap it using the new GTT offset */ ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); if (ret) - goto unlock; + goto unpin; prefault = 16; if (page_offset + prefault >= obj->base.size >> PAGE_SHIFT) @@ -1492,6 +1485,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (vm_insert_pfn(vma, page_offset, pfn)) break; } +unpin: + i915_gem_object_unpin(obj); unlock: mutex_unlock(&dev->struct_mutex); out: -- 1.7.10.4