amdgpu: use alloca and malloc in critical codepaths (v2)
authorMarek Olšák <marek.olsak@amd.com>
Tue, 2 Jun 2015 12:43:52 +0000 (14:43 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 5 Aug 2015 17:47:51 +0000 (13:47 -0400)
And don't clear the memory when it's unnecessary.

v2: use malloc for arrays that can be big

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
amdgpu/amdgpu_bo.c
amdgpu/amdgpu_cs.c

index 5ac78de..eca2c6f 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -639,9 +640,15 @@ int amdgpu_bo_list_create(amdgpu_device_handle dev,
        unsigned i;
        int r;
 
-       list = calloc(number_of_resources, sizeof(struct drm_amdgpu_bo_list_entry));
+       if (!number_of_resources)
+               return -EINVAL;
 
-       if (list == NULL)
+       /* overflow check for multiplication */
+       if (number_of_resources > UINT32_MAX / sizeof(struct drm_amdgpu_bo_list_entry))
+               return -EINVAL;
+
+       list = malloc(number_of_resources * sizeof(struct drm_amdgpu_bo_list_entry));
+       if (!list)
                return -ENOMEM;
 
        memset(&args, 0, sizeof(args));
@@ -660,15 +667,14 @@ int amdgpu_bo_list_create(amdgpu_device_handle dev,
 
        r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_BO_LIST,
                                &args, sizeof(args));
+       free(list);
        if (r)
-               goto out;
+               return r;
 
-       *result = calloc(1, sizeof(struct amdgpu_bo_list));
+       *result = malloc(sizeof(struct amdgpu_bo_list));
        (*result)->dev = dev;
        (*result)->handle = args.out.list_handle;
-out:
-       free(list);
-       return r;
+       return 0;
 }
 
 int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
@@ -699,11 +705,17 @@ int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
        unsigned i;
        int r;
 
-       list = calloc(number_of_resources, sizeof(struct drm_amdgpu_bo_list_entry));
+       if (!number_of_resources)
+               return -EINVAL;
+
+       /* overflow check for multiplication */
+       if (number_of_resources > UINT32_MAX / sizeof(struct drm_amdgpu_bo_list_entry))
+               return -EINVAL;
+
+       list = malloc(number_of_resources * sizeof(struct drm_amdgpu_bo_list_entry));
        if (list == NULL)
                return -ENOMEM;
 
-       memset(&args, 0, sizeof(args));
        args.in.operation = AMDGPU_BO_LIST_OP_UPDATE;
        args.in.list_handle = handle->handle;
        args.in.bo_number = number_of_resources;
index 0fa05ec..bf79df3 100644 (file)
@@ -201,8 +201,8 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
                sizeof(struct drm_amdgpu_cs_chunk) +
                sizeof(struct drm_amdgpu_cs_chunk_data));
 
-       chunk_array = calloc(1, size);
-       if (NULL == chunk_array)
+       chunk_array = alloca(size);
+       if (!chunk_array)
                return -ENOMEM;
 
        chunks = (struct drm_amdgpu_cs_chunk *)(chunk_array + ibs_request->number_of_ibs + 1);
@@ -262,7 +262,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
 
 error_unlock:
        pthread_mutex_unlock(&context->sequence_mutex);
-       free(chunk_array);
        return r;
 }