diff --git a/projects/clr/rocclr/device/rocm/rocblit.cpp b/projects/clr/rocclr/device/rocm/rocblit.cpp index 35fad4d650..1b7b627d78 100644 --- a/projects/clr/rocclr/device/rocm/rocblit.cpp +++ b/projects/clr/rocclr/device/rocm/rocblit.cpp @@ -748,9 +748,11 @@ bool DmaBlitManager::hsaCopyStagedOrPinned(const_address hostSrc, address hostDs firstTx = false; } - // @note: HIP requires a blocking wait on D2H with the pageable system memory - if (amd::IS_HIP && !hostToDev) { + // @note: HIP requires to unpin all memory after operation, due to an optimization with + // direct HSA signal check HIP avoids the command completion wait + if (amd::IS_HIP && (gpu().command() != nullptr) && gpu().command()->IsMemoryPinned()) { gpu().Barriers().WaitCurrent(); + gpu().command()->ReleasePinnedMemory(); } if (!status) { diff --git a/projects/clr/rocclr/platform/command.hpp b/projects/clr/rocclr/platform/command.hpp index 31374d71ad..6070f94548 100644 --- a/projects/clr/rocclr/platform/command.hpp +++ b/projects/clr/rocclr/platform/command.hpp @@ -388,6 +388,12 @@ class Command : public Event { //! Release the resources associated with this event. virtual void releaseResources(); + //! Empty function for pinned memory check + virtual bool IsMemoryPinned() const { return false; } + + //! Empty function for release of pinned memory + virtual void ReleasePinnedMemory() {} + //! Empty function for adding pinned memory virtual void AddPinnedMemory(Memory* pinned) {} @@ -500,10 +506,18 @@ class OneMemoryArgCommand : public Command { memory_->release(); DEBUG_ONLY(memory_ = NULL); Command::releaseResources(); + ReleasePinnedMemory(); + } + + //! Release all pinned memory for this command + virtual void ReleasePinnedMemory() { for (auto it : pinned_memory_) { it->release(); } + pinned_memory_.clear(); } + //! Release all pinned memory for this command + virtual bool IsMemoryPinned() const { return !pinned_memory_.empty(); } //! Adds pinned memory, used in this command for later release virtual void AddPinnedMemory(Memory* pinned) override { pinned_memory_.push_back(pinned); }