Initialize HSA Queue object before creating KFD queue
Initialize all the fields in the HSA queue object to known values before calling the thunk to create the KFD queue. This ensures that when the debugger detects that a KFD queue is created it can access the values it requires. The values it requires include the apperture addresses, queue scratch memory base, and the HSA queue kind. Change-Id: Ic985755b0402c6794d5987e60aff50d223f09eb9
Этот коммит содержится в:
@@ -151,31 +151,20 @@ AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id, Scr
|
||||
queue_rsrc.Queue_write_ptr_aql = (uint64_t*)&amd_queue_.max_legacy_doorbell_dispatch_id_plus_1;
|
||||
}
|
||||
|
||||
HSAKMT_STATUS kmt_status;
|
||||
kmt_status = hsaKmtCreateQueue(node_id, HSA_QUEUE_COMPUTE_AQL, 100, priority_, ring_buf_,
|
||||
ring_buf_alloc_bytes_, NULL, &queue_rsrc);
|
||||
if (kmt_status != HSAKMT_STATUS_SUCCESS)
|
||||
throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,
|
||||
"Queue create failed at hsaKmtCreateQueue\n");
|
||||
queue_id_ = queue_rsrc.QueueId;
|
||||
MAKE_NAMED_SCOPE_GUARD(QueueGuard, [&]() { hsaKmtDestroyQueue(queue_id_); });
|
||||
|
||||
// Populate doorbell signal structure.
|
||||
memset(&signal_, 0, sizeof(signal_));
|
||||
signal_.kind = (doorbell_type_ == 2) ? AMD_SIGNAL_KIND_DOORBELL : AMD_SIGNAL_KIND_LEGACY_DOORBELL;
|
||||
signal_.legacy_hardware_doorbell_ptr =
|
||||
(volatile uint32_t*)queue_rsrc.Queue_DoorBell;
|
||||
signal_.queue_ptr = &amd_queue_;
|
||||
|
||||
// Populate amd_queue_ structure.
|
||||
amd_queue_.hsa_queue.type = HSA_QUEUE_TYPE_MULTI;
|
||||
amd_queue_.hsa_queue.features = HSA_QUEUE_FEATURE_KERNEL_DISPATCH;
|
||||
amd_queue_.hsa_queue.base_address = ring_buf_;
|
||||
amd_queue_.hsa_queue.doorbell_signal = Signal::Convert(this);
|
||||
amd_queue_.hsa_queue.size = queue_size_pkts;
|
||||
amd_queue_.hsa_queue.id = queue_id_;
|
||||
amd_queue_.hsa_queue.id = INVALID_QUEUEID;
|
||||
amd_queue_.read_dispatch_id_field_base_byte_offset = uint32_t(
|
||||
uintptr_t(&amd_queue_.read_dispatch_id) - uintptr_t(&amd_queue_));
|
||||
// Initialize the doorbell signal structure.
|
||||
memset(&signal_, 0, sizeof(signal_));
|
||||
signal_.kind = (doorbell_type_ == 2) ? AMD_SIGNAL_KIND_DOORBELL : AMD_SIGNAL_KIND_LEGACY_DOORBELL;
|
||||
signal_.legacy_hardware_doorbell_ptr = nullptr;
|
||||
signal_.queue_ptr = &amd_queue_;
|
||||
|
||||
const auto& props = agent->properties();
|
||||
amd_queue_.max_cu_id = (props.NumFComputeCores / props.NumSIMDPerCU) - 1;
|
||||
@@ -221,6 +210,25 @@ AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id, Scr
|
||||
assert(amd_queue_.private_segment_aperture_base_hi != 0 && "No private region found.");
|
||||
}
|
||||
|
||||
// Ensure the amd_queue_ is fully initialized before creating the KFD queue.
|
||||
// This ensures that the debugger can access the fields once it detects there
|
||||
// is a KFD queue. The debugger may access the aperture addresses, queue
|
||||
// scratch base, and queue type.
|
||||
|
||||
HSAKMT_STATUS kmt_status;
|
||||
kmt_status = hsaKmtCreateQueue(node_id, HSA_QUEUE_COMPUTE_AQL, 100, priority_, ring_buf_,
|
||||
ring_buf_alloc_bytes_, NULL, &queue_rsrc);
|
||||
if (kmt_status != HSAKMT_STATUS_SUCCESS)
|
||||
throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,
|
||||
"Queue create failed at hsaKmtCreateQueue\n");
|
||||
// Complete populating the doorbell signal structure.
|
||||
signal_.legacy_hardware_doorbell_ptr =
|
||||
(volatile uint32_t*)queue_rsrc.Queue_DoorBell;
|
||||
// Complete populating the amd_queue_ structure.
|
||||
amd_queue_.hsa_queue.id = queue_id_ = queue_rsrc.QueueId;
|
||||
|
||||
MAKE_NAMED_SCOPE_GUARD(QueueGuard, [&]() { hsaKmtDestroyQueue(queue_id_); });
|
||||
|
||||
MAKE_NAMED_SCOPE_GUARD(EventGuard, [&]() {
|
||||
ScopedAcquire<KernelMutex> _lock(&queue_lock_);
|
||||
queue_count_--;
|
||||
|
||||
Ссылка в новой задаче
Block a user