nvidia: use vzalloc for oversized page table allocations#1234
Open
guzebing1612-dev wants to merge 1 commit into
Open
nvidia: use vzalloc for oversized page table allocations#1234guzebing1612-dev wants to merge 1 commit into
guzebing1612-dev wants to merge 1 commit into
Conversation
nvos_create_alloc() allocates at->page_table as a single array of
nvidia_pte_t entries:
pt_size = num_pages * sizeof(nvidia_pte_t)
For very large registered system-memory ranges, pt_size can exceed
INT_MAX. For example, a 512 GiB range with 4 KiB base pages requires
134,217,728 entries. With 16-byte nvidia_pte_t entries, pt_size is
2,147,483,648 bytes.
kvzalloc() rejects sizes larger than INT_MAX before falling back to
vmalloc, so nvos_create_alloc() can fail even though the page table is
CPU-side metadata and does not require physical contiguity.
Use vzalloc() directly when pt_size exceeds INT_MAX, while preserving
the existing kvzalloc() path for smaller allocations.
The existing kvfree() release path remains valid for both kvzalloc()
and vzalloc() allocations.
Signed-off-by: Guzebing <guzebing1612@gmail.com>
9d59c5c to
cb2a351
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR avoids a failure in
nvos_create_alloc()when registering very largesystem-memory ranges.
The issue was found in a CXL-DRAM use case where a large CXL-DRAM backed host
memory region is registered with the NVIDIA driver so that it can be accessed by
the GPU. In the tested workload, vLLM + LMCache uses CXL-DRAM as host-side KV
cache storage, and a 512 GiB CXL-DRAM backed range needs to be registered with
cudaHostRegister().nvos_create_alloc()currently allocatesat->page_tableas one largekvzalloc()object. For very large registered host-memory ranges, the computedpage table metadata size can exceed
INT_MAX. In that case,kvzalloc()failsbefore falling back to
vmalloc, and the registration fails.This change uses
vzalloc()directly only whenpt_size > INT_MAX, whilepreserving the existing
kvzalloc()path for smaller allocations.Background
The target deployment uses CXL-DRAM as an extension of host memory for GPU
workloads. The specific use case is to make a large CXL-DRAM backed host memory
range available to the GPU through CUDA host memory registration.
In this setup:
The failure was observed when trying to register a 512 GiB CXL-DRAM backed host
memory range for GPU use.
Problem
nvos_create_alloc()allocatesat->page_tableas a single metadata array:For very large registered system-memory ranges,
pt_sizecan exceed thekvmalloc()/kvzalloc()size guard.For example, a 512 GiB registered range with 4 KiB base pages requires:
2147483648 bytesis exactly 2 GiB and is larger thanINT_MAX. In this case,kvzalloc()returns NULL before falling back tovmalloc, causingnvos_create_alloc()to fail.In CUDA applications this is visible as a large
cudaHostRegister()failure,because the CUDA user-space API eventually enters the NVIDIA kernel module path
which registers and pins the user pages.
Root cause
The failure is caused by a single oversized kernel allocation for CPU-side page
metadata:
The page table metadata is CPU-side driver metadata. It does not require
physical contiguity. The existing cleanup path already uses
kvfree(), which isvalid for both
kvzalloc()-backed andvzalloc()-backed allocations.Testing scope
This has been tested with the NVIDIA open kernel module flavor only.
Reproduction and validation environment:
I do not have access to the proprietary kernel module package of the same
version, so I have not verified whether the same issue reproduces with the
proprietary kernel module flavor.
Runtime evidence before this patch
For the 512 GiB failure case, bpftrace showed that the NVIDIA page table
metadata size reaches 2048 MiB:
A small kernel-module probe also reproduced the allocator boundary:
This matches the observed 512 GiB failure.
Validation after this patch
The driver was rebuilt with this change and the patched open kernel module was
loaded on the same test system.
After the patch:
This verifies that the 512 GiB registration no longer fails at the
nvos_create_alloc()page table allocation path.