> +///
> +/// 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.
Dave.