Implement hsaKmtGetQueueInfo interface

For items in HsaQueueInfo, control stack information comes from KFD, CU
mask information is maintained in Thunk, and others (queue detail error
and queue type extended) are ignored (value = 0) at this point.

Change-Id: Ib21370b0f52b2bb4ebe6a9b4b6ec6139cccb25ca
Signed-off-by: Amber Lin <Amber.Lin@amd.com>


[ROCm/ROCR-Runtime commit: 683fc96325]
This commit is contained in:
Amber Lin
2017-05-25 14:51:30 -04:00
parent c53049ce46
commit dd782c86c0
6 changed files with 131 additions and 3 deletions
+1
View File
@@ -59,6 +59,7 @@ extern int PAGE_SHIFT;
do { if ((uint64_t)PORT_VPTR_TO_UINT64(x) % PAGE_SIZE) return HSAKMT_STATUS_INVALID_PARAMETER; } while(0)
#define ALIGN_UP(x,align) (((uint64_t)(x) + (align) - 1) & ~(uint64_t)((align)-1))
#define ALIGN_UP_32(x,align) (((uint32_t)(x) + (align) - 1) & ~(uint32_t)((align)-1))
#define PAGE_ALIGN_UP(x) ALIGN_UP(x,PAGE_SIZE)
#define BITMASK(n) (((n) < sizeof(1ULL) * CHAR_BIT ? (1ULL << (n)) : 0) - 1ULL)
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
+1
View File
@@ -55,6 +55,7 @@ hsaKmtSetTrapHandler;
hsaKmtGetTileConfig;
hsaKmtQueryPointerInfo;
hsaKmtSetMemoryUserData;
hsaKmtGetQueueInfo;
local: *;
};
+90 -1
View File
@@ -122,7 +122,14 @@ struct queue {
void *ctx_save_restore;
uint32_t ctx_save_restore_size;
uint32_t ctl_stack_size;
void *ctl_stack_copy;
const struct device_info *dev_info;
/* This queue structure is allocated from GPU with page aligned size
* but only small bytes are used. We use the extra space in the end for
* cu_mask bits array.
*/
uint32_t cu_mask_count; /* in bits */
uint32_t cu_mask[0];
};
struct process_doorbells {
@@ -416,6 +423,11 @@ static void free_queue(struct queue *q)
free_exec_aligned_memory(q->ctx_save_restore,
q->ctx_save_restore_size,
PAGE_SIZE, q->dev_info->asic_family);
if (q->ctl_stack_copy)
free_exec_aligned_memory(q->ctl_stack_copy,
q->ctl_stack_size,
PAGE_SIZE, q->dev_info->asic_family);
free_exec_aligned_memory((void *)q, sizeof(*q), PAGE_SIZE, q->dev_info->asic_family);
}
@@ -451,6 +463,11 @@ static int handle_concrete_asic(struct queue *q,
return HSAKMT_STATUS_NO_MEMORY;
args->ctx_save_restore_address = (uintptr_t)q->ctx_save_restore;
if (IS_SOC15(q->dev_info->asic_family)) {
q->ctl_stack_copy = malloc(q->ctl_stack_size);
if (q->ctl_stack_copy == NULL)
return HSAKMT_STATUS_NO_MEMORY;
}
}
}
@@ -479,6 +496,8 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtCreateQueue(HSAuint32 NodeId,
unsigned int doorbell_offset;
struct device_info *dev_info;
int err;
HsaNodeProperties props;
uint32_t cu_num, i;
CHECK_KFD_OPEN();
@@ -501,6 +520,19 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtCreateQueue(HSAuint32 NodeId,
memset(q, 0, sizeof(*q));
/* By default, CUs are all turned on. Initialize cu_mask to '1
* for all CU bits.
*/
if (hsaKmtGetNodeProperties(NodeId, &props))
q->cu_mask_count = 0;
else {
cu_num = props.NumFComputeCores / props.NumSIMDPerCU;
/* cu_mask_count counts bits. It must be multiple of 32 */
q->cu_mask_count = ALIGN_UP_32(cu_num, 32);
for (i = 0; i < cu_num; i++)
q->cu_mask[i/32] |= (1 << (i % 32));
}
struct kfd_ioctl_create_queue_args args;
memset(&args, 0, sizeof(args));
@@ -534,7 +566,6 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtCreateQueue(HSAuint32 NodeId,
return err;
}
args.read_pointer_address = QueueResource->QueueRptrValue;
args.write_pointer_address = QueueResource->QueueWptrValue;
args.ring_base_address = (uintptr_t)QueueAddress;
@@ -662,6 +693,64 @@ HSAKMT_STATUS HSAKMTAPI hsaKmtSetQueueCUMask(HSA_QUEUEID QueueId,
if (err == -1)
return HSAKMT_STATUS_ERROR;
memcpy(q->cu_mask, QueueCUMask, CUMaskCount / 8);
q->cu_mask_count = CUMaskCount;
return HSAKMT_STATUS_SUCCESS;
}
HSAKMT_STATUS
HSAKMTAPI
hsaKmtGetQueueInfo(
HSA_QUEUEID QueueId,
HsaQueueInfo *QueueInfo
)
{
struct queue *q = PORT_UINT64_TO_VPTR(QueueId);
struct kfd_ioctl_get_queue_wave_state_args args;
uintptr_t ctl_stack_base_addr = 0;
CHECK_KFD_OPEN();
if (QueueInfo == NULL || q == NULL)
return HSAKMT_STATUS_INVALID_PARAMETER;
if (q->ctx_save_restore == NULL)
return HSAKMT_STATUS_ERROR;
memset(&args, 0, sizeof(args));
args.queue_id = q->queue_id;
if (IS_SOC15(q->dev_info->asic_family)) {
/* From SOC15 onwards the control stack is kept in the MQD.
* The save area is at the beginning of the allocated space.
* Request a copy of the control stack from the KFD.
*/
ctl_stack_base_addr = (uintptr_t)q->ctl_stack_copy;
QueueInfo->UserContextSaveArea = q->ctx_save_restore;
args.ctl_stack_address = ctl_stack_base_addr;
} else {
/* Before SOC15 the control stack is already in userspace.
* The save area immediately follows the control stack.
*/
ctl_stack_base_addr = (uintptr_t)q->ctx_save_restore;
QueueInfo->UserContextSaveArea = (void *)
((uintptr_t)q->ctx_save_restore + q->ctl_stack_size);
args.ctl_stack_address = 0;
}
if (kmtIoctl(kfd_fd, AMDKFD_IOC_GET_QUEUE_WAVE_STATE, &args) < 0)
return HSAKMT_STATUS_ERROR;
QueueInfo->ControlStackTop = (void *)(ctl_stack_base_addr +
q->ctl_stack_size - args.ctl_stack_used_size);
QueueInfo->SaveAreaSizeInBytes = args.save_area_used_size;
QueueInfo->ControlStackUsedInBytes = args.ctl_stack_used_size;
QueueInfo->NumCUAssigned = q->cu_mask_count;
QueueInfo->CUMaskInfo = q->cu_mask;
QueueInfo->QueueDetailError = 0;
QueueInfo->QueueTypeExtended = 0;
return HSAKMT_STATUS_SUCCESS;
}