Skip to content

Commit 68fc780

Browse files
authored
[SYCL][L0] Fix memory leak in event pool. (#2838)
Memory leak in event pool was caused because we failed to invoke zeEventPoolDestroy() because we set the live events of the newly created pool with max number of events. And then we only destroy the pool if the live events count drops to zero. The number of live events drops to zero only we really used all 256 events available in the pool. Therefore, it became a memory leak when only a few events are used in the pool. The fix is to introduce a new method finalize() in pi_context class. This method is invoked from the pi_context destructor. It checks if there is any pool that has non-zero live events and then calls zeEventPoolDestroy for it to deallocate event pool associated with the context. Signed-off-by: Byoungro So <[email protected]>
1 parent 6733c8b commit 68fc780

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

sycl/plugins/level_zero/pi_level_zero.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,26 @@ pi_result _pi_context::initialize() {
437437
return PI_SUCCESS;
438438
}
439439

440+
pi_result _pi_context::finalize() {
441+
// This function is called when pi_context is deallocated, piContextRelase.
442+
// There could be some memory that may have not been deallocated.
443+
// For example, zeEventPool could be still alive.
444+
std::lock_guard<std::mutex> NumEventsLiveInEventPoolGuard(
445+
NumEventsLiveInEventPoolMutex, std::adopt_lock);
446+
if (ZeEventPool && NumEventsLiveInEventPool[ZeEventPool])
447+
zeEventPoolDestroy(ZeEventPool);
448+
449+
// Destroy the command list used for initializations
450+
ZE_CALL(zeCommandListDestroy(ZeCommandListInit));
451+
452+
// Destruction of some members of pi_context uses L0 context
453+
// and therefore it must be valid at that point.
454+
// Technically it should be placed to the destructor of pi_context
455+
// but this makes API error handling more complex.
456+
ZE_CALL(zeContextDestroy(ZeContext));
457+
return PI_SUCCESS;
458+
}
459+
440460
pi_result
441461
_pi_queue::resetCommandListFenceEntry(ze_command_list_handle_t ZeCommandList,
442462
bool MakeAvailable) {
@@ -1810,16 +1830,10 @@ pi_result piContextRelease(pi_context Context) {
18101830

18111831
assert(Context);
18121832
if (--(Context->RefCount) == 0) {
1813-
auto ZeContext = Context->ZeContext;
1814-
// Destroy the command list used for initializations
1815-
ZE_CALL(zeCommandListDestroy(Context->ZeCommandListInit));
1833+
// Clean up any live memory associated with Context
1834+
pi_result Result = Context->finalize();
18161835
delete Context;
1817-
1818-
// Destruction of some members of pi_context uses L0 context
1819-
// and therefore it must be valid at that point.
1820-
// Technically it should be placed to the destructor of pi_context
1821-
// but this makes API error handling more complex.
1822-
ZE_CALL(zeContextDestroy(ZeContext));
1836+
return Result;
18231837
}
18241838
return PI_SUCCESS;
18251839
}

sycl/plugins/level_zero/pi_level_zero.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ struct _pi_context : _pi_object {
216216
// Initialize the PI context.
217217
pi_result initialize();
218218

219+
// Finalize the PI context
220+
pi_result finalize();
221+
219222
// A L0 context handle is primarily used during creation and management of
220223
// resources that may be used by multiple devices.
221224
ze_context_handle_t ZeContext;

0 commit comments

Comments
 (0)