Skip to content

Commit bc301f5

Browse files
authored
[Offload] Do not do not re-initialize RPC server (llvm#218757)
Summary: This was done for every executable that was loaded. In the current OpenMP use this never caused issues, but we need to check if this was already done so we don't leak the memory.
1 parent 4cca4a5 commit bc301f5

1 file changed

Lines changed: 31 additions & 26 deletions

File tree

  • offload/plugins-nextgen/common/src

offload/plugins-nextgen/common/src/RPC.cpp

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -207,32 +207,40 @@ RPCServerTy::isDeviceUsingRPC(plugin::GenericDeviceTy &Device,
207207
Error RPCServerTy::initDevice(plugin::GenericDeviceTy &Device,
208208
plugin::GenericGlobalHandlerTy &Handler,
209209
plugin::DeviceImageTy &Image) {
210+
std::lock_guard<decltype(BufferMutex)> Lock(BufferMutex);
210211
uint64_t NumPorts =
211212
std::min(Device.requestedRPCPortCount(), rpc::MAX_PORT_COUNT);
212-
auto RPCBufferOrErr = Device.allocate(
213-
rpc::Server::allocation_size(Device.getRPCNumLanes(), NumPorts), nullptr,
214-
TARGET_ALLOC_HOST);
215-
if (!RPCBufferOrErr)
216-
return RPCBufferOrErr.takeError();
217-
218-
void *RPCBuffer = *RPCBufferOrErr;
219-
if (!RPCBuffer)
220-
return plugin::Plugin::error(
221-
error::ErrorCode::UNKNOWN,
222-
"failed to initialize RPC server for device %d", Device.getDeviceId());
223-
224-
// The doorbell is used by AMDGPU targets to let the server thread be
225-
// descheduled. It is optional and will be ignored if the fields are null.
226-
rpc::Doorbell Doorbell{};
227-
if (auto Err = Device.Plugin.initRPCDoorbell(Doorbell.value, Doorbell.mailbox,
228-
Doorbell.event_id))
229-
return Err;
230-
231-
auto *DoorbellPtr = reinterpret_cast<rpc::Doorbell *>(
232-
static_cast<uint8_t *>(RPCBuffer) + rpc::Server::doorbell_offset());
233-
std::memcpy(DoorbellPtr, &Doorbell, sizeof(rpc::Doorbell));
213+
void *RPCBuffer = Buffers[Device.getDeviceId()];
214+
if (!RPCBuffer) {
215+
auto RPCBufferOrErr = Device.allocate(
216+
rpc::Server::allocation_size(Device.getRPCNumLanes(), NumPorts),
217+
nullptr, TARGET_ALLOC_HOST);
218+
if (!RPCBufferOrErr)
219+
return RPCBufferOrErr.takeError();
220+
221+
RPCBuffer = *RPCBufferOrErr;
222+
if (!RPCBuffer)
223+
return plugin::Plugin::error(
224+
error::ErrorCode::UNKNOWN,
225+
"failed to initialize RPC server for device %d",
226+
Device.getDeviceId());
227+
228+
// The doorbell is used by AMDGPU targets to let the server thread be
229+
// descheduled. It is optional and will be ignored if the fields are null.
230+
rpc::Doorbell Doorbell{};
231+
if (auto Err = Device.Plugin.initRPCDoorbell(
232+
Doorbell.value, Doorbell.mailbox, Doorbell.event_id))
233+
return Err;
234+
235+
auto *DoorbellPtr = reinterpret_cast<rpc::Doorbell *>(
236+
static_cast<uint8_t *>(RPCBuffer) + rpc::Server::doorbell_offset());
237+
std::memcpy(DoorbellPtr, &Doorbell, sizeof(rpc::Doorbell));
238+
239+
Buffers[Device.getDeviceId()] = RPCBuffer;
240+
Devices[Device.getDeviceId()] = &Device;
241+
}
234242

235-
// Get the address of the RPC client from the device.
243+
// Each image has its own client that must point at the shared buffer.
236244
plugin::GlobalTy ClientGlobal("__llvm_rpc_client", sizeof(rpc::Client));
237245
if (auto Err =
238246
Handler.getGlobalMetadataFromDevice(Device, Image, ClientGlobal))
@@ -242,9 +250,6 @@ Error RPCServerTy::initDevice(plugin::GenericDeviceTy &Device,
242250
if (auto Err = Device.dataSubmit(ClientGlobal.getPtr(), &client,
243251
sizeof(rpc::Client), nullptr))
244252
return Err;
245-
std::lock_guard<decltype(BufferMutex)> Lock(BufferMutex);
246-
Buffers[Device.getDeviceId()] = RPCBuffer;
247-
Devices[Device.getDeviceId()] = &Device;
248253

249254
return Error::success();
250255
}

0 commit comments

Comments
 (0)