From c3ee9c6407a244d08d17eed2f065157bc921f512 Mon Sep 17 00:00:00 2001 From: "Neil R. Spruit" Date: Fri, 11 Apr 2025 16:41:49 -0700 Subject: [PATCH] [UR][L0] Fix Barrier Event Cleanup - Fix barrier wait cleanup of events given an out event such that an additional refcnt release is done and with multi command lists and in order, the active barrier is properly cleared before reassignment. Signed-off-by: Neil R. Spruit --- .../source/adapters/level_zero/event.cpp | 16 ++++++++++++++-- .../source/adapters/level_zero/queue.cpp | 7 ++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/unified-runtime/source/adapters/level_zero/event.cpp b/unified-runtime/source/adapters/level_zero/event.cpp index 49ab2036b8ac8..f23cab32c5a5b 100644 --- a/unified-runtime/source/adapters/level_zero/event.cpp +++ b/unified-runtime/source/adapters/level_zero/event.cpp @@ -302,6 +302,9 @@ ur_result_t urEnqueueEventsWaitWithBarrierExt( // need to keep track of any active barriers if we have in-order queue. if (UseMultipleCmdlistBarriers && !Queue->isInOrderQueue()) { auto UREvent = reinterpret_cast(ResultEvent); + // We must release the Active Barrier before we start the next one + // otherwise we will leak an event that won't be released. + UR_CALL(Queue->ActiveBarriers.clear()); Queue->ActiveBarriers.add(UREvent); } @@ -884,12 +887,21 @@ ur_result_t urEventRelease(/** [in] handle of the event object */ ur_event_handle_t Event) { Event->RefCountExternal--; bool isEventsWaitCompleted = - Event->CommandType == UR_COMMAND_EVENTS_WAIT && Event->Completed; + (Event->CommandType == UR_COMMAND_EVENTS_WAIT || + Event->CommandType == UR_COMMAND_EVENTS_WAIT_WITH_BARRIER) && + Event->Completed; UR_CALL(urEventReleaseInternal(Event)); // If this is a Completed Event Wait Out Event, then we need to cleanup the // event at user release and not at the time of completion. + // If the event is labelled as completed and no additional references are + // removed, then we still need to decrement the event, but not mark as + // completed. if (isEventsWaitCompleted) { - UR_CALL(CleanupCompletedEvent((Event), false, false)); + if (Event->CleanedUp) { + UR_CALL(urEventReleaseInternal(Event)); + } else { + UR_CALL(CleanupCompletedEvent((Event), false, false)); + } } return UR_RESULT_SUCCESS; diff --git a/unified-runtime/source/adapters/level_zero/queue.cpp b/unified-runtime/source/adapters/level_zero/queue.cpp index 46e71e2439d2d..e0534af478ae7 100644 --- a/unified-runtime/source/adapters/level_zero/queue.cpp +++ b/unified-runtime/source/adapters/level_zero/queue.cpp @@ -2374,10 +2374,11 @@ ur_queue_handle_t_::insertActiveBarriers(ur_command_list_ptr_t &CmdList, Event->WaitList = ActiveBarriersWaitList; Event->OwnNativeHandle = true; - // If there are more active barriers, insert a barrier on the command-list. We - // do not need an event for finishing so we pass nullptr. + // If there are more active barriers, insert a barrier on the command-list. + // We need to signal the current active barrier event otherwise we will leak + // the Event object when we replace the active barrier. ZE2UR_CALL(zeCommandListAppendBarrier, - (CmdList->first, nullptr, ActiveBarriersWaitList.Length, + (CmdList->first, Event->ZeEvent, ActiveBarriersWaitList.Length, ActiveBarriersWaitList.ZeEventList)); return UR_RESULT_SUCCESS; }