Skip to content

Commit f1017d0

Browse files
authored
[DevTSAN] Move AllocInfo into DeviceInfo to support indirect access (#19634)
If we maintain AllocInfo in ContextInfo, this will cause the pointer which is allocated by another context can't be poisoned.
1 parent 155a86c commit f1017d0

File tree

3 files changed

+33
-21
lines changed

3 files changed

+33
-21
lines changed

unified-runtime/source/loader/layers/sanitizer/tsan/tsan_buffer.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,10 @@ ur_result_t MemBuffer::getHandle(ur_device_handle_t Device, char *&Handle) {
186186
}
187187

188188
ur_result_t MemBuffer::free() {
189-
for (const auto &[_, Ptr] : Allocations) {
190-
ur_result_t URes = getTsanInterceptor()->releaseMemory(Context, Ptr);
189+
for (const auto &[Device, Ptr] : Allocations) {
190+
ur_result_t URes = Device
191+
? getTsanInterceptor()->releaseMemory(Context, Ptr)
192+
: getContext()->urDdiTable.USM.pfnFree(Context, Ptr);
191193
if (URes != UR_RESULT_SUCCESS) {
192194
UR_LOG_L(getContext()->logger, ERR, "Failed to free buffer handle {}",
193195
(void *)Ptr);

unified-runtime/source/loader/layers/sanitizer/tsan/tsan_interceptor.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ ur_result_t DeviceInfo::allocShadowMemory() {
101101
return UR_RESULT_SUCCESS;
102102
}
103103

104-
void ContextInfo::insertAllocInfo(TsanAllocInfo AI) {
104+
void DeviceInfo::insertAllocInfo(TsanAllocInfo AI) {
105105
std::scoped_lock<ur_shared_mutex> Guard(AllocInfosMutex);
106106
AllocInfos.insert(std::move(AI));
107107
}
@@ -153,7 +153,15 @@ ur_result_t TsanInterceptor::allocateMemory(ur_context_handle_t Context,
153153

154154
auto AI = TsanAllocInfo{reinterpret_cast<uptr>(Allocated), Size};
155155
// For updating shadow memory
156-
CI->insertAllocInfo(std::move(AI));
156+
if (Device) {
157+
auto DI = getDeviceInfo(Device);
158+
DI->insertAllocInfo(std::move(AI));
159+
} else {
160+
for (const auto &Device : CI->DeviceList) {
161+
auto DI = getDeviceInfo(Device);
162+
DI->insertAllocInfo(AI);
163+
}
164+
}
157165

158166
*ResultPtr = Allocated;
159167
return UR_RESULT_SUCCESS;
@@ -163,11 +171,14 @@ ur_result_t TsanInterceptor::releaseMemory(ur_context_handle_t Context,
163171
void *Ptr) {
164172
auto CI = getContextInfo(Context);
165173
auto Addr = reinterpret_cast<uptr>(Ptr);
166-
{
167-
std::scoped_lock<ur_shared_mutex> Guard(CI->AllocInfosMutex);
168-
auto It = std::find_if(CI->AllocInfos.begin(), CI->AllocInfos.end(),
174+
175+
for (const auto &Device : CI->DeviceList) {
176+
auto DI = getDeviceInfo(Device);
177+
std::scoped_lock<ur_shared_mutex> Guard(DI->AllocInfosMutex);
178+
auto It = std::find_if(DI->AllocInfos.begin(), DI->AllocInfos.end(),
169179
[&](auto &P) { return P.AllocBegin == Addr; });
170-
CI->AllocInfos.erase(It);
180+
if (It != DI->AllocInfos.end())
181+
DI->AllocInfos.erase(It);
171182
}
172183

173184
UR_CALL(getContext()->urDdiTable.USM.pfnFree(Context, Ptr));
@@ -343,7 +354,7 @@ ur_result_t TsanInterceptor::preLaunchKernel(ur_kernel_handle_t Kernel,
343354

344355
UR_CALL(prepareLaunch(CI, DI, InternalQueue, Kernel, LaunchInfo));
345356

346-
UR_CALL(updateShadowMemory(CI, DI, Kernel, InternalQueue));
357+
UR_CALL(updateShadowMemory(DI, Kernel, InternalQueue));
347358

348359
UR_CALL(getContext()->urDdiTable.Queue.pfnFinish(InternalQueue));
349360

@@ -470,12 +481,12 @@ ur_result_t TsanInterceptor::prepareLaunch(std::shared_ptr<ContextInfo> &,
470481
return UR_RESULT_SUCCESS;
471482
}
472483

473-
ur_result_t TsanInterceptor::updateShadowMemory(
474-
std::shared_ptr<ContextInfo> &CI, std::shared_ptr<DeviceInfo> &DI,
475-
ur_kernel_handle_t Kernel, ur_queue_handle_t Queue) {
484+
ur_result_t TsanInterceptor::updateShadowMemory(std::shared_ptr<DeviceInfo> &DI,
485+
ur_kernel_handle_t Kernel,
486+
ur_queue_handle_t Queue) {
476487
auto &PI = getProgramInfo(GetProgram(Kernel));
477-
std::scoped_lock<ur_shared_mutex> Guard(CI->AllocInfosMutex);
478-
for (auto &AllocInfo : CI->AllocInfos) {
488+
std::scoped_lock<ur_shared_mutex> Guard(DI->AllocInfosMutex);
489+
for (auto &AllocInfo : DI->AllocInfos) {
479490
UR_CALL(DI->Shadow->CleanShadow(Queue, AllocInfo.AllocBegin,
480491
AllocInfo.AllocSize));
481492
}

unified-runtime/source/loader/layers/sanitizer/tsan/tsan_interceptor.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ struct DeviceInfo {
4444

4545
std::shared_ptr<ShadowMemory> Shadow;
4646

47+
ur_shared_mutex AllocInfosMutex;
48+
std::set<TsanAllocInfo> AllocInfos;
49+
4750
explicit DeviceInfo(ur_device_handle_t Device) : Handle(Device) {}
4851

4952
ur_result_t allocShadowMemory();
53+
54+
void insertAllocInfo(TsanAllocInfo AI);
5055
};
5156

5257
struct ContextInfo {
@@ -56,9 +61,6 @@ struct ContextInfo {
5661

5762
std::vector<ur_device_handle_t> DeviceList;
5863

59-
ur_shared_mutex AllocInfosMutex;
60-
std::set<TsanAllocInfo> AllocInfos;
61-
6264
ur_shared_mutex InternalQueueMapMutex;
6365
std::unordered_map<ur_device_handle_t, std::optional<ManagedQueue>>
6466
InternalQueueMap;
@@ -80,8 +82,6 @@ struct ContextInfo {
8082

8183
ContextInfo &operator=(const ContextInfo &) = delete;
8284

83-
void insertAllocInfo(TsanAllocInfo AI);
84-
8585
ur_queue_handle_t getInternalQueue(ur_device_handle_t);
8686
};
8787

@@ -297,8 +297,7 @@ class TsanInterceptor {
297297
ur_shared_mutex KernelLaunchMutex;
298298

299299
private:
300-
ur_result_t updateShadowMemory(std::shared_ptr<ContextInfo> &CI,
301-
std::shared_ptr<DeviceInfo> &DI,
300+
ur_result_t updateShadowMemory(std::shared_ptr<DeviceInfo> &DI,
302301
ur_kernel_handle_t Kernel,
303302
ur_queue_handle_t Queue);
304303

0 commit comments

Comments
 (0)