Repository navigation
Validate and lock SharedBuffer allocations (#24463) - #24463
alirezamonfared wants to merge 1 commit into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24463
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 New Failure, 1 Unrelated FailureAs of commit 87da567 with merge base 893d815 ( BROKEN TRUNK - The following job failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
|
@alirezamonfared has exported this pull request. If you are a Meta employee, you can view the originating Diff in D128567553. |
This PR needs a
|
Summary: Pull Request resolved: pytorch#24463 ## TL;DR Make the QNN `SharedBuffer` manager safe for concurrent callers. Reject invalid `AllocMem` requests before they reach the RPC allocator. ## Problem `SharedBuffer` is a process-wide singleton. Its four maps (aligned-to-original pointer, allocated size, and the tensor-to-custom-memory map and its reverse) had no synchronization. Applications call `QnnExecuTorchAllocCustomMem`, `QnnExecuTorchAddCustomMemTensorAddr` and `QnnExecuTorchFreeCustomMem` while `QnnManager` reads the same maps to register tensor memory. Allocate, register, lookup and free on different threads could therefore race. `AllocMem` also had three validation and bookkeeping bugs: - It accepted a zero size, a zero or non-power-of-two alignment, and sizes whose alignment padding overflows the `int32_t` rpcmem size. - It recorded an allocated size before confirming the pointer insertion. - When that insertion failed, it freed the allocation but still returned the aligned pointer. ## Solution A per-instance `memory_mutex_` now guards every map access. Before calling the RPC allocator, `AllocMem` rejects a zero size, a zero or non-power-of-two alignment, and any request where `bytes + alignment` exceeds `INT32_MAX`. A new allocation stays in a scoped owner until its bookkeeping is installed. If installing the bookkeeping fails after the RPC allocation succeeds, the scoped owner frees the original rpcmem pointer, removes any partial entries, and `AllocMem` returns null. A new `shared_buffer_test` drives the manager through fake RPC callbacks, so it needs no device. Authored with Claude Code and Codex. Differential Revision: D128567553
f54891c to
87da567
Compare
Summary:
TL;DR
Make the QNN
SharedBuffermanager safe for concurrent callers. Reject invalidAllocMemrequests before they reach the RPC allocator.Problem
SharedBufferis a process-wide singleton. Its four maps (aligned-to-original pointer, allocated size, and the tensor-to-custom-memory map and its reverse) had no synchronization. Applications callQnnExecuTorchAllocCustomMem,QnnExecuTorchAddCustomMemTensorAddrandQnnExecuTorchFreeCustomMemwhileQnnManagerreads the same maps to register tensor memory. Allocate, register, lookup and free on different threads could therefore race.AllocMemalso had three validation and bookkeeping bugs:int32_trpcmem size.Solution
A per-instance
memory_mutex_now guards every map access. Before calling the RPC allocator,AllocMemrejects a zero size, a zero or non-power-of-two alignment, and any request wherebytes + alignmentexceedsINT32_MAX. A new allocation stays in a scoped owner until its bookkeeping is installed. If installing the bookkeeping fails after the RPC allocation succeeds, the scoped owner frees the original rpcmem pointer, removes any partial entries, andAllocMemreturns null. A newshared_buffer_testdrives the manager through fake RPC callbacks, so it needs no device.Authored with Claude Code and Codex.
Differential Revision: D128567553