diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2018-06-14 12:41:03 +0300 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2018-06-14 16:35:13 +0300 |
commit | a2bbf714834288da0ed4668d4e4d895ffef73de2 (patch) | |
tree | c180280f5e285c4dacb1869330940b6b5a5b83e8 /drivers/gpu/drm/i915/i915_gem_gtt.c | |
parent | e62230deeeae1f096a4be2360204536caf9ad8b6 (diff) | |
download | linux-a2bbf714834288da0ed4668d4e4d895ffef73de2.tar.xz |
drm/i915/gtt: Only keep gen6 page directories pinned while active
In order to be able to evict the gen6 ppgtt, we have to unpin it at some
point. We can simply use our context activity tracking to know when the
ppgtt is no longer in use by hardware, and so only keep it pinned while
being used a request.
For the kernel_context (and thus aliasing_ppgtt), it remains pinned at
all times, as the kernel_context itself is pinned at all times.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180614094103.18025-5-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 267f1f97b9f0..0ee9e154359f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1912,7 +1912,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm) { struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm)); - i915_vma_unpin(ppgtt->vma); i915_vma_destroy(ppgtt->vma); gen6_ppgtt_free_pd(ppgtt); @@ -1998,11 +1997,20 @@ static struct i915_vma *pd_vma_create(struct gen6_hw_ppgtt *ppgtt, int size) return vma; } -static int gen6_ppgtt_pin(struct i915_hw_ppgtt *base) +int gen6_ppgtt_pin(struct i915_hw_ppgtt *base) { struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(base); /* + * Workaround the limited maximum vma->pin_count and the aliasing_ppgtt + * which will be pinned into every active context. + * (When vma->pin_count becomes atomic, I expect we will naturally + * need a larger, unpacked, type and kill this redundancy.) + */ + if (ppgtt->pin_count++) + return 0; + + /* * PPGTT PDEs reside in the GGTT and consists of 512 entries. The * allocator works in address space sizes, so it's multiplied by page * size. We allocate at the top of the GTT to avoid fragmentation. @@ -2012,6 +2020,17 @@ static int gen6_ppgtt_pin(struct i915_hw_ppgtt *base) PIN_GLOBAL | PIN_HIGH); } +void gen6_ppgtt_unpin(struct i915_hw_ppgtt *base) +{ + struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(base); + + GEM_BUG_ON(!ppgtt->pin_count); + if (--ppgtt->pin_count) + return; + + i915_vma_unpin(ppgtt->vma); +} + static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915) { struct i915_ggtt * const ggtt = &i915->ggtt; @@ -2053,21 +2072,8 @@ static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915) if (err) goto err_vma; - err = gen6_ppgtt_pin(&ppgtt->base); - if (err) - goto err_pd; - - DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n", - ppgtt->vma->node.size >> 20, - ppgtt->vma->node.start / PAGE_SIZE); - - DRM_DEBUG_DRIVER("Adding PPGTT at offset %x\n", - ppgtt->base.pd.base.ggtt_offset << 10); - return &ppgtt->base; -err_pd: - gen6_ppgtt_free_pd(ppgtt); err_vma: i915_vma_destroy(ppgtt->vma); err_scratch: |