Skip to content

[UR][L0] Fix potential memory leaks - #22938

Open
kweronsx wants to merge 1 commit into
intel:syclfrom
kweronsx:potential-mem-leak
Open

[UR][L0] Fix potential memory leaks#22938
kweronsx wants to merge 1 commit into
intel:syclfrom
kweronsx:potential-mem-leak

Conversation

@kweronsx

Copy link
Copy Markdown
Contributor

Fixes #18265

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.

Pull request overview

This PR addresses potential memory leaks in the Unified Runtime Level Zero adapter by introducing RAII guards around allocations that can be bypassed by early-return macros (e.g., ZE2UR_CALL / UR_CALL).

Changes:

  • Add a guard in urMemBufferCreate to ensure partially-created ur_buffer instances are freed on error paths.
  • Refactor buffer partition creation to use std::unique_ptr / std::make_unique and release ownership on success.
  • Add an RAII guard for waitlist.ZeEventList in ur_buffer::getBufferZeHandle so it’s deleted on all exit paths.
Suppressed comments (1)

unified-runtime/source/adapters/level_zero/memory.cpp:1916

  • This function retains the context and inserts into Context->MemAllocs before executing several UR_CALL/ZE2UR_CALL operations that can early-return. On those error paths, the retained context and MemAllocs entry will not be rolled back, causing leaks/state pollution even if the ur_buffer is RAII-managed. Consider deferring the retain/MemAllocs.emplace(...) until after all fallible operations succeed (right before returning), or add a scope rollback guard that erases the map entry and releases the retained context on failure.
  *Mem = v1_cast(static_cast<ur_mem_handle_t_ *>(Buffer.release()));

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

Comment thread unified-runtime/source/adapters/level_zero/memory.cpp Outdated

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

unified-runtime/source/adapters/level_zero/memory.cpp:1864

  • ur_buffer's destructor does not call free() (see ur_buffer::~ur_buffer()), so using std::unique_ptr<ur_buffer> here means any early-return after the buffer is created (e.g. from UR_CALL(...) / ZE2UR_CALL(...) later in this function) will delete the object without releasing allocations or an owned native handle. This can introduce leaks on error paths. Use the same guard pattern as urMemBufferCreate (custom deleter calling free() before delete) so cleanup happens on all returns.
  std::unique_ptr<ur_buffer> Buffer;
  try {
    Buffer = std::make_unique<ur_buffer>(
        Context, Size, Device, ur_cast<char *>(NativeMem), OwnNativeHandle);
  } catch (const std::bad_alloc &) {

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

unified-runtime/source/adapters/level_zero/memory.cpp:1680

  • The guard is still null if new ur_buffer(...) throws. With UR_MEM_FLAG_USE_HOST_POINTER, maybeImportUSM has already imported Host, so an allocation/constructor failure reaches these catches without releasing that import. Release the import in both failure paths (or guard it independently until the buffer assumes ownership).
    Buffer = new ur_buffer(Context, Size, HostPtrOrNull, HostPtrImported);
    bufferGuard.reset(Buffer);

Comment thread unified-runtime/source/adapters/level_zero/memory.cpp Outdated

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread unified-runtime/source/adapters/level_zero/memory.cpp Outdated

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

unified-runtime/source/adapters/level_zero/memory.cpp:1680

  • The guard is armed only after ur_buffer finishes construction, but maybeImportUSM has already imported Host above. If allocation of the object or Allocations[nullptr] in the constructor throws, these catch paths return without releasing that imported pointer, so the OOM path still leaks the resource this change is intended to protect. Release the import in both constructor-failure handlers (or guard it separately until ownership transfers to bufferGuard).
    bufferGuard.reset(Buffer);

Comment thread unified-runtime/source/adapters/level_zero/memory.cpp

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

unified-runtime/source/adapters/level_zero/memory.cpp:1903

  • Delay adopting the native allocation until creation has fully succeeded. Both getZeHandle and zeCommandListAppendMemoryCopy below can return an error; after this assignment, such a return runs the guard, whose deleter calls free() and releases NativeMem. The API specifies that ownership is transferred to the resultant object, so a failed call must not consume the caller's handle. Mark this allocation free_native only at the success/commit point, and defer or roll back the corresponding MemAllocs entry and context retain so failure cleanup still releases only adapter-created allocations.
  if (OwnNativeHandle)
    Buffer->Allocations[Device].ReleaseAction =
        ur_buffer::allocation_t::free_native;

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

unified-runtime/source/adapters/level_zero/memory.cpp:1680

  • This guard is armed only after ur_buffer finishes construction. With UR_MEM_FLAG_USE_HOST_POINTER and USM import enabled, maybeImportUSM has already registered Host, while the constructor's Allocations[nullptr] insertion can throw std::bad_alloc. The catch then returns without an object whose free() can release that registration, so the imported pointer still leaks. Add a separate import guard immediately after maybeImportUSM and dismiss it once the constructed buffer assumes the unimport release action.
    bufferGuard.reset(Buffer);

@kweronsx
kweronsx force-pushed the potential-mem-leak branch from 0868ee1 to 25f8390 Compare August 17, 2026 09:24
@kweronsx
kweronsx requested a balanced review from Copilot August 17, 2026 09:24

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@kweronsx
kweronsx marked this pull request as ready for review August 17, 2026 10:27
@kweronsx
kweronsx requested a review from a team as a code owner August 17, 2026 10:27
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.

[UR][L0] Possible memory leak in ur_buffer::getBufferZeHandle

2 participants