Commit bf75d59e authored by Chris Wilson's avatar Chris Wilson

drm/i915: Only unwind the local pgtable layer if empty

Only if we allocated the layer and the lower level failed should we
remove this layer when unwinding. Otherwise we ignore the overlapping
entries by overwriting the old layer with scratch.

Fixes: c5d092a4 ("drm/i915: Remove bitmap tracking for used-pml4")
Fixes: e2b763ca ("drm/i915: Remove bitmap tracking for used-pdpes")
Reported-by: default avatarMatthew Auld <matthew.william.auld@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99947
Testcase: igt/drv_selftest/live_gtt
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Tested-by: default avatarMatthew Auld <matthew.auld@intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170227122654.27651-1-chris@chris-wilson.co.uk
parent 69060d96
...@@ -716,10 +716,13 @@ static bool gen8_ppgtt_clear_pd(struct i915_address_space *vm, ...@@ -716,10 +716,13 @@ static bool gen8_ppgtt_clear_pd(struct i915_address_space *vm,
u32 pde; u32 pde;
gen8_for_each_pde(pt, pd, start, length, pde) { gen8_for_each_pde(pt, pd, start, length, pde) {
GEM_BUG_ON(pt == vm->scratch_pt);
if (!gen8_ppgtt_clear_pt(vm, pt, start, length)) if (!gen8_ppgtt_clear_pt(vm, pt, start, length))
continue; continue;
gen8_ppgtt_set_pde(vm, pd, vm->scratch_pt, pde); gen8_ppgtt_set_pde(vm, pd, vm->scratch_pt, pde);
GEM_BUG_ON(!pd->used_pdes);
pd->used_pdes--; pd->used_pdes--;
free_pt(vm, pt); free_pt(vm, pt);
...@@ -755,10 +758,13 @@ static bool gen8_ppgtt_clear_pdp(struct i915_address_space *vm, ...@@ -755,10 +758,13 @@ static bool gen8_ppgtt_clear_pdp(struct i915_address_space *vm,
unsigned int pdpe; unsigned int pdpe;
gen8_for_each_pdpe(pd, pdp, start, length, pdpe) { gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
GEM_BUG_ON(pd == vm->scratch_pd);
if (!gen8_ppgtt_clear_pd(vm, pd, start, length)) if (!gen8_ppgtt_clear_pd(vm, pd, start, length))
continue; continue;
gen8_ppgtt_set_pdpe(vm, pdp, vm->scratch_pd, pdpe); gen8_ppgtt_set_pdpe(vm, pdp, vm->scratch_pd, pdpe);
GEM_BUG_ON(!pdp->used_pdpes);
pdp->used_pdpes--; pdp->used_pdpes--;
free_pd(vm, pd); free_pd(vm, pd);
...@@ -801,6 +807,8 @@ static void gen8_ppgtt_clear_4lvl(struct i915_address_space *vm, ...@@ -801,6 +807,8 @@ static void gen8_ppgtt_clear_4lvl(struct i915_address_space *vm,
GEM_BUG_ON(!USES_FULL_48BIT_PPGTT(vm->i915)); GEM_BUG_ON(!USES_FULL_48BIT_PPGTT(vm->i915));
gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) { gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
GEM_BUG_ON(pdp == vm->scratch_pdp);
if (!gen8_ppgtt_clear_pdp(vm, pdp, start, length)) if (!gen8_ppgtt_clear_pdp(vm, pdp, start, length))
continue; continue;
...@@ -1089,6 +1097,7 @@ static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm, ...@@ -1089,6 +1097,7 @@ static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm,
gen8_ppgtt_set_pde(vm, pd, pt, pde); gen8_ppgtt_set_pde(vm, pd, pt, pde);
pd->used_pdes++; pd->used_pdes++;
GEM_BUG_ON(pd->used_pdes > I915_PDES);
} }
pt->used_ptes += gen8_pte_count(start, length); pt->used_ptes += gen8_pte_count(start, length);
...@@ -1118,21 +1127,25 @@ static int gen8_ppgtt_alloc_pdp(struct i915_address_space *vm, ...@@ -1118,21 +1127,25 @@ static int gen8_ppgtt_alloc_pdp(struct i915_address_space *vm,
gen8_initialize_pd(vm, pd); gen8_initialize_pd(vm, pd);
gen8_ppgtt_set_pdpe(vm, pdp, pd, pdpe); gen8_ppgtt_set_pdpe(vm, pdp, pd, pdpe);
pdp->used_pdpes++; pdp->used_pdpes++;
GEM_BUG_ON(pdp->used_pdpes > I915_PDPES_PER_PDP(vm));
mark_tlbs_dirty(i915_vm_to_ppgtt(vm)); mark_tlbs_dirty(i915_vm_to_ppgtt(vm));
} }
ret = gen8_ppgtt_alloc_pd(vm, pd, start, length); ret = gen8_ppgtt_alloc_pd(vm, pd, start, length);
if (unlikely(ret)) { if (unlikely(ret))
gen8_ppgtt_set_pdpe(vm, pdp, vm->scratch_pd, pdpe); goto unwind_pd;
pdp->used_pdpes--;
free_pd(vm, pd);
goto unwind;
}
} }
return 0; return 0;
unwind_pd:
if (!pd->used_pdes) {
gen8_ppgtt_set_pdpe(vm, pdp, vm->scratch_pd, pdpe);
GEM_BUG_ON(!pdp->used_pdpes);
pdp->used_pdpes--;
free_pd(vm, pd);
}
unwind: unwind:
gen8_ppgtt_clear_pdp(vm, pdp, from, start - from); gen8_ppgtt_clear_pdp(vm, pdp, from, start - from);
return -ENOMEM; return -ENOMEM;
...@@ -1166,15 +1179,17 @@ static int gen8_ppgtt_alloc_4lvl(struct i915_address_space *vm, ...@@ -1166,15 +1179,17 @@ static int gen8_ppgtt_alloc_4lvl(struct i915_address_space *vm,
} }
ret = gen8_ppgtt_alloc_pdp(vm, pdp, start, length); ret = gen8_ppgtt_alloc_pdp(vm, pdp, start, length);
if (unlikely(ret)) { if (unlikely(ret))
gen8_ppgtt_set_pml4e(pml4, vm->scratch_pdp, pml4e); goto unwind_pdp;
free_pdp(vm, pdp);
goto unwind;
}
} }
return 0; return 0;
unwind_pdp:
if (!pdp->used_pdpes) {
gen8_ppgtt_set_pml4e(pml4, vm->scratch_pdp, pml4e);
free_pdp(vm, pdp);
}
unwind: unwind:
gen8_ppgtt_clear_4lvl(vm, from, start - from); gen8_ppgtt_clear_4lvl(vm, from, start - from);
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment