diff options
author | Ben Goz <ben.goz@amd.com> | 2014-12-07 14:50:28 +0200 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2015-06-12 23:24:52 +0300 |
commit | dd1947fcff12ad564437fb7c4b3cd1e616cc97e2 (patch) | |
tree | e03dc30db01a011c270a68254eb4c90ebcd5a80f | |
parent | 992c631933fd3bc81e56323045797669d0792dbd (diff) |
Add CZ support to queues module
Signed-off-by: Ben Goz <ben.goz@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r-- | src/queues.c | 146 |
1 files changed, 140 insertions, 6 deletions
diff --git a/src/queues.c b/src/queues.c index 1feb9ba..2d7692f 100644 --- a/src/queues.c +++ b/src/queues.c @@ -30,15 +30,73 @@ #include <sys/mman.h> #include <math.h> #include <stdio.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <fcntl.h> /* 1024 doorbells, 4 bytes each doorbell */ #define DOORBELLS_PAGE_SIZE 1024 * 4 +struct device_info +{ + uint32_t ctx_save_restore_size; + uint32_t eop_buffer_size; +}; + +struct device_info kaveri_device_info = { + .ctx_save_restore_size = 0, + .eop_buffer_size = 0, +}; + +struct device_info carrizo_device_info = { + .ctx_save_restore_size = 2756608, + .eop_buffer_size = 4096, +}; + +struct device_id +{ + uint16_t dev_id; + struct device_info *dev_info; +}; + +struct device_id supported_devices[] = { + { 0x1304, &kaveri_device_info }, /* Kaveri */ + { 0x1305, &kaveri_device_info }, /* Kaveri */ + { 0x1306, &kaveri_device_info }, /* Kaveri */ + { 0x1307, &kaveri_device_info }, /* Kaveri */ + { 0x1309, &kaveri_device_info }, /* Kaveri */ + { 0x130A, &kaveri_device_info }, /* Kaveri */ + { 0x130B, &kaveri_device_info }, /* Kaveri */ + { 0x130C, &kaveri_device_info }, /* Kaveri */ + { 0x130D, &kaveri_device_info }, /* Kaveri */ + { 0x130E, &kaveri_device_info }, /* Kaveri */ + { 0x130F, &kaveri_device_info }, /* Kaveri */ + { 0x1310, &kaveri_device_info }, /* Kaveri */ + { 0x1311, &kaveri_device_info }, /* Kaveri */ + { 0x1312, &kaveri_device_info }, /* Kaveri */ + { 0x1313, &kaveri_device_info }, /* Kaveri */ + { 0x1315, &kaveri_device_info }, /* Kaveri */ + { 0x1316, &kaveri_device_info }, /* Kaveri */ + { 0x1317, &kaveri_device_info }, /* Kaveri */ + { 0x1318, &kaveri_device_info }, /* Kaveri */ + { 0x131B, &kaveri_device_info }, /* Kaveri */ + { 0x131C, &kaveri_device_info }, /* Kaveri */ + { 0x131D, &kaveri_device_info }, /* Kaveri */ + { 0x9870, &carrizo_device_info }, /* Carrizo */ + { 0x9874, &carrizo_device_info }, /* Carrizo */ + { 0x9875, &carrizo_device_info }, /* Carrizo */ + { 0x9876, &carrizo_device_info }, /* Carrizo */ + { 0x9877, &carrizo_device_info }, /* Carrizo */ + { 0, NULL } +}; + struct queue { uint32_t queue_id; uint32_t wptr; uint32_t rptr; + void *eop_buffer; + void *ctx_save_restore; }; struct process_doorbells @@ -50,6 +108,74 @@ struct process_doorbells struct process_doorbells doorbells[] = {[0 ... (NUM_OF_SUPPORTED_GPUS-1)] = {.need_mmap = true, .doorbells = NULL, .doorbells_mutex = PTHREAD_MUTEX_INITIALIZER}}; +static struct device_info *get_device_info_by_dev_id(uint16_t dev_id) +{ + int i = 0; + while (supported_devices[i].dev_id != 0) { + if (supported_devices[i].dev_id == dev_id) { + return supported_devices[i].dev_info; + } + i++; + } + + return NULL; +} + +static void free_queue(struct queue *q) +{ + if (q->eop_buffer) + free(q->eop_buffer); + if (q->ctx_save_restore) + free(q->ctx_save_restore); + free(q); +} + +static void* allocate_exec_aligned_memory(uint32_t size, uint32_t align) +{ + void *ptr; + int retval; + + retval = posix_memalign(&ptr, align, size); + if (retval != 0) + return NULL; + + retval = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC); + if (retval != 0) { + free(ptr); + return NULL; + } + + memset(ptr, 0, size); + return ptr; +} + +static int handle_concrete_asic(struct device_info *dev_info, struct queue *q, + struct kfd_ioctl_create_queue_args *args) +{ + if (dev_info) { + if (dev_info->eop_buffer_size > 0) { + q->eop_buffer = + allocate_exec_aligned_memory(dev_info->eop_buffer_size, PAGE_SIZE); + if (q->eop_buffer == NULL) { + return HSAKMT_STATUS_NO_MEMORY; + } + args->eop_buffer_address = (uintptr_t)q->eop_buffer; + args->eop_buffer_size = dev_info->eop_buffer_size; + } + if (dev_info->ctx_save_restore_size > 0) { + args->ctx_save_restore_size = dev_info->ctx_save_restore_size; + q->ctx_save_restore = + allocate_exec_aligned_memory(dev_info->ctx_save_restore_size, PAGE_SIZE); + if (q->ctx_save_restore == NULL) {; + return HSAKMT_STATUS_NO_MEMORY; + } + args->ctx_save_restore_address = (uintptr_t)q->ctx_save_restore; + } + } + + return HSAKMT_STATUS_SUCCESS; +} + HSAKMT_STATUS HSAKMTAPI hsaKmtCreateQueue( @@ -65,6 +191,8 @@ hsaKmtCreateQueue( { HSAKMT_STATUS result; uint32_t gpu_id; + uint16_t dev_id; + struct device_info *dev_info; int err; void* ptr; CHECK_KFD_OPEN(); @@ -75,23 +203,28 @@ hsaKmtCreateQueue( struct queue *q = malloc(sizeof(struct queue)); if (q == NULL) - { return HSAKMT_STATUS_NO_MEMORY; - } - memset(q, 0, sizeof(*q)); struct kfd_ioctl_create_queue_args args; memset(&args, 0, sizeof(args)); + dev_id = get_device_id_by_node(NodeId); + dev_info = get_device_info_by_dev_id(dev_id); args.gpu_id = gpu_id; + err = handle_concrete_asic(dev_info, q, &args); + if (err != HSAKMT_STATUS_SUCCESS) { + free_queue(q); + return err; + } + switch (Type) { case HSA_QUEUE_COMPUTE: args.queue_type = KFD_IOC_QUEUE_TYPE_COMPUTE; break; case HSA_QUEUE_SDMA: free(q); return HSAKMT_STATUS_NOT_IMPLEMENTED; case HSA_QUEUE_COMPUTE_AQL: args.queue_type = KFD_IOC_QUEUE_TYPE_COMPUTE_AQL; break; - default: free(q); return HSAKMT_STATUS_INVALID_PARAMETER; + default: free_queue(q); return HSAKMT_STATUS_INVALID_PARAMETER; } if (Type != HSA_QUEUE_COMPUTE_AQL) @@ -111,7 +244,7 @@ hsaKmtCreateQueue( if (err == -1) { - free(q); + free_queue(q); return HSAKMT_STATUS_ERROR; } @@ -126,6 +259,7 @@ hsaKmtCreateQueue( if (ptr == MAP_FAILED) { pthread_mutex_unlock(&doorbells[NodeId].doorbells_mutex); hsaKmtDestroyQueue(q->queue_id); + free_queue(q); return HSAKMT_STATUS_ERROR; } @@ -201,7 +335,7 @@ hsaKmtDestroyQueue( } else { - free(q); + free_queue(q); return HSAKMT_STATUS_SUCCESS; } } |