[Intel-gfx] [PATCH 140/190] drm/i915: Fix partial GGTT faulting
Chris Wilson
chris at chris-wilson.co.uk
Mon Jan 11 02:45:24 PST 2016
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 at 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
More information about the Intel-gfx
mailing list