forked from OSchip/llvm-project
[OpenMP][FIX] Avoid use of stack allocations in asynchronous calls
As reported by Guilherme Valarini [0], we used to pass stack allocations to calls that can nowadays be asynchronous. This is arguably a problem and it will inevitably result in UB. To remedy the situation we allocate the locations as part of the AsyncInfoTy object. The lifetime of that object matches what we need for now. If the synchronization is not tied to the AsyncInfoTy object anymore we might need to have a different buffer construct in global space. This should be back-ported to LLVM 12 but needs slight modifications as it is based on refactoring patches we do not need to backport. [0] https://lists.llvm.org/pipermail/openmp-dev/2021-February/003867.html Reviewed By: JonChesterfield Differential Revision: https://reviews.llvm.org/D96667
This commit is contained in:
parent
758b849931
commit
2518cc65d2
|
@ -14,6 +14,7 @@
|
|||
#ifndef _OMPTARGET_H_
|
||||
#define _OMPTARGET_H_
|
||||
|
||||
#include <deque>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -136,6 +137,10 @@ struct DeviceTy;
|
|||
/// associated with a libomptarget layer device. RAII semantics to avoid
|
||||
/// mistakes.
|
||||
class AsyncInfoTy {
|
||||
/// Locations we used in (potentially) asynchronous calls which should live
|
||||
/// as long as this AsyncInfoTy object.
|
||||
std::deque<void *> BufferLocations;
|
||||
|
||||
__tgt_async_info AsyncInfo;
|
||||
DeviceTy &Device;
|
||||
|
||||
|
@ -151,6 +156,10 @@ public:
|
|||
///
|
||||
/// \returns OFFLOAD_FAIL or OFFLOAD_SUCCESS appropriately.
|
||||
int synchronize();
|
||||
|
||||
/// Return a void* reference with a lifetime that is at least as long as this
|
||||
/// AsyncInfoTy object. The location can be used as intermediate buffer.
|
||||
void *&getVoidPtrLocation();
|
||||
};
|
||||
|
||||
/// This struct is a record of non-contiguous information
|
||||
|
|
|
@ -31,6 +31,11 @@ int AsyncInfoTy::synchronize() {
|
|||
return Result;
|
||||
}
|
||||
|
||||
void *&AsyncInfoTy::getVoidPtrLocation() {
|
||||
BufferLocations.push_back(nullptr);
|
||||
return BufferLocations.back();
|
||||
}
|
||||
|
||||
/* All begin addresses for partially mapped structs must be 8-aligned in order
|
||||
* to ensure proper alignment of members. E.g.
|
||||
*
|
||||
|
@ -432,7 +437,8 @@ int targetDataBegin(ident_t *loc, DeviceTy &Device, int32_t arg_num,
|
|||
DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n",
|
||||
DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin));
|
||||
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
|
||||
void *TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
|
||||
void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation();
|
||||
TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
|
||||
int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase,
|
||||
sizeof(void *), AsyncInfo);
|
||||
if (rt != OFFLOAD_SUCCESS) {
|
||||
|
@ -1123,8 +1129,9 @@ static int processDataBefore(ident_t *loc, int64_t DeviceId, void *HostPtr,
|
|||
DP("Parent lambda base " DPxMOD "\n", DPxPTR(TgtPtrBase));
|
||||
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
|
||||
void *TgtPtrBegin = (void *)((uintptr_t)TgtPtrBase + Delta);
|
||||
void *PointerTgtPtrBegin = Device.getTgtPtrBegin(
|
||||
HstPtrVal, ArgSizes[I], IsLast, false, IsHostPtr);
|
||||
void *&PointerTgtPtrBegin = AsyncInfo.getVoidPtrLocation();
|
||||
PointerTgtPtrBegin = Device.getTgtPtrBegin(HstPtrVal, ArgSizes[I],
|
||||
IsLast, false, IsHostPtr);
|
||||
if (!PointerTgtPtrBegin) {
|
||||
DP("No lambda captured variable mapped (" DPxMOD ") - ignored\n",
|
||||
DPxPTR(HstPtrVal));
|
||||
|
|
Loading…
Reference in New Issue