We want to always use the partial VMA as a fallback for a failure to bind the object into the GGTT. This extends the support partial objects in the GGTT to cover everything, not just objects too large. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem.c | 64 +++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 70397c1022d1..a8f4d4633bdb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1447,7 +1447,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data); struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_ggtt_view view = i915_ggtt_view_normal; struct i915_vma *ggtt; pgoff_t page_offset; unsigned long pfn; @@ -1482,22 +1481,26 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } /* Use a partial view if the object is bigger than the aperture. */ - if (obj->base.size >= dev_priv->gtt.mappable_end && - obj->tiling_mode == I915_TILING_NONE) { + /* Now pin it into the GTT if needed */ + ggtt = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, + PIN_MAPPABLE | PIN_NONBLOCK); + if (IS_ERR(ggtt)) { static const unsigned int chunk_size = 256; // 1 MiB + struct i915_ggtt_view partial; - memset(&view, 0, sizeof(view)); - view.type = I915_GGTT_VIEW_PARTIAL; - view.params.partial.offset = rounddown(page_offset, chunk_size); - view.params.partial.size = + memset(&partial, 0, sizeof(partial)); + partial.type = I915_GGTT_VIEW_PARTIAL; + partial.params.partial.offset = + rounddown(page_offset, chunk_size); + partial.params.partial.size = min_t(unsigned int, chunk_size, (vma->vm_end - vma->vm_start)/PAGE_SIZE - - view.params.partial.offset); - } + partial.params.partial.offset); - /* Now pin it into the GTT if needed */ - ggtt = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE); + ggtt = i915_gem_object_ggtt_pin(obj, &partial, 0, 0, + PIN_MAPPABLE); + } if (IS_ERR(ggtt)) { ret = PTR_ERR(ggtt); goto unlock; @@ -1515,24 +1518,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) pfn = dev_priv->gtt.mappable_base + ggtt->node.start; pfn >>= PAGE_SHIFT; - if (unlikely(view.type == I915_GGTT_VIEW_PARTIAL)) { - /* Overriding existing pages in partial view does not cause - * us any trouble as TLBs are still valid because the fault - * is due to userspace losing part of the mapping or never - * having accessed it before (at this partials' range). - */ - unsigned long base = vma->vm_start + - (view.params.partial.offset << PAGE_SHIFT); - unsigned int i; - - for (i = 0; i < view.params.partial.size; i++) { - ret = vm_insert_pfn(vma, base + i * PAGE_SIZE, pfn + i); - if (ret) - break; - } - - obj->fault_mappable = true; - } else { + if (ggtt->ggtt_view.type == I915_GGTT_VIEW_NORMAL) { if (!obj->fault_mappable) { unsigned long size = min_t(unsigned long, vma->vm_end - vma->vm_start, @@ -1546,13 +1532,29 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) break; } - - obj->fault_mappable = true; } else ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn + page_offset); + } else { + /* Overriding existing pages in partial view does not cause + * us any trouble as TLBs are still valid because the fault + * is due to userspace losing part of the mapping or never + * having accessed it before (at this partials' range). + */ + const struct i915_ggtt_view *view = &ggtt->ggtt_view; + unsigned long base = vma->vm_start + + (view->params.partial.offset << PAGE_SHIFT); + unsigned int i; + + for (i = 0; i < view->params.partial.size; i++) { + ret = vm_insert_pfn(vma, base + i * PAGE_SIZE, pfn + i); + if (ret) + break; + } } + + obj->fault_mappable = true; unpin: __i915_vma_unpin(ggtt); unlock: -- 2.7.0.rc3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx