From c8986d1ecbcd50a00ecdb7887f7d43141de3196a Mon Sep 17 00:00:00 2001 From: Ross Brunton Date: Wed, 20 Aug 2025 13:23:57 +0100 Subject: [PATCH] [Offload] Guard olMemAlloc/Free with a mutex (#153786) Both these functions update an `AllocInfoMap` structure in the context, however they did not use any locks, causing random failures in threaded code. Now they use a mutex. --- offload/liboffload/src/OffloadImpl.cpp | 28 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index 54c6d452cbd9..8995b110d104 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -125,6 +125,7 @@ struct OffloadContext { bool TracingEnabled = false; bool ValidationEnabled = true; DenseMap AllocInfoMap{}; + std::mutex AllocInfoMapMutex{}; SmallVector Platforms{}; size_t RefCount; @@ -534,26 +535,33 @@ Error olMemAlloc_impl(ol_device_handle_t Device, ol_alloc_type_t Type, return Alloc.takeError(); *AllocationOut = *Alloc; - OffloadContext::get().AllocInfoMap.insert_or_assign(*Alloc, - AllocInfo{Device, Type}); + { + std::lock_guard Lock(OffloadContext::get().AllocInfoMapMutex); + OffloadContext::get().AllocInfoMap.insert_or_assign( + *Alloc, AllocInfo{Device, Type}); + } return Error::success(); } Error olMemFree_impl(void *Address) { - if (!OffloadContext::get().AllocInfoMap.contains(Address)) - return createOffloadError(ErrorCode::INVALID_ARGUMENT, - "address is not a known allocation"); + ol_device_handle_t Device; + ol_alloc_type_t Type; + { + std::lock_guard Lock(OffloadContext::get().AllocInfoMapMutex); + if (!OffloadContext::get().AllocInfoMap.contains(Address)) + return createOffloadError(ErrorCode::INVALID_ARGUMENT, + "address is not a known allocation"); - auto AllocInfo = OffloadContext::get().AllocInfoMap.at(Address); - auto Device = AllocInfo.Device; - auto Type = AllocInfo.Type; + auto AllocInfo = OffloadContext::get().AllocInfoMap.at(Address); + Device = AllocInfo.Device; + Type = AllocInfo.Type; + OffloadContext::get().AllocInfoMap.erase(Address); + } if (auto Res = Device->Device->dataDelete(Address, convertOlToPluginAllocTy(Type))) return Res; - OffloadContext::get().AllocInfoMap.erase(Address); - return Error::success(); }