Skip to content

[UR][L0] Free the active-barrier wait list when all barrier events have completed - #23165

Open
uditagarwal97 wants to merge 1 commit into
intel:syclfrom
uditagarwal97:udit/fix-l0-active-barrier-waitlist-leak
Open

uditagarwal97 wants to merge 1 commit into
intel:syclfrom
uditagarwal97:udit/fix-l0-active-barrier-waitlist-leak

Conversation

@uditagarwal97

Copy link
Copy Markdown
Contributor

ur_queue_handle_t_::insertActiveBarriers() builds a ur_ze_event_list_t from the
queue's active barriers and then, if the resulting length is zero, returns early:

    if (ActiveBarriersWaitList.Length == 0) {
      return UR_RESULT_SUCCESS;
    }

createAndRetainUrZeEventList() allocates its ZeEventList and UrEventList arrays up
front, before filtering, so a zero length does not mean nothing was allocated - it
means every barrier event had already completed by the time the list was built.
ur_ze_event_list_t has no destructor, and the only thing that frees those arrays is
the ownership transfer further down the function, which this early return skips.
So both arrays leak, every time.

Found by LeakSanitizer on level_zero:gpu.

Reproduction

#include <sycl/detail/core.hpp>
#include <vector>

int main() {
  sycl::queue Q;
  std::vector<int> Data(1024, 0);
  sycl::buffer<int> Buf(Data.data(), sycl::range<1>(1024));
  Q.submit([&](sycl::handler &CGH) {
    auto Acc = Buf.get_access<sycl::access_mode::write>(CGH);
    CGH.parallel_for(sycl::range<1>(1024), [=](sycl::id<1> I) { Acc[I] = 5; });
  });
  Q.ext_oneapi_submit_barrier().wait();
  auto HostAcc = Buf.get_host_access();
  return HostAcc[0] == 5 ? 0 : 1;
}

The .wait() is what makes it fire: the barrier event is complete by the time the host-accessor
read-back asks for a command list, so the wait list comes back with Length == 0.


Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

…ve completed

ur_queue_handle_t_::insertActiveBarriers() builds a ur_ze_event_list_t from the
queue's active barriers and then, if the resulting length is zero, returns early:

    if (ActiveBarriersWaitList.Length == 0) {
      return UR_RESULT_SUCCESS;
    }

createAndRetainUrZeEventList() allocates its ZeEventList and UrEventList arrays up
front, before filtering, so a zero length does not mean nothing was allocated - it
means every barrier event had already completed by the time the list was built.
ur_ze_event_list_t has no destructor, and the only thing that frees those arrays is
the ownership transfer further down the function, which this early return skips.
So both arrays leak, every time.

Release them explicitly on that path. collectEventsForReleaseAndDestroyUrZeEventList
is the existing API for it, and the event list it collects is provably empty here
because it pushes Length entries and Length is zero - so no release loop is needed.

Found by LeakSanitizer on level_zero:gpu. It is not specific to reusable_events, as
first suspected: the 16-line repro is a plain out-of-order queue with
ext_oneapi_submit_barrier().wait() followed by a host accessor, which leaks 2
allocations. Zero with this change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@uditagarwal97
uditagarwal97 requested a balanced review from Copilot September 14, 2026 23:56
@uditagarwal97 uditagarwal97 self-assigned this Sep 14, 2026
@uditagarwal97
uditagarwal97 marked this pull request as ready for review September 15, 2026 00:04
@uditagarwal97
uditagarwal97 requested a review from a team as a code owner September 15, 2026 00:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The cleanup correctly releases both allocated arrays without affecting retained events or control flow.

Pull request overview

Fixes a Level Zero queue memory leak when all active barrier events have completed.

Changes:

  • Frees allocated wait-list arrays before the zero-length early return.
  • Documents why cleanup remains necessary for an empty filtered list.
File summaries
File Description
unified-runtime/source/adapters/level_zero/queue.cpp Cleans up empty active-barrier wait lists.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants