{"record":{"id":"c38b3ff8a49f5549","repo":"sgl-project/sglang","slug":"vmmreservation-map-existing-after-close","errorCode":null,"errorMessage":"VmmReservation.map_existing after close","messagePattern":"VmmReservation\\.map_existing after close","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/utils/cuda_vmm_utils.py","lineNumber":596,"sourceCode":"            if handle is not None:\n                try:\n                    check_drv(drv.cuMemRelease(handle), \"cuMemRelease(local rollback)\")\n                except BaseException as cleanup_error:\n                    cleanup_errors.append(cleanup_error)\n            if cleanup_errors:\n                error.add_note(\n                    f\"{len(cleanup_errors)} CUDA VMM rollback operation(s) also failed\"\n                )\n                raise error from cleanup_errors[0]\n            raise\n\n        self._mappings.append((address, size, handle))\n        return handle\n\n    def map_existing(self, offset: int, size: int, handle) -> None:\n        \"\"\"Map a caller-owned physical allocation into this reservation.\"\"\"\n        if self._closed:\n            raise RuntimeError(\"VmmReservation.map_existing after close\")\n        offset, size = int(offset), int(size)\n        drv = _get_cuda_driver()\n        address = self.base + offset\n        mapped = False\n        try:\n            check_drv(\n                drv.cuMemMap(address, size, 0, handle, 0),\n                \"cuMemMap(existing)\",\n            )\n            mapped = True\n            check_drv(\n                drv.cuMemSetAccess(\n                    address,\n                    size,\n                    self._access_descs,\n                    len(self._access_descs),\n                ),\n                \"cuMemSetAccess(existing)\",","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/utils/cuda_vmm_utils.py#L578-L614","documentation":"VmmReservation.map_existing refuses to map a caller-owned physical allocation (via cuMemMap of an exported handle) after the reservation has been closed, because the underlying VA range has already been released to the driver.","triggerScenarios":"Calling map_existing on a VmmReservation whose close() has already run (the _closed flag is set); typically when mapping peer views or setup-layer handles after teardown began.","commonSituations":"Error-path cleanup ordering: an exception triggers close() of the reservation, then a subsequent retry or teardown handler calls map_existing; or holding a stale reservation object across a model reload / engine shutdown.","solutions":["Audit cleanup paths to ensure no code path maps after close (guard with try/finally ordering).","Check reservation._closed / use a wrapper that raises a clear domain error before calling.","Create a fresh reservation and redo the import instead of reusing a closed one."],"exampleFix":"// before\nres.map_existing(offset, size, handle)  # res already closed\n\n// after\nif res._closed:\n    res = VmmReservation.reserve(total_size)\nres.map_existing(offset, size, handle)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_open(res) -> bool:\n    return not getattr(res, \"_closed\", True)","tryCatchPattern":"try:\n    res.map_existing(offset, size, handle)\nexcept RuntimeError as e:\n    if \"after close\" in str(e):\n        res = make_fresh_reservation(total_size)\n        res.map_existing(offset, size, handle)\n    else:\n        raise","preventionTips":["Guard all map calls with an is-open check in teardown-adjacent code","Invalidate references to reservations in close()/__exit__"],"tags":["cuda","vmm","use-after-close","lifecycle"],"backgroundTag":"use-after-close","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}