Re: [PATCH 12/16] gpu: nova-core: mm: Add virtual address range tracking to VMM
From: Danilo Krummrich
Date: Wed Sep 09 2026 - 15:56:09 EST
On Wed Sep 9, 2026 at 5:59 AM CEST, Eliot Courtney wrote:
> + /// Allocate a contiguous virtual frame number range.
> + ///
> + /// # Arguments
> + ///
> + /// - `num_pages`: Number of pages to allocate.
> + /// - `va_range`: `None` = allocate anywhere, `Some(range)` = constrain allocation to the given
> + /// range.
> + fn alloc_vfn_range(&self, num_pages: usize, va_range: Option<Range<u64>>) -> Result<Vfn> {
> + let page_size: u64 = PAGE_SIZE.into_safe_cast();
> +
> + let start_vfn = match va_range {
> + Some(r) => {
> + let num_pages_u64: u64 = num_pages.into_safe_cast();
> + let size = num_pages_u64.checked_mul(page_size).ok_or(EOVERFLOW)?;
> + let range_size = r.end.checked_sub(r.start).ok_or(EOVERFLOW)?;
> + if range_size != size {
> + return Err(EINVAL);
> + }
> + let start_vfn: usize = (r.start / page_size).into_safe_cast();
> + let end_vfn: usize = (r.end / page_size).into_safe_cast();
> + self.virt_alloc
> + .insert_range(start_vfn..end_vfn, (), GFP_KERNEL)?;
> + start_vfn
> + }
> + None => self
> + .virt_alloc
> + .alloc_range(num_pages, (), ..self.va_pages, GFP_KERNEL)?,
> + };
> +
> + Ok(Vfn::new(start_vfn.into_safe_cast()))
> + }
> +
> + /// Free a virtual frame number range back to the maple tree.
> + fn free_vfn(&self, vfn: Vfn) {
> + let vfn_index: usize = vfn.raw().into_safe_cast();
> + if self.virt_alloc.erase(vfn_index).is_none() {
> + kernel::pr_warn!("free_vfn: VFN {} not found in maple tree\n", vfn_index);
> + }
> + }
Ick! I think this should be done with a guard type, e.g.
struct AllocatedVfnRange<'a> {
vfn_start: Vfn,
virt_alloc: &'a MapleTreeAlloc<()>,
}
Now, I get that this isn't done because the whole Vmm is within a Mutex and
hence it would tie its lifetime to the MutexGuard.
But, Vmm shouldn't be embedded in a Mutex in the first place, as it defeats the
whole purpose of having the prepare_map() and execute_map() split.
Requiring the same lock for execute_map() as for prepare_map() will pull a
memory reclaim path into the DMA fence signaling critical path.