On 2/3/2026 10:55 PM, Dave Airlie wrote:
>> +///
>> +/// These flags control the allocation behavior of the buddy allocator.
>> +#[derive(Clone, Copy, Default, PartialEq, Eq)]
>> +pub struct BuddyFlags(usize);
>> +
>> +impl BuddyFlags {
>> +    /// Range-based allocation from start to end addresses.
>> +    pub const RANGE_ALLOCATION: usize = 
>> bindings::GPU_BUDDY_RANGE_ALLOCATION;
>> +
>> +    /// Allocate from top of address space downward.
>> +    pub const TOPDOWN_ALLOCATION: usize = 
>> bindings::GPU_BUDDY_TOPDOWN_ALLOCATION;
>> +
>> +    /// Allocate physically contiguous blocks.
>> +    pub const CONTIGUOUS_ALLOCATION: usize = 
>> bindings::GPU_BUDDY_CONTIGUOUS_ALLOCATION;
>> +
>> +    /// Request allocation from the cleared (zeroed) memory. The zero'ing 
>> is not
>> +    /// done by the allocator, but by the caller before freeing old blocks.
>> +    pub const CLEAR_ALLOCATION: usize = 
>> bindings::GPU_BUDDY_CLEAR_ALLOCATION;
>> +
>> +    /// Disable trimming of partially used blocks.
>> +    pub const TRIM_DISABLE: usize = bindings::GPU_BUDDY_TRIM_DISABLE;
>> +
>> +    /// Mark blocks as cleared (zeroed) when freeing. When set during free,
>> +    /// indicates that the caller has already zeroed the memory.
>> +    pub const CLEARED: usize = bindings::GPU_BUDDY_CLEARED;
>> +
>> +    /// Create [`BuddyFlags`] from a raw value with validation.
>> +    ///
>> +    /// Use `|` operator to combine flags if needed, before calling this 
>> method.
>> +    pub fn try_new(flags: usize) -> Result<Self> {
>> +        // Flags must not exceed u32::MAX to satisfy the GPU buddy 
>> allocator C API.
>> +        if flags > u32::MAX as usize {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        // `TOPDOWN_ALLOCATION` only works without `RANGE_ALLOCATION`. When 
>> both are
>> +        // set, `TOPDOWN_ALLOCATION` is silently ignored by the allocator. 
>> Reject this.
>> +        if (flags & Self::RANGE_ALLOCATION) != 0 && (flags & 
>> Self::TOPDOWN_ALLOCATION) != 0 {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        Ok(Self(flags))
>> +    }
>> +
>> +    /// Get raw value of the flags.
>> +    pub(crate) fn as_raw(self) -> usize {
>> +        self.0
>> +    }
>> +}
>> +
>> +/// Parameters for creating a GPU buddy allocator.
>> +#[derive(Clone, Copy)]
>> +pub struct GpuBuddyParams {
>> +    /// Base offset in bytes where the managed memory region starts.
>> +    /// Allocations will be offset by this value.
>> +    pub base_offset_bytes: u64,
>> +    /// Total physical memory size managed by the allocator in bytes.
>> +    pub physical_memory_size_bytes: u64,
>> +    /// Minimum allocation unit / chunk size in bytes, must be >= 4KB.
>> +    pub chunk_size_bytes: u64,
>> +}
>> +
>> +/// Parameters for allocating blocks from a GPU buddy allocator.
>> +#[derive(Clone, Copy)]
>> +pub struct GpuBuddyAllocParams {
>> +    /// Start of allocation range in bytes. Use 0 for beginning.
>> +    pub start_range_address: u64,
>> +    /// End of allocation range in bytes. Use 0 for entire range.
>> +    pub end_range_address: u64,
>> +    /// Total size to allocate in bytes.
>> +    pub size_bytes: u64,
>> +    /// Minimum block size for fragmented allocations in bytes.
>> +    pub min_block_size_bytes: u64,
>> +    /// Buddy allocator behavior flags.
>> +    pub buddy_flags: BuddyFlags,
>> +}
>> +
> 
> (not a full review)
> 
> Any reason these two need Clone, Copy? I'm not seeing a use case for
> that, maybe we should pass them as non-mutable references, but I don't
> think there is any point in passing them by value ever.
Yes, one reason I did that is because the doctests reuse the same params. But I
could also just pass by reference as you suggest. It might remove some mem
copies in the doctests. I will make this change then, thanks!

--
Joel Fernandes

Reply via email to