summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2015-06-02 14:43:52 +0200
committerMarek Olšák <marek.olsak@amd.com>2015-06-05 11:14:54 +0200
commitadd229652240b8b7548ebf3fff968d66be135626 (patch)
tree320de2ed2ac7f8b42b5d2de44641f80c68747261
parentf04107b8a25e242a3aa5ae2a15a6216fe09bb239 (diff)
amdgpu: use alloca and malloc in critical codepaths (v2)
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>
-rw-r--r--amdgpu/amdgpu_bo.c30
-rw-r--r--amdgpu/amdgpu_cs.c5
2 files changed, 23 insertions, 12 deletions
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
index 3d586a8c..f72666b9 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -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;
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 0fa05ece..bf79df35 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -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;
}