drm/vc4: Use drm_malloc_ab to fix large rendering jobs.
authorEric Anholt <eric@anholt.net>
Tue, 19 Jul 2016 18:32:44 +0000 (11:32 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 20 Aug 2016 02:16:40 +0000 (19:16 -0700)
If you exceeded the size that kmalloc would return, you'd get a dmesg
warning and a return from the job submit.  We can handle much
allocations with vmalloc, and drm_malloc_ab makes that decision.

Fixes failure in piglit's scissor-many.

Signed-off-by: Eric Anholt <eric@anholt.net>
drivers/gpu/drm/vc4/vc4_gem.c

index 62df61f..bfd1b52 100644 (file)
@@ -534,8 +534,8 @@ vc4_cl_lookup_bos(struct drm_device *dev,
                return -EINVAL;
        }
 
-       exec->bo = kcalloc(exec->bo_count, sizeof(struct drm_gem_cma_object *),
-                          GFP_KERNEL);
+       exec->bo = drm_calloc_large(exec->bo_count,
+                                   sizeof(struct drm_gem_cma_object *));
        if (!exec->bo) {
                DRM_ERROR("Failed to allocate validated BO pointers\n");
                return -ENOMEM;
@@ -608,7 +608,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
         * read the contents back for validation, and I think the
         * bo->vaddr is uncached access.
         */
-       temp = kmalloc(temp_size, GFP_KERNEL);
+       temp = drm_malloc_ab(temp_size, 1);
        if (!temp) {
                DRM_ERROR("Failed to allocate storage for copying "
                          "in bin/render CLs.\n");
@@ -675,7 +675,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
        ret = vc4_validate_shader_recs(dev, exec);
 
 fail:
-       kfree(temp);
+       drm_free_large(temp);
        return ret;
 }
 
@@ -688,7 +688,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
        if (exec->bo) {
                for (i = 0; i < exec->bo_count; i++)
                        drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
-               kfree(exec->bo);
+               drm_free_large(exec->bo);
        }
 
        while (!list_empty(&exec->unref_list)) {