Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_gtt.c | 43 ++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 14aae05..10cfad8 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -546,8 +546,10 @@ static void gen8_teardown_va_range(struct i915_address_space *vm, uint64_t pd_start = start; gen8_for_each_pde(pt, pd, pd_start, pd_len, temp, pde) { free_pt_single(pt, vm->dev); + pd->page_tables[pde] = NULL; } free_pd_single(pd, vm->dev); + ppgtt->pdp.pagedirs[pdpe] = NULL; } } @@ -598,26 +600,40 @@ unwind_out: return -ENOMEM; } -static int gen8_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt, - const int max_pdp) +static int gen8_ppgtt_alloc_pagedirs(struct i915_pagedirpo *pdp, + uint64_t start, + uint64_t length) { - int i; + struct i915_hw_ppgtt *ppgtt = + container_of(pdp, struct i915_hw_ppgtt, pdp); + struct i915_pagedir *unused; + uint64_t temp; + uint32_t pdpe; - for (i = 0; i < max_pdp; i++) { - ppgtt->pdp.pagedirs[i] = alloc_pd_single(ppgtt->base.dev); - if (IS_ERR(ppgtt->pdp.pagedirs[i])) + /* FIXME: PPGTT container_of won't work for 64b */ + BUG_ON((start + length) > 0x800000000ULL); + + gen8_for_each_pdpe(unused, pdp, start, length, temp, pdpe) { + BUG_ON(unused); + pdp->pagedirs[pdpe] = alloc_pd_single(ppgtt->base.dev); + if (IS_ERR(ppgtt->pdp.pagedirs[pdpe])) goto unwind_out; + + ppgtt->num_pd_pages++; } - ppgtt->num_pd_pages = max_pdp; BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPES); return 0; unwind_out: - while (i--) - free_pd_single(ppgtt->pdp.pagedirs[i], + while (pdpe--) { + free_pd_single(ppgtt->pdp.pagedirs[pdpe], ppgtt->base.dev); + ppgtt->num_pd_pages--; + } + + WARN_ON(ppgtt->num_pd_pages); return -ENOMEM; } @@ -627,7 +643,8 @@ static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt, { int ret; - ret = gen8_ppgtt_allocate_page_directories(ppgtt, max_pdp); + ret = gen8_ppgtt_alloc_pagedirs(&ppgtt->pdp, ppgtt->base.start, + ppgtt->base.total); if (ret) return ret; @@ -664,6 +681,10 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) if (size % (1<<30)) DRM_INFO("Pages will be wasted unless GTT size (%llu) is divisible by 1GB\n", size); + ppgtt->base.start = 0; + ppgtt->base.total = size; + BUG_ON(ppgtt->base.total == 0); + /* 1. Do all our allocations for page directories and page tables. */ ret = gen8_ppgtt_alloc(ppgtt, max_pdp); if (ret) @@ -697,8 +718,6 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) ppgtt->base.clear_range = gen8_ppgtt_clear_range; ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; ppgtt->base.cleanup = gen8_ppgtt_cleanup; - ppgtt->base.start = 0; - ppgtt->base.total = ppgtt->num_pd_entries * GEN8_PTES_PER_PT * PAGE_SIZE; DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n", ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp); -- 1.9.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx