Workaround gfx90a SDMA0 quirk.

Because of sharing ports with other engines, the
hardware design team has advised that SDMA0 on gfx90a
should only be used for host-to-device data transfers.
The recommendation is to use SDMA1 for any device-to-device
or device-to-host data transfers.

A driver change will ensure that, for each gfx90a
device, only the first PCIe SDMA queue a process
requests will possibly be from SDMA0. This patch ensures
that the first PCIe queue requested (which may be from
SDMA0) is always set up for host-to-device.

Change-Id: I6793ca95596dedaed9d5be1dbd9469ceef2a5c33
This commit is contained in:
Sean Keely
2021-08-20 00:56:04 -05:00
والد e0224ad89f
کامیت 280a458d0c
@@ -599,7 +599,7 @@ void GpuAgent::InitDma() {
queues_[QueueUtility].reset(queue_lambda);
// Decide which engine to use for blits.
auto blit_lambda = [this](bool use_xgmi, lazy_ptr<core::Queue>& queue) {
auto blit_lambda = [this](bool use_xgmi, lazy_ptr<core::Queue>& queue, bool isHostToDev) {
Flag::SDMA_OVERRIDE sdma_override = core::Runtime::runtime_singleton_->flag().enable_sdma();
// User SDMA queues are unstable on gfx8 and unsupported on gfx1013.
@@ -608,6 +608,12 @@ void GpuAgent::InitDma() {
if (sdma_override != Flag::SDMA_DEFAULT) use_sdma = (sdma_override == Flag::SDMA_ENABLE);
if (use_sdma && (HSA_PROFILE_BASE == profile_)) {
// On gfx90a ensure that HostToDevice queue is created first and so is placed on SDMA0.
if ((!use_xgmi) && (!isHostToDev) && (isa_->GetMajorVersion() == 9) &&
(isa_->GetMinorVersion() == 0) && (isa_->GetStepping() == 10)) {
*blits_[BlitHostToDev];
}
auto ret = CreateBlitSdma(use_xgmi);
if (ret != nullptr) return ret;
}
@@ -643,13 +649,14 @@ void GpuAgent::InitDma() {
return ret;
});
blits_[BlitHostToDev].reset(
[blit_lambda, this]() { return blit_lambda(false, queues_[QueueBlitOnly]); });
[blit_lambda, this]() { return blit_lambda(false, queues_[QueueBlitOnly], true); });
blits_[BlitDevToHost].reset(
[blit_lambda, this]() { return blit_lambda(false, queues_[QueueUtility]); });
[blit_lambda, this]() { return blit_lambda(false, queues_[QueueUtility], false); });
// XGMI engines.
for (uint32_t idx = DefaultBlitCount; idx < blit_cnt_; idx++) {
blits_[idx].reset([blit_lambda, this]() { return blit_lambda(true, queues_[QueueUtility]); });
blits_[idx].reset(
[blit_lambda, this]() { return blit_lambda(true, queues_[QueueUtility], false); });
}
// GWS queues.