Skip to content

Commit af0e95b

Browse files
[SYCL][Coverity] Fix MISSING_LOCK coverity hits in the program manager (#18121)
This PR guards accesses to `m_DeviceImage` and `m_VFSet2BinImage` caches/maps in the Program Manager using `m_KernelIDsMutex` in situations where multiple threads may be accessing the maps at the same time. I am opting to use `m_KernelIDsMutex` here as both maps are commonly accessed while holding said mutex: In fact, a lot of maps/caches in the program manager use `m_KernelIDsMutex` (This is not the most optimal solution, but that is out of the scope of this PR, see #18165) This PR addresses Coverity hits that needs to have fixes submitted before the code cutoff. --------- Co-authored-by: Steffen Larsen <[email protected]>
1 parent 51dbbc4 commit af0e95b

File tree

2 files changed

+41
-29
lines changed

2 files changed

+41
-29
lines changed

sycl/source/detail/program_manager/program_manager.cpp

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -765,35 +765,42 @@ ProgramManager::collectDependentDeviceImagesForVirtualFunctions(
765765
}
766766
}
767767

768-
while (!WorkList.empty()) {
769-
std::string SetName = WorkList.front();
770-
WorkList.pop();
768+
if (!WorkList.empty()) {
769+
// Guard read access to m_VFSet2BinImage:
770+
// TODO: a better solution should be sought in the future, i.e. a different
771+
// mutex than m_KernelIDsMutex, check lock check pattern, etc.
772+
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
771773

772-
// There could be more than one device image that uses the same set
773-
// of virtual functions, or provides virtual funtions from the same
774-
// set.
775-
for (RTDeviceBinaryImage *BinImage : m_VFSet2BinImage[SetName]) {
776-
// Here we can encounter both uses-virtual-functions-set and
777-
// virtual-functions-set properties, but their handling is the same: we
778-
// just grab all sets they reference and add them for consideration if
779-
// we haven't done so already.
780-
for (const sycl_device_binary_property &VFProp :
781-
BinImage->getVirtualFunctions()) {
782-
std::string StrValue = DeviceBinaryProperty(VFProp).asCString();
783-
for (const auto &SetName : detail::split_string(StrValue, ',')) {
784-
if (HandledSets.insert(SetName).second)
785-
WorkList.push(SetName);
774+
while (!WorkList.empty()) {
775+
std::string SetName = WorkList.front();
776+
WorkList.pop();
777+
778+
// There could be more than one device image that uses the same set
779+
// of virtual functions, or provides virtual funtions from the same
780+
// set.
781+
for (RTDeviceBinaryImage *BinImage : m_VFSet2BinImage.at(SetName)) {
782+
// Here we can encounter both uses-virtual-functions-set and
783+
// virtual-functions-set properties, but their handling is the same: we
784+
// just grab all sets they reference and add them for consideration if
785+
// we haven't done so already.
786+
for (const sycl_device_binary_property &VFProp :
787+
BinImage->getVirtualFunctions()) {
788+
std::string StrValue = DeviceBinaryProperty(VFProp).asCString();
789+
for (const auto &SetName : detail::split_string(StrValue, ',')) {
790+
if (HandledSets.insert(SetName).second)
791+
WorkList.push(SetName);
792+
}
786793
}
787-
}
788794

789-
// TODO: Complete this part about handling of incompatible device images.
790-
// If device image uses the same virtual function set, then we only
791-
// link it if it is compatible.
792-
// However, if device image provides virtual function set and it is
793-
// incompatible, then we should link its "dummy" version to avoid link
794-
// errors about unresolved external symbols.
795-
if (doesDevSupportDeviceRequirements(Dev, *BinImage))
796-
DeviceImagesToLink.insert(BinImage);
795+
// TODO: Complete this part about handling of incompatible device
796+
// images. If device image uses the same virtual function set, then we
797+
// only link it if it is compatible. However, if device image provides
798+
// virtual function set and it is incompatible, then we should link its
799+
// "dummy" version to avoid link errors about unresolved external
800+
// symbols.
801+
if (doesDevSupportDeviceRequirements(Dev, *BinImage))
802+
DeviceImagesToLink.insert(BinImage);
803+
}
797804
}
798805
}
799806

@@ -2163,8 +2170,14 @@ void ProgramManager::addImages(sycl_device_binaries DeviceBinary) {
21632170
}
21642171

21652172
void ProgramManager::removeImages(sycl_device_binaries DeviceBinary) {
2173+
if (DeviceBinary->NumDeviceBinaries == 0)
2174+
return;
2175+
// Acquire lock to read and modify maps for kernel bundles
2176+
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
2177+
21662178
for (int I = 0; I < DeviceBinary->NumDeviceBinaries; I++) {
21672179
sycl_device_binary RawImg = &(DeviceBinary->DeviceBinaries[I]);
2180+
21682181
auto DevImgIt = m_DeviceImages.find(RawImg);
21692182
if (DevImgIt == m_DeviceImages.end())
21702183
continue;
@@ -2178,9 +2191,6 @@ void ProgramManager::removeImages(sycl_device_binaries DeviceBinary) {
21782191
// Drop the kernel argument mask map
21792192
m_EliminatedKernelArgMasks.erase(Img);
21802193

2181-
// Acquire lock to modify maps for kernel bundles
2182-
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
2183-
21842194
// Unmap the unique kernel IDs for the offload entries
21852195
for (sycl_offload_entry EntriesIt = EntriesB; EntriesIt != EntriesE;
21862196
EntriesIt = EntriesIt->Increment()) {

sycl/source/detail/program_manager/program_manager.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ class ProgramManager {
459459

460460
/// Keeps all device images we are refering to during program lifetime. Used
461461
/// for proper cleanup.
462+
/// Access must be guarded by the m_KernelIDsMutex mutex.
462463
std::unordered_map<sycl_device_binary, RTDeviceBinaryImageUPtr>
463464
m_DeviceImages;
464465

@@ -468,6 +469,7 @@ class ProgramManager {
468469

469470
/// Caches list of device images that use or provide virtual functions from
470471
/// the same set. Used to simplify access.
472+
/// Access must be guarded by the m_KernelIDsMutex mutex.
471473
std::unordered_map<std::string, std::set<RTDeviceBinaryImage *>>
472474
m_VFSet2BinImage;
473475

0 commit comments

Comments
 (0)