In case of error during allocation we should free the entries allocated during the current "transaction". We can't simply reuse the clear_range, since for gen6 we're not shrinking ppgtt. We can extract unwind to a function though, and use range rather than bitmaps. Cc: Arkadiusz Hiler <arkadiusz.hiler@xxxxxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Michel Thierry <michel.thierry@xxxxxxxxx> Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> Signed-off-by: Michał Winiarski <michal.winiarski@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_gtt.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 49e1006..f760c3e 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1917,6 +1917,23 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, kunmap_px(ppgtt, pt_vaddr); } +static void gen6_ppgtt_unwind_pd(struct i915_address_space *vm, + struct i915_page_directory *pd, + uint64_t start, uint64_t length) { + + struct i915_page_table *pt; + uint64_t pde; + + /* We're only using this for cleanup on PT allocation failure, + * and since in this case scratch_pt is already encoded in pde there's + * no need to call gen6_write_pde. + */ + gen6_for_each_pde(pt, pd, start, length, pde) { + pd->page_table[pde] = vm->scratch_pt; + free_pt(vm->i915, pt); + } +} + static int gen6_alloc_va_range(struct i915_address_space *vm, uint64_t start, uint64_t length) { @@ -1954,7 +1971,10 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, pt = alloc_pt(dev_priv); if (IS_ERR(pt)) { ret = PTR_ERR(pt); - goto unwind_out; + gen6_ppgtt_unwind_pd(vm, &ppgtt->pd, + start_save, start - start_save); + mark_tlbs_dirty(ppgtt); + return ret; } gen6_initialize_pt(vm, pt); @@ -1993,17 +2013,6 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, mark_tlbs_dirty(ppgtt); return 0; - -unwind_out: - for_each_set_bit(pde, new_page_tables, I915_PDES) { - struct i915_page_table *pt = ppgtt->pd.page_table[pde]; - - ppgtt->pd.page_table[pde] = vm->scratch_pt; - free_pt(dev_priv, pt); - } - - mark_tlbs_dirty(ppgtt); - return ret; } static int gen6_init_scratch(struct i915_address_space *vm) -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx