From b793811ef6689cb701b0146196f47588c68f8bf0 Mon Sep 17 00:00:00 2001 From: Jason Tang Date: Sun, 20 Jun 2021 14:24:24 -0400 Subject: [PATCH] SWDEV-287088 - Workaround VM page fault on Windows Some chunk memory are not guaranteed to be resident during initial allocation. Use CPDMA to force resident. Change-Id: If1a2da3e75f136caaa4c7a29d8f604d6af2639fa --- rocclr/device/pal/palresource.cpp | 24 ++++++++++++++++++++++++ rocclr/device/pal/palresource.hpp | 1 + 2 files changed, 25 insertions(+) diff --git a/rocclr/device/pal/palresource.cpp b/rocclr/device/pal/palresource.cpp index 2950e8a01f..99e8d1c344 100644 --- a/rocclr/device/pal/palresource.cpp +++ b/rocclr/device/pal/palresource.cpp @@ -1929,6 +1929,22 @@ bool MemorySubAllocator::InitAllocator(GpuMemoryReference* mem_ref) { return true; } +// ================================================================================================ +void MemorySubAllocator::forceResident(GpuMemoryReference* mem_ref) { + if (IS_WINDOWS) { + // Write one DWORD using CPDMA to force resident + GpuEvent event; + auto gpu = device_->xferQueue(); + uint32_t data = 0; + + gpu->eventBegin(MainEngine); + gpu->queue(MainEngine).addCmdMemRef(mem_ref); + gpu->iCmd()->CmdUpdateMemory(*mem_ref->iMem(), 0, 4, &data); + gpu->eventEnd(MainEngine, event); + gpu->waitForEvent(&event); + } +} + // ================================================================================================ bool MemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved_va) { Pal::GpuMemoryCreateInfo createInfo = {}; @@ -1944,6 +1960,8 @@ bool MemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved_va) { createInfo.mallPolicy = static_cast(device_->settings().mallPolicy_); GpuMemoryReference* mem_ref = GpuMemoryReference::Create(*device_, createInfo); if (mem_ref != nullptr) { + // Workaround: some chunk memory are not guaranteed to be resident during initial allocation. + forceResident(mem_ref); return InitAllocator(mem_ref); } return false; @@ -1964,6 +1982,8 @@ bool CoarseMemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved_va) { createInfo.mallPolicy = static_cast(device_->settings().mallPolicy_); GpuMemoryReference* mem_ref = GpuMemoryReference::Create(*device_, createInfo); if (mem_ref != nullptr) { + // Workaround: some chunk memory are not guaranteed to be resident during initial allocation. + forceResident(mem_ref); return InitAllocator(mem_ref); } return false; @@ -1980,6 +2000,8 @@ bool FineMemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved_va) { createInfo.mallPolicy = Pal::GpuMemMallPolicy::Never; GpuMemoryReference* mem_ref = GpuMemoryReference::Create(*device_, createInfo); if ((mem_ref != nullptr) && InitAllocator(mem_ref)) { + // Workaround: some chunk memory are not guaranteed to be resident during initial allocation. + forceResident(mem_ref); mem_ref->iMem()->Map(&mem_ref->cpuAddress_); return mem_ref->cpuAddress_ != nullptr; } @@ -1998,6 +2020,8 @@ bool FineUncachedMemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved createInfo.mallPolicy = Pal::GpuMemMallPolicy::Never; GpuMemoryReference* mem_ref = GpuMemoryReference::Create(*device_, createInfo); if ((mem_ref != nullptr) && InitAllocator(mem_ref)) { + // Workaround: some chunk memory are not guaranteed to be resident during initial allocation. + forceResident(mem_ref); mem_ref->iMem()->Map(&mem_ref->cpuAddress_); return mem_ref->cpuAddress_ != nullptr; } diff --git a/rocclr/device/pal/palresource.hpp b/rocclr/device/pal/palresource.hpp index ec11a1a24b..bf3cf0196b 100644 --- a/rocclr/device/pal/palresource.hpp +++ b/rocclr/device/pal/palresource.hpp @@ -528,6 +528,7 @@ class MemorySubAllocator : public amd::HeapObject { //! Allocate new chunk of memory virtual bool CreateChunk(const Pal::IGpuMemory* reserved_va); bool InitAllocator(GpuMemoryReference* mem_ref); + void forceResident(GpuMemoryReference* mem_ref); Device* device_; std::unordered_map heaps_;