amdgpu: add a function to create amdgpu bo internally (v4)

a helper function to create and initialize amdgpu bo

v2: update error handling: add label and free bo
v3: update error handling: separate each error label
v4: update error handling and rebase

Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
main
Junwei Zhang 2018-08-14 11:00:09 +08:00 committed by Christian König
parent 3d8b6ea664
commit f31fd57c60
1 changed files with 108 additions and 107 deletions

View File

@ -48,18 +48,12 @@ static void amdgpu_close_kms_handle(amdgpu_device_handle dev,
drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &args); drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &args);
} }
int amdgpu_bo_alloc(amdgpu_device_handle dev, static int amdgpu_bo_create(amdgpu_device_handle dev,
struct amdgpu_bo_alloc_request *alloc_buffer, uint64_t size,
uint32_t handle,
amdgpu_bo_handle *buf_handle) amdgpu_bo_handle *buf_handle)
{ {
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
union drm_amdgpu_gem_create args;
unsigned heap = alloc_buffer->preferred_heap;
int r = 0;
/* It's an error if the heap is not specified */
if (!(heap & (AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_VRAM)))
return -EINVAL;
bo = calloc(1, sizeof(struct amdgpu_bo)); bo = calloc(1, sizeof(struct amdgpu_bo));
if (!bo) if (!bo)
@ -67,7 +61,25 @@ int amdgpu_bo_alloc(amdgpu_device_handle dev,
atomic_set(&bo->refcount, 1); atomic_set(&bo->refcount, 1);
bo->dev = dev; bo->dev = dev;
bo->alloc_size = alloc_buffer->alloc_size; bo->alloc_size = size;
bo->handle = handle;
pthread_mutex_init(&bo->cpu_access_mutex, NULL);
*buf_handle = bo;
return 0;
}
int amdgpu_bo_alloc(amdgpu_device_handle dev,
struct amdgpu_bo_alloc_request *alloc_buffer,
amdgpu_bo_handle *buf_handle)
{
union drm_amdgpu_gem_create args;
unsigned heap = alloc_buffer->preferred_heap;
int r = 0;
/* It's an error if the heap is not specified */
if (!(heap & (AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_VRAM)))
return -EINVAL;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.in.bo_size = alloc_buffer->alloc_size; args.in.bo_size = alloc_buffer->alloc_size;
@ -80,24 +92,23 @@ int amdgpu_bo_alloc(amdgpu_device_handle dev,
/* Allocate the buffer with the preferred heap. */ /* Allocate the buffer with the preferred heap. */
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_CREATE, r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_CREATE,
&args, sizeof(args)); &args, sizeof(args));
if (r)
goto out;
r = amdgpu_bo_create(dev, alloc_buffer->alloc_size, args.out.handle,
buf_handle);
if (r) { if (r) {
free(bo); amdgpu_close_kms_handle(dev, args.out.handle);
return r; goto out;
} }
bo->handle = args.out.handle; pthread_mutex_lock(&dev->bo_table_mutex);
r = handle_table_insert(&dev->bo_handles, (*buf_handle)->handle,
pthread_mutex_lock(&bo->dev->bo_table_mutex); *buf_handle);
r = handle_table_insert(&bo->dev->bo_handles, bo->handle, bo); pthread_mutex_unlock(&dev->bo_table_mutex);
pthread_mutex_unlock(&bo->dev->bo_table_mutex);
pthread_mutex_init(&bo->cpu_access_mutex, NULL);
if (r) if (r)
amdgpu_bo_free(bo); amdgpu_bo_free(*buf_handle);
else out:
*buf_handle = bo;
return r; return r;
} }
@ -257,7 +268,9 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
struct drm_gem_open open_arg = {}; struct drm_gem_open open_arg = {};
struct drm_gem_close close_arg = {}; struct drm_gem_close close_arg = {};
struct amdgpu_bo *bo = NULL; struct amdgpu_bo *bo = NULL;
int r; uint32_t handle = 0, flink_name = 0;
uint64_t alloc_size = 0;
int r = 0;
int dma_fd; int dma_fd;
uint64_t dma_buf_size = 0; uint64_t dma_buf_size = 0;
@ -267,22 +280,18 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
/* Convert a DMA buf handle to a KMS handle now. */ /* Convert a DMA buf handle to a KMS handle now. */
if (type == amdgpu_bo_handle_type_dma_buf_fd) { if (type == amdgpu_bo_handle_type_dma_buf_fd) {
uint32_t handle;
off_t size; off_t size;
/* Get a KMS handle. */ /* Get a KMS handle. */
r = drmPrimeFDToHandle(dev->fd, shared_handle, &handle); r = drmPrimeFDToHandle(dev->fd, shared_handle, &handle);
if (r) { if (r)
pthread_mutex_unlock(&dev->bo_table_mutex); goto unlock;
return r;
}
/* Query the buffer size. */ /* Query the buffer size. */
size = lseek(shared_handle, 0, SEEK_END); size = lseek(shared_handle, 0, SEEK_END);
if (size == (off_t)-1) { if (size == (off_t)-1) {
pthread_mutex_unlock(&dev->bo_table_mutex); r = -errno;
amdgpu_close_kms_handle(dev, handle); goto free_bo_handle;
return -errno;
} }
lseek(shared_handle, 0, SEEK_SET); lseek(shared_handle, 0, SEEK_SET);
@ -303,12 +312,12 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
case amdgpu_bo_handle_type_kms: case amdgpu_bo_handle_type_kms:
case amdgpu_bo_handle_type_kms_noimport: case amdgpu_bo_handle_type_kms_noimport:
/* Importing a KMS handle in not allowed. */ /* Importing a KMS handle in not allowed. */
pthread_mutex_unlock(&dev->bo_table_mutex); r = -EPERM;
return -EPERM; goto unlock;
default: default:
pthread_mutex_unlock(&dev->bo_table_mutex); r = -EINVAL;
return -EINVAL; goto unlock;
} }
if (bo) { if (bo) {
@ -321,62 +330,37 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
return 0; return 0;
} }
bo = calloc(1, sizeof(struct amdgpu_bo));
if (!bo) {
pthread_mutex_unlock(&dev->bo_table_mutex);
if (type == amdgpu_bo_handle_type_dma_buf_fd) {
amdgpu_close_kms_handle(dev, shared_handle);
}
return -ENOMEM;
}
/* Open the handle. */ /* Open the handle. */
switch (type) { switch (type) {
case amdgpu_bo_handle_type_gem_flink_name: case amdgpu_bo_handle_type_gem_flink_name:
open_arg.name = shared_handle; open_arg.name = shared_handle;
r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_OPEN, &open_arg); r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_OPEN, &open_arg);
if (r) { if (r)
free(bo); goto unlock;
pthread_mutex_unlock(&dev->bo_table_mutex);
return r;
}
bo->handle = open_arg.handle; flink_name = shared_handle;
handle = open_arg.handle;
alloc_size = open_arg.size;
if (dev->flink_fd != dev->fd) { if (dev->flink_fd != dev->fd) {
close_arg.handle = open_arg.handle; r = drmPrimeHandleToFD(dev->flink_fd, handle,
r = drmPrimeHandleToFD(dev->flink_fd, bo->handle, DRM_CLOEXEC, &dma_fd); DRM_CLOEXEC, &dma_fd);
if (r) { if (r)
free(bo); goto free_bo_handle;
drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE, r = drmPrimeFDToHandle(dev->fd, dma_fd, &handle);
&close_arg);
pthread_mutex_unlock(&dev->bo_table_mutex);
return r;
}
r = drmPrimeFDToHandle(dev->fd, dma_fd, &bo->handle );
close(dma_fd); close(dma_fd);
drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE, &close_arg); if (r)
goto free_bo_handle;
if (r) { close_arg.handle = open_arg.handle;
free(bo); r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE,
pthread_mutex_unlock(&dev->bo_table_mutex); &close_arg);
return r; if (r)
} goto free_bo_handle;
}
bo->flink_name = shared_handle;
bo->alloc_size = open_arg.size;
r = handle_table_insert(&dev->bo_flink_names, shared_handle,
bo);
if (r) {
pthread_mutex_unlock(&dev->bo_table_mutex);
amdgpu_bo_free(bo);
return r;
} }
break; break;
case amdgpu_bo_handle_type_dma_buf_fd: case amdgpu_bo_handle_type_dma_buf_fd:
bo->handle = shared_handle; handle = shared_handle;
bo->alloc_size = dma_buf_size; alloc_size = dma_buf_size;
break; break;
case amdgpu_bo_handle_type_kms: case amdgpu_bo_handle_type_kms:
@ -385,16 +369,41 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
} }
/* Initialize it. */ /* Initialize it. */
atomic_set(&bo->refcount, 1); r = amdgpu_bo_create(dev, alloc_size, handle, &bo);
bo->dev = dev; if (r)
pthread_mutex_init(&bo->cpu_access_mutex, NULL); goto free_bo_handle;
handle_table_insert(&dev->bo_handles, bo->handle, bo); r = handle_table_insert(&dev->bo_handles, bo->handle, bo);
pthread_mutex_unlock(&dev->bo_table_mutex); if (r)
goto free_bo_handle;
if (flink_name) {
bo->flink_name = flink_name;
r = handle_table_insert(&dev->bo_flink_names, flink_name,
bo);
if (r)
goto remove_handle;
}
output->buf_handle = bo; output->buf_handle = bo;
output->alloc_size = bo->alloc_size; output->alloc_size = bo->alloc_size;
pthread_mutex_unlock(&dev->bo_table_mutex);
return 0; return 0;
remove_handle:
handle_table_remove(&dev->bo_handles, bo->handle);
free_bo_handle:
if (flink_name && !close_arg.handle && open_arg.handle) {
close_arg.handle = open_arg.handle;
drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_CLOSE, &close_arg);
}
if (bo)
amdgpu_bo_free(bo);
else
amdgpu_close_kms_handle(dev, handle);
unlock:
pthread_mutex_unlock(&dev->bo_table_mutex);
return r;
} }
int amdgpu_bo_free(amdgpu_bo_handle buf_handle) int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
@ -580,7 +589,6 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
amdgpu_bo_handle *buf_handle) amdgpu_bo_handle *buf_handle)
{ {
int r; int r;
struct amdgpu_bo *bo;
struct drm_amdgpu_gem_userptr args; struct drm_amdgpu_gem_userptr args;
args.addr = (uintptr_t)cpu; args.addr = (uintptr_t)cpu;
@ -590,28 +598,21 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_USERPTR, r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_USERPTR,
&args, sizeof(args)); &args, sizeof(args));
if (r) if (r)
return r; goto out;
bo = calloc(1, sizeof(struct amdgpu_bo)); r = amdgpu_bo_create(dev, size, args.handle, buf_handle);
if (!bo) if (r) {
return -ENOMEM; amdgpu_close_kms_handle(dev, args.handle);
goto out;
atomic_set(&bo->refcount, 1); }
bo->dev = dev;
bo->alloc_size = size;
bo->handle = args.handle;
pthread_mutex_lock(&bo->dev->bo_table_mutex);
r = handle_table_insert(&bo->dev->bo_handles, bo->handle, bo);
pthread_mutex_unlock(&bo->dev->bo_table_mutex);
pthread_mutex_init(&bo->cpu_access_mutex, NULL);
pthread_mutex_lock(&dev->bo_table_mutex);
r = handle_table_insert(&dev->bo_handles, (*buf_handle)->handle,
*buf_handle);
pthread_mutex_unlock(&dev->bo_table_mutex);
if (r) if (r)
amdgpu_bo_free(bo); amdgpu_bo_free(*buf_handle);
else out:
*buf_handle = bo;
return r; return r;
} }