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.

Reply via email to