From 432329c8530a100400d6670f660f3e35bf2ff735 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Thu, 25 Aug 2022 15:55:16 -0700 Subject: [PATCH] dev-amdgpu: Allow device address source for SDMA COPY Now that the memory manager can DMA read from device memory, allow the linear copy SDMA packet to use device memory as a source. This is used when copying memory from device to host when SDMA engines are enabled. This improves simulation performance over using (simulated) BLIT kernels with SDMA engines disabled. Change-Id: I1f41b294022f0049d154a401c1dc885abb4f223b Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/62713 Maintainer: Jason Lowe-Power Reviewed-by: Matt Sinclair Maintainer: Matt Sinclair Reviewed-by: Jason Lowe-Power Tested-by: kokoro --- src/dev/amdgpu/sdma_engine.cc | 36 +++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/dev/amdgpu/sdma_engine.cc b/src/dev/amdgpu/sdma_engine.cc index df08e32289..d71fb09579 100644 --- a/src/dev/amdgpu/sdma_engine.cc +++ b/src/dev/amdgpu/sdma_engine.cc @@ -535,11 +535,35 @@ SDMAEngine::copy(SDMAQueue *q, sdmaCopy *pkt) pkt->source = getGARTAddr(pkt->source); DPRINTF(SDMAEngine, "GART addr %lx\n", pkt->source); - // first we have to read needed data from the source address - uint8_t *dmaBuffer = new uint8_t[pkt->count]; - auto cb = new DmaVirtCallback( - [ = ] (const uint64_t &) { copyReadData(q, pkt, dmaBuffer); }); - dmaReadVirt(pkt->source, pkt->count, cb, (void *)dmaBuffer); + // Check if the source is MMHUB. If it is we need to use the GpuMemMgr + // to read memory and not dmaReadVirt. + auto tgen = translate(pkt->source, 64); + auto addr_range = *(tgen->begin()); + Addr tmp_addr = addr_range.paddr; + DPRINTF(SDMAEngine, "Tmp addr %#lx -> %#lx\n", pkt->source, tmp_addr); + + if ((gpuDevice->getVM().inMMHUB(pkt->source) && cur_vmid == 0) || + (gpuDevice->getVM().inMMHUB(tmp_addr) && cur_vmid != 0)) { + Addr mmhubAddr = 0; + if (cur_vmid == 0) { + mmhubAddr = pkt->source - gpuDevice->getVM().getMMHUBBase(); + } else { + mmhubAddr = tmp_addr - gpuDevice->getVM().getMMHUBBase(); + } + + uint8_t *dmaBuffer = new uint8_t[pkt->count]; + DPRINTF(SDMAEngine, "Copying from device address %#lx\n", mmhubAddr); + auto cb = new EventFunctionWrapper( + [ = ]{ copyReadData(q, pkt, dmaBuffer); }, name()); + gpuDevice->getMemMgr()->readRequest(mmhubAddr, dmaBuffer, pkt->count, + 0, cb); + } else { + // first we have to read needed data from the source address + uint8_t *dmaBuffer = new uint8_t[pkt->count]; + auto cb = new DmaVirtCallback( + [ = ] (const uint64_t &) { copyReadData(q, pkt, dmaBuffer); }); + dmaReadVirt(pkt->source, pkt->count, cb, (void *)dmaBuffer); + } } /* Completion of data reading for a copy packet. */ @@ -570,7 +594,7 @@ SDMAEngine::copyReadData(SDMAQueue *q, sdmaCopy *pkt, uint8_t *dmaBuffer) } else { mmhubAddr = tmp_addr - gpuDevice->getVM().getMMHUBBase(); } - DPRINTF(SDMAEngine, "Copying to MMHUB address %#lx\n", mmhubAddr); + DPRINTF(SDMAEngine, "Copying to device address %#lx\n", mmhubAddr); gpuDevice->getMemMgr()->writeRequest(mmhubAddr, dmaBuffer, pkt->count); delete pkt;