Add queues module
Signed-off-by: Ben Goz <ben.goz@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@amd.com>
[ROCm/ROCR-Runtime commit: 678287d98b]
This commit is contained in:
@@ -67,6 +67,7 @@ uint16_t get_device_id_by_node(HSAuint32 node_id);
|
|||||||
extern int kfd_ioctl(int cmdcode, void* data);
|
extern int kfd_ioctl(int cmdcode, void* data);
|
||||||
|
|
||||||
/* Void pointer arithmetic (or remove -Wpointer-arith to allow void pointers arithmetic) */
|
/* Void pointer arithmetic (or remove -Wpointer-arith to allow void pointers arithmetic) */
|
||||||
|
#define VOID_PTR_ADD32(ptr,n) (void*)((uint32_t*)(ptr) + n)/*ptr + offset*/
|
||||||
#define VOID_PTR_ADD(ptr,n) (void*)((uint8_t*)(ptr) + n)/*ptr + offset*/
|
#define VOID_PTR_ADD(ptr,n) (void*)((uint8_t*)(ptr) + n)/*ptr + offset*/
|
||||||
#define VOID_PTR_SUB(ptr,n) (void*)((uint8_t*)(ptr) - n)/*ptr - offset*/
|
#define VOID_PTR_SUB(ptr,n) (void*)((uint8_t*)(ptr) - n)/*ptr - offset*/
|
||||||
#define VOID_PTRS_SUB(ptr1,ptr2) (uint64_t)((uint8_t*)(ptr1) - (uint8_t*)(ptr2)) /*ptr1 - ptr2*/
|
#define VOID_PTRS_SUB(ptr1,ptr2) (uint64_t)((uint8_t*)(ptr1) - (uint8_t*)(ptr2)) /*ptr1 - ptr2*/
|
||||||
|
|||||||
@@ -27,6 +27,28 @@
|
|||||||
#include "linux/kfd_ioctl.h"
|
#include "linux/kfd_ioctl.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* 1024 doorbells, 4 bytes each doorbell */
|
||||||
|
#define DOORBELLS_PAGE_SIZE 1024 * 4
|
||||||
|
|
||||||
|
struct queue
|
||||||
|
{
|
||||||
|
uint32_t queue_id;
|
||||||
|
uint32_t wptr;
|
||||||
|
uint32_t rptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct process_doorbells
|
||||||
|
{
|
||||||
|
bool need_mmap;
|
||||||
|
void* doorbells;
|
||||||
|
pthread_mutex_t doorbells_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct process_doorbells doorbells[] = {[0 ... (NUM_OF_SUPPORTED_GPUS-1)] = {.need_mmap = true, .doorbells = NULL, .doorbells_mutex = PTHREAD_MUTEX_INITIALIZER}};
|
||||||
|
|
||||||
HSAKMT_STATUS
|
HSAKMT_STATUS
|
||||||
HSAKMTAPI
|
HSAKMTAPI
|
||||||
@@ -41,9 +63,82 @@ hsaKmtCreateQueue(
|
|||||||
HsaQueueResource* QueueResource //OUT
|
HsaQueueResource* QueueResource //OUT
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
HSAKMT_STATUS result;
|
||||||
|
uint32_t gpu_id;
|
||||||
|
int err;
|
||||||
|
void* ptr;
|
||||||
CHECK_KFD_OPEN();
|
CHECK_KFD_OPEN();
|
||||||
|
|
||||||
return HSAKMT_STATUS_NOT_SUPPORTED;
|
result = validate_nodeid(NodeId, &gpu_id);
|
||||||
|
if (result != HSAKMT_STATUS_SUCCESS)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
args.gpu_id = gpu_id;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type != HSA_QUEUE_COMPUTE_AQL)
|
||||||
|
{
|
||||||
|
QueueResource->QueueRptrValue = (uintptr_t)&q->rptr;
|
||||||
|
QueueResource->QueueWptrValue = (uintptr_t)&q->wptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.read_pointer_address = QueueResource->QueueRptrValue;
|
||||||
|
args.write_pointer_address = QueueResource->QueueWptrValue;
|
||||||
|
args.ring_base_address = (uintptr_t)QueueAddress;
|
||||||
|
args.ring_size = QueueSizeInBytes;
|
||||||
|
args.queue_percentage = QueuePercentage;
|
||||||
|
args.queue_priority = Priority;
|
||||||
|
|
||||||
|
err = kfd_ioctl(KFD_IOC_CREATE_QUEUE, &args);
|
||||||
|
|
||||||
|
if (err == -1)
|
||||||
|
{
|
||||||
|
free(q);
|
||||||
|
return HSAKMT_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->queue_id = args.queue_id;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&doorbells[NodeId].doorbells_mutex);
|
||||||
|
|
||||||
|
if (doorbells[NodeId].need_mmap) {
|
||||||
|
ptr = mmap(0, DOORBELLS_PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED, kfd_fd, args.doorbell_offset);
|
||||||
|
|
||||||
|
if (ptr == MAP_FAILED) {
|
||||||
|
pthread_mutex_unlock(&doorbells[NodeId].doorbells_mutex);
|
||||||
|
hsaKmtDestroyQueue(q->queue_id);
|
||||||
|
return HSAKMT_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
doorbells[NodeId].need_mmap = false;
|
||||||
|
doorbells[NodeId].doorbells = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&doorbells[NodeId].doorbells_mutex);
|
||||||
|
|
||||||
|
QueueResource->QueueId = PORT_VPTR_TO_UINT64(q);
|
||||||
|
QueueResource->Queue_DoorBell = VOID_PTR_ADD32(doorbells[NodeId].doorbells, q->queue_id);
|
||||||
|
|
||||||
|
return HSAKMT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,9 +153,26 @@ hsaKmtUpdateQueue(
|
|||||||
HsaEvent* Event //IN
|
HsaEvent* Event //IN
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
struct kfd_ioctl_update_queue_args arg;
|
||||||
|
struct queue *q = PORT_UINT64_TO_VPTR(QueueId);
|
||||||
|
|
||||||
CHECK_KFD_OPEN();
|
CHECK_KFD_OPEN();
|
||||||
|
|
||||||
return HSAKMT_STATUS_NOT_SUPPORTED;
|
if (q == NULL)
|
||||||
|
return (HSAKMT_STATUS_INVALID_PARAMETER);
|
||||||
|
arg.queue_id = (HSAuint32)q->queue_id;
|
||||||
|
arg.ring_base_address = (uintptr_t)QueueAddress;
|
||||||
|
arg.ring_size = QueueSize;
|
||||||
|
arg.queue_percentage = QueuePercentage;
|
||||||
|
arg.queue_priority = Priority;
|
||||||
|
|
||||||
|
int err = kfd_ioctl(KFD_IOC_UPDATE_QUEUE, &arg);
|
||||||
|
if (err == -1)
|
||||||
|
{
|
||||||
|
return HSAKMT_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HSAKMT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
HSAKMT_STATUS
|
HSAKMT_STATUS
|
||||||
@@ -71,5 +183,25 @@ hsaKmtDestroyQueue(
|
|||||||
{
|
{
|
||||||
CHECK_KFD_OPEN();
|
CHECK_KFD_OPEN();
|
||||||
|
|
||||||
return HSAKMT_STATUS_NOT_SUPPORTED;
|
struct queue *q = PORT_UINT64_TO_VPTR(QueueId);
|
||||||
|
struct kfd_ioctl_destroy_queue_args args;
|
||||||
|
|
||||||
|
if (q == NULL)
|
||||||
|
return (HSAKMT_STATUS_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
memset(&args, 0, sizeof(args));
|
||||||
|
|
||||||
|
args.queue_id = q->queue_id;
|
||||||
|
|
||||||
|
int err = kfd_ioctl(KFD_IOC_DESTROY_QUEUE, &args);
|
||||||
|
|
||||||
|
if (err == -1)
|
||||||
|
{
|
||||||
|
return HSAKMT_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(q);
|
||||||
|
return HSAKMT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user