wsl/hsakmt: Add no pcie atomic support for dispatch packet
This patch adds no pcie atomic support. This patch uses cpu to update cmd queue completion signal to resolve potential contention issue, and replaces ATOMIC_MEM with WRITE_DATA packet to update ring_index. Signed-off-by: Shane Xiao <shane.xiao@amd.com> Reviewed-by: Aaron Liu <aaron.liu@amd.com> Reviewed-by: Longlong Yao <Longlong.Yao@amd.com> Reviewed-by: Flora Cui <flora.cui@amd.com> Part-of: <http://10.67.69.192/wsl/libhsakmt/-/merge_requests/22>
Cette révision appartient à :
+29
-4
@@ -251,6 +251,8 @@ ComputeQueue::ComputeQueue(WDDMDevice *device,
|
||||
cmdbuf_aql_frame_size(0),
|
||||
needs_barrier(true),
|
||||
ready_to_submit(false),
|
||||
platform_atomic_support_(false),
|
||||
signal_addr_(NULL),
|
||||
thread_stop_(false),
|
||||
scratch_waves_(device->MaxScratchSlotsPerCu() * device->ComputeUnitCount()),
|
||||
scratch_size_per_wave_(0),
|
||||
@@ -548,6 +550,7 @@ hsa_status_t ComputeQueue::Init(void) {
|
||||
|
||||
ib_start_addr = cmdbuf_addr;
|
||||
cmdbuf_aql_frame_size = device->GetAqlFrameSize();
|
||||
platform_atomic_support_ = device->SupportPlatformAtomic();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -704,13 +707,19 @@ ComputeQueue::KernelDispatchAqlToPm4(char *cpu, hsa_kernel_dispatch_packet_t *pa
|
||||
uint64_t *signal_addr = (uint64_t *)&signal->value;
|
||||
debug_print("signal value=%" PRIx64 "\n", signal->value);
|
||||
|
||||
i += cmd_util.BuildAtomicMem(signal_addr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i, cache_policy__mec_atomic_mem__bypass, -1);
|
||||
if (platform_atomic_support_)
|
||||
i += cmd_util.BuildAtomicMem(signal_addr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i, cache_policy__mec_atomic_mem__bypass, -1);
|
||||
else
|
||||
signal_addr_ = signal_addr;
|
||||
}
|
||||
|
||||
// The ring_rptr is used to record pm4 queue rptr value,
|
||||
// dispatch readptr position, this is used to share rptr with
|
||||
// aql queue.
|
||||
i += cmd_util.BuildAtomicMem((uint64_t *)ring_rptr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i);
|
||||
if (platform_atomic_support_)
|
||||
i += cmd_util.BuildAtomicMem((uint64_t *)ring_rptr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i);
|
||||
else
|
||||
i += cmd_util.BuildWriteData64Command(cpu + i, (uint64_t *)ring_rptr, cmdbuf_aql_frame_write_index + 1);
|
||||
|
||||
ib_size = i;
|
||||
cmdbuf_aql_frame_write_index++;
|
||||
@@ -786,13 +795,19 @@ ComputeQueue::BarrierGenericAqlToPm4(char *cpu, hsa_barrier_and_packet_t *packet
|
||||
// flush cache
|
||||
i += cmd_util.BuildAcquireMem(major, cpu + i);
|
||||
|
||||
i += cmd_util.BuildAtomicMem(signal_addr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i, cache_policy__mec_atomic_mem__bypass, -1);
|
||||
if (platform_atomic_support_)
|
||||
i += cmd_util.BuildAtomicMem(signal_addr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i, cache_policy__mec_atomic_mem__bypass, -1);
|
||||
else
|
||||
signal_addr_ = signal_addr;
|
||||
}
|
||||
|
||||
// The ring_rptr is used to record pm4 queue rptr value,
|
||||
// dispatch readptr position, this is used to share rptr with
|
||||
// aql queue.
|
||||
i += cmd_util.BuildAtomicMem((uint64_t *)ring_rptr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i);
|
||||
if (platform_atomic_support_)
|
||||
i += cmd_util.BuildAtomicMem((uint64_t *)ring_rptr, TC_OP_ATOMIC_ADD_RTN_64, cpu + i);
|
||||
else
|
||||
i += cmd_util.BuildWriteData64Command(cpu + i, (uint64_t *)ring_rptr, cmdbuf_aql_frame_write_index + 1);
|
||||
|
||||
ib_size = i;
|
||||
cmdbuf_aql_frame_write_index++;
|
||||
@@ -944,6 +959,16 @@ hsa_status_t ComputeQueue::Process(void) {
|
||||
if (ret != HSA_STATUS_SUCCESS)
|
||||
return ret;
|
||||
|
||||
// CPU wait for GPU fence, and cpu update the signal.
|
||||
if (!platform_atomic_support_ && signal_addr_) {
|
||||
// CPU wait for GPU fence
|
||||
if (!device->CpuWait(&syncobj, &cmdbuf_aql_frame_write_index, 1, false))
|
||||
return HSA_STATUS_ERROR;
|
||||
//CPU update completional signal
|
||||
atomic::Decrement(signal_addr_);
|
||||
signal_addr_ = NULL;
|
||||
}
|
||||
|
||||
ready_to_submit = false;
|
||||
|
||||
debug_print("done %p wptr=%" PRIx64 " rptr=%" PRIx64 "\n",
|
||||
|
||||
Référencer dans un nouveau ticket
Bloquer un utilisateur