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 <ch...@chris-wilson.co.uk>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to