[BUG]: VMM growth frees an unowned address after a failed adjacent reservation
@Andy-Jost y travaille déjà.
Depuis le 23/7/2026.
Évaluation
Cette issue n'a pas encore été évaluée.
Description
Component
cuda.core
What happened?
VirtualMemoryResource.modify_allocation() first tries to reserve the additional virtual address range immediately after the existing allocation.
When that cuMemAddressReserve() call fails with a recoverable error, the returned pointer is not an owned reservation. The cuda.bindings wrapper returns (error, None) for this case, but the current growth path still calls cuMemAddressFree(new_ptr, size) before entering the slow-path fallback.
That cleanup call is invalid because no reservation was created. It can replace the original recoverable reservation error with another driver error, such as CUDA_ERROR_INVALID_VALUE, and prevent the fallback from being attempted.
How to reproduce
On a CUDA VMM-capable GPU, first allocate a small buffer and request an intentionally impossible growth size:
import platform
from cuda.core import Device, VirtualMemoryResource, VirtualMemoryResourceOptions
from cuda.core._utils.cuda_utils import CUDAError
device = Device(0)
device.set_current()
handle_type = "win32_kmt" if platform.system() == "Windows" else "posix_fd"
mr = VirtualMemoryResource(
device,
config=VirtualMemoryResourceOptions(handle_type=handle_type),
)
buf = mr.allocate(4096)
try:
# Adjust this value if needed to make cuMemAddressReserve return
# CUDA_ERROR_OUT_OF_MEMORY on the target platform.
mr.modify_allocation(buf, 1 << 62)
except CUDAError as exc:
print(exc)
finally:
buf.close()
On the affected path, when the adjacent reservation returns CUDA_ERROR_OUT_OF_MEMORY, the subsequent cuMemAddressFree(None, size) produces a second error and masks the original reservation failure. The corrected path skips the free because the reservation did not succeed, then proceeds to the slow-path attempt and preserves the driver error if that attempt also fails.
The binding-level behavior can also be observed directly: cuMemAddressReserve() returns ptr=None on failure, while cuMemAddressFree() requires a pointer that came from a successful reservation.
Expected behavior
If the adjacent reservation fails, the code should not call cuMemAddressFree() for its returned pointer. It should either enter the slow path or propagate the original reservation error.
A reservation should only be freed when cuMemAddressReserve() succeeded and returned a noncontiguous address.
Additional context
PR #2237 separates these two cases and adds regression coverage for both failed reservations and successful noncontiguous reservations.
- Langage dominant
- Cython
- Étoiles
- 3.4k
- Forks
- 329
- Merge moyen
- 1 j 21 h
- PR mergées (30 j)
- 113
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de NVIDIA/cuda-python
-
bug cuda.core
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
NVIDIA/cuda-python#2886 · 1 commentaire ·
-
triage
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
NVIDIA/cuda-python#2717 ·
-
triage
Difficulté 1/5 1-3 heures Accessibilité débutants 90/100
NVIDIA/cuda-python#2712 ·
-
[BUG]: LocatedHeaderDir is mutable, so callers can poison the cached header-directory lookup Ouvertetriage
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
NVIDIA/cuda-python#2646 · 1 réaction ·
-
cuda.core triage
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
NVIDIA/cuda-python#2435 · 1 commentaire ·