We can just operate on ranges and make use of cleanup functions
introduced with ppgtt shrinking.

Cc: Arkadiusz Hiler <[email protected]>
Cc: Chris Wilson <[email protected]>
Cc: Joonas Lahtinen <[email protected]>
Cc: Michel Thierry <[email protected]>
Cc: Mika Kuoppala <[email protected]>
Signed-off-by: Michał Winiarski <[email protected]>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 82 ++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f760c3e..c6f0708 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1109,6 +1109,7 @@ static int gen8_ppgtt_alloc_pagetabs(struct 
i915_address_space *vm,
        struct drm_i915_private *dev_priv = vm->i915;
        struct i915_page_table *pt;
        uint32_t pde;
+       const uint64_t start_save = start;
 
        gen8_for_each_pde(pt, pd, start, length, pde) {
                /* Don't reallocate page tables */
@@ -1119,8 +1120,11 @@ static int gen8_ppgtt_alloc_pagetabs(struct 
i915_address_space *vm,
                }
 
                pt = alloc_pt(dev_priv);
-               if (IS_ERR(pt))
-                       goto unwind_out;
+               if (IS_ERR(pt)) {
+                       gen8_ppgtt_clear_pd(vm, pd, start_save,
+                                           start - start_save);
+                       return PTR_ERR(pt);
+               }
 
                gen8_initialize_pt(vm, pt);
                pd->page_table[pde] = pt;
@@ -1129,12 +1133,6 @@ static int gen8_ppgtt_alloc_pagetabs(struct 
i915_address_space *vm,
        }
 
        return 0;
-
-unwind_out:
-       for_each_set_bit(pde, new_pts, I915_PDES)
-               free_pt(dev_priv, pd->page_table[pde]);
-
-       return -ENOMEM;
 }
 
 /**
@@ -1171,6 +1169,7 @@ gen8_ppgtt_alloc_page_directories(struct 
i915_address_space *vm,
        struct i915_page_directory *pd;
        uint32_t pdpe;
        uint32_t pdpes = I915_PDPES_PER_PDP(dev_priv);
+       const uint64_t start_save = start;
 
        WARN_ON(!bitmap_empty(new_pds, pdpes));
 
@@ -1179,8 +1178,11 @@ gen8_ppgtt_alloc_page_directories(struct 
i915_address_space *vm,
                        continue;
 
                pd = alloc_pd(dev_priv);
-               if (IS_ERR(pd))
-                       goto unwind_out;
+               if (IS_ERR(pd)) {
+                       gen8_ppgtt_clear_pdp(vm, pdp, start_save,
+                                            start - start_save);
+                       return PTR_ERR(pd);
+               }
 
                gen8_initialize_pd(vm, pd);
                pdp->page_directory[pdpe] = pd;
@@ -1189,12 +1191,6 @@ gen8_ppgtt_alloc_page_directories(struct 
i915_address_space *vm,
        }
 
        return 0;
-
-unwind_out:
-       for_each_set_bit(pdpe, new_pds, pdpes)
-               free_pd(dev_priv, pdp->page_directory[pdpe]);
-
-       return -ENOMEM;
 }
 
 /**
@@ -1223,14 +1219,18 @@ gen8_ppgtt_alloc_page_dirpointers(struct 
i915_address_space *vm,
        struct drm_i915_private *dev_priv = vm->i915;
        struct i915_page_directory_pointer *pdp;
        uint32_t pml4e;
+       const uint64_t start_save = start;
 
        WARN_ON(!bitmap_empty(new_pdps, GEN8_PML4ES_PER_PML4));
 
        gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
                if (!test_bit(pml4e, pml4->used_pml4es)) {
                        pdp = alloc_pdp(dev_priv);
-                       if (IS_ERR(pdp))
-                               goto unwind_out;
+                       if (IS_ERR(pdp)) {
+                               gen8_ppgtt_clear_pml4(vm, pml4, start_save,
+                                                     start - start_save);
+                               return PTR_ERR(pdp);
+                       }
 
                        gen8_initialize_pdp(vm, pdp);
                        pml4->pdps[pml4e] = pdp;
@@ -1243,12 +1243,6 @@ gen8_ppgtt_alloc_page_dirpointers(struct 
i915_address_space *vm,
        }
 
        return 0;
-
-unwind_out:
-       for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
-               free_pdp(dev_priv, pml4->pdps[pml4e]);
-
-       return -ENOMEM;
 }
 
 static void
@@ -1295,7 +1289,6 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
 {
        struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
        unsigned long *new_page_dirs, *new_page_tables;
-       struct drm_i915_private *dev_priv = vm->i915;
        struct i915_page_directory *pd;
        const uint64_t start_save = start;
        const uint64_t length_save = length;
@@ -1328,8 +1321,12 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
        gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
                ret = gen8_ppgtt_alloc_pagetabs(vm, pd, start, length,
                                                new_page_tables + pdpe * 
BITS_TO_LONGS(I915_PDES));
-               if (ret)
-                       goto err_out;
+               if (ret) {
+                       gen8_ppgtt_clear_pdp(vm, pdp, start_save,
+                                            start - start_save);
+                       mark_tlbs_dirty(ppgtt);
+                       return ret;
+               }
        }
 
        start = start_save;
@@ -1381,23 +1378,6 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
        free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
        mark_tlbs_dirty(ppgtt);
        return 0;
-
-err_out:
-       while (pdpe--) {
-               unsigned long temp;
-
-               for_each_set_bit(temp, new_page_tables + pdpe *
-                               BITS_TO_LONGS(I915_PDES), I915_PDES)
-                       free_pt(dev_priv,
-                               pdp->page_directory[pdpe]->page_table[temp]);
-       }
-
-       for_each_set_bit(pdpe, new_page_dirs, pdpes)
-               free_pd(dev_priv, pdp->page_directory[pdpe]);
-
-       free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
-       mark_tlbs_dirty(ppgtt);
-       return ret;
 }
 
 static int gen8_alloc_va_range_4lvl(struct i915_address_space *vm,
@@ -1410,6 +1390,7 @@ static int gen8_alloc_va_range_4lvl(struct 
i915_address_space *vm,
        struct i915_page_directory_pointer *pdp;
        uint64_t pml4e;
        int ret = 0;
+       const uint64_t start_save = start;
 
        /* Do the pml4 allocations first, so we don't need to track the newly
         * allocated tables below the pdp */
@@ -1431,8 +1412,11 @@ static int gen8_alloc_va_range_4lvl(struct 
i915_address_space *vm,
                WARN_ON(!pdp);
 
                ret = gen8_alloc_va_range_3lvl(vm, pdp, start, length);
-               if (ret)
-                       goto err_out;
+               if (ret) {
+                       gen8_ppgtt_clear_pml4(vm, pml4, start_save,
+                                             start - start_save);
+                       return ret;
+               }
 
                gen8_setup_page_directory_pointer(ppgtt, pml4, pdp, pml4e);
        }
@@ -1441,12 +1425,6 @@ static int gen8_alloc_va_range_4lvl(struct 
i915_address_space *vm,
                  GEN8_PML4ES_PER_PML4);
 
        return 0;
-
-err_out:
-       for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
-               gen8_ppgtt_cleanup_3lvl(vm->i915, pml4->pdps[pml4e]);
-
-       return ret;
 }
 
 static int gen8_alloc_va_range(struct i915_address_space *vm,
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to