From: Ben Widawsky <benjamin.widawsky@xxxxxxxxx> Start using gen8_for_each_pdpe macro to allocate the page directories. Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx> Signed-off-by: Michel Thierry <michel.thierry@xxxxxxxxx> --- 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 07f0d24..274b20f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -594,8 +594,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); + ppgtt->pdp.pagedir[pdpe] = NULL; } } @@ -670,25 +672,39 @@ 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.pagedir[i] = alloc_pd_single(); - if (IS_ERR(ppgtt->pdp.pagedir[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->pagedir[pdpe] = alloc_pd_single(); + if (IS_ERR(ppgtt->pdp.pagedir[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.pagedir[i]); + while (pdpe--) { + free_pd_single(ppgtt->pdp.pagedir[pdpe]); + ppgtt->num_pd_pages--; + } + + WARN_ON(ppgtt->num_pd_pages); return -ENOMEM; } @@ -698,7 +714,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; @@ -775,6 +792,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) @@ -822,8 +843,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_PAGE * PAGE_SIZE; DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n", ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp); -- 2.1.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx