From 48442e18e9e0ad0b5a9e8bea75944719c6382079 Mon Sep 17 00:00:00 2001 From: Luke Drummond Date: Mon, 2 Oct 2023 15:19:30 +0100 Subject: [PATCH] [rocm] Fix segfault with -O0-compiled kernels `kernels_[blitType]` yields a null function pointer in `KernelBlitManager::initHeap` due to `KernelBlitManager::createProgram` not initializing all the kernels because of broken layout invariants. `KernBlitManager::NumBlitKernels` has two possible return values: `BlitTotal, and BlitLinearTotal` which are sentinels. These sentinels are used in `KernelBlitManager::createProgram` to initialize the `kernels_` array. It correctly initializes `[0, NumBlitKernels())`, but `InitHeap` is > `NumBlitKernels`, so the `InitHeap` kernel is not loaded. Thus, when images are disabled, and a kernel has an `hidden_heap_v1` entry, the `InitHeap` blitkernel is not loaded, and `kernelBlitManager::initHeap` subsequently gets a null pointer. The kernel always has such `hidden_heap_v1` descriptor entry at -O0, but I believe it's possible (unconfirmed) for this situation to occur in other circumstances. The fix is simply to ensure the `InitHeap` enumeration has a numeric value *less than* `BlitLinearTotal`. n.b. This bug does not exist on the 5.7 release, but it looks like that's by chance. --- device/devhcprintf.cpp | 1 + device/rocm/rocblit.hpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/device/devhcprintf.cpp b/device/devhcprintf.cpp index b36f7758..38c323e0 100644 --- a/device/devhcprintf.cpp +++ b/device/devhcprintf.cpp @@ -26,6 +26,7 @@ #include #include #include +#include static void checkPrintf(FILE* stream, int* outCount, const char* fmt, ...) { va_list args; diff --git a/device/rocm/rocblit.hpp b/device/rocm/rocblit.hpp index 8360e6b1..061f6391 100644 --- a/device/rocm/rocblit.hpp +++ b/device/rocm/rocblit.hpp @@ -290,13 +290,13 @@ class KernelBlitManager : public DmaBlitManager { StreamOpsWait, Scheduler, GwsInit, + InitHeap, BlitLinearTotal, FillImage = BlitLinearTotal, BlitCopyImage, BlitCopyImage1DA, BlitCopyImageToBuffer, BlitCopyBufferToImage, - InitHeap, BlitTotal }; @@ -595,9 +595,9 @@ static const char* BlitName[KernelBlitManager::BlitTotal] = { "__amd_rocclr_fillBufferAligned", "__amd_rocclr_fillBufferAligned2D", "__amd_rocclr_copyBuffer", "__amd_rocclr_copyBufferAligned", "__amd_rocclr_copyBufferRect", "__amd_rocclr_copyBufferRectAligned", "__amd_rocclr_streamOpsWrite", "__amd_rocclr_streamOpsWait", - "__amd_rocclr_scheduler", "__amd_rocclr_gwsInit", "__amd_rocclr_fillImage", + "__amd_rocclr_scheduler", "__amd_rocclr_gwsInit", "__amd_rocclr_initHeap", "__amd_rocclr_fillImage", "__amd_rocclr_copyImage", "__amd_rocclr_copyImage1DA", "__amd_rocclr_copyImageToBuffer", - "__amd_rocclr_copyBufferToImage", "__amd_rocclr_initHeap" + "__amd_rocclr_copyBufferToImage" }; inline void KernelBlitManager::setArgument(amd::Kernel* kernel, size_t index,