From: "Danilo Krummrich" <dakr@kernel.org>
To: "Joel Fernandes" <joelagnelf@nvidia.com>
Cc: linux-kernel@vger.kernel.org,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Jonathan Corbet" <corbet@lwn.net>,
"Alex Deucher" <alexander.deucher@amd.com>,
"Christian König" <christian.koenig@amd.com>,
"Jani Nikula" <jani.nikula@linux.intel.com>,
"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
"Tvrtko Ursulin" <tursulin@ursulin.net>,
"Huang Rui" <ray.huang@amd.com>,
"Matthew Auld" <matthew.auld@intel.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Lucas De Marchi" <lucas.demarchi@intel.com>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Helge Deller" <deller@gmx.de>,
"Alice Ryhl" <aliceryhl@google.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"John Hubbard" <jhubbard@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Timur Tabi" <ttabi@nvidia.com>, "Edwin Peer" <epeer@nvidia.com>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Andrea Righi" <arighi@nvidia.com>,
"Andy Ritger" <aritger@nvidia.com>, "Zhi Wang" <zhiw@nvidia.com>,
"Balbir Singh" <balbirs@nvidia.com>,
"Philipp Stanner" <phasta@kernel.org>,
"Elle Rhumsaa" <elle@weathered-steel.dev>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
joel@joelfernandes.org, nouveau@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
linux-doc@vger.kernel.org, amd-gfx@lists.freedesktop.org,
intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
linux-fbdev@vger.kernel.org
Subject: Re: [PATCH -next v8 2/3] rust: gpu: Add GPU buddy allocator bindings
Date: Tue, 10 Feb 2026 12:55:01 +0100 [thread overview]
Message-ID: <DGB9G697GSWO.3VBFGU5MKFPMR@kernel.org> (raw)
In-Reply-To: <20260209214246.2783990-3-joelagnelf@nvidia.com>
On Mon Feb 9, 2026 at 10:42 PM CET, Joel Fernandes wrote:
[...]
> +//! params.size_bytes = SZ_8M as u64;
It looks there are ~30 occurences of `as u64` in this example code, which seems
quite inconvinient for drivers.
In nova-core I proposed to have FromSafeCast / IntoSafeCast for usize, u32 and
u64, which would help here as well, once factored out.
But even this seems pretty annoying. I wonder if we should just have separate
64-bit size constants, as they'd be pretty useful in other places as well, e.g.
GPUVM.
> +/// Inner structure holding the actual buddy allocator.
> +///
> +/// # Synchronization
> +///
> +/// The C `gpu_buddy` API requires synchronization (see `include/linux/gpu_buddy.h`).
> +/// The internal [`GpuBuddyGuard`] ensures that the lock is held for all
> +/// allocator and free operations, preventing races between concurrent allocations
> +/// and the freeing that occurs when [`AllocatedBlocks`] is dropped.
> +///
> +/// # Invariants
> +///
> +/// The inner [`Opaque`] contains a valid, initialized buddy allocator.
> +#[pin_data(PinnedDrop)]
> +struct GpuBuddyInner {
> + #[pin]
> + inner: Opaque<bindings::gpu_buddy>,
> + #[pin]
> + lock: Mutex<()>,
Why don't we have the mutex around the Opaque<bindings::gpu_buddy>? It's the
only field the mutex does protect.
Is it because mutex does not take an impl PinInit? If so, we should add a
comment with a proper TODO.
> + /// Base offset for all allocations (does not change after init).
> + base_offset: u64,
> + /// Cached chunk size (does not change after init).
> + chunk_size: u64,
> + /// Cached total size (does not change after init).
> + size: u64,
> +}
> +
> +impl GpuBuddyInner {
> + /// Create a pin-initializer for the buddy allocator.
> + fn new(params: &GpuBuddyParams) -> impl PinInit<Self, Error> {
I think we can just pass them by value, they shouldn't be needed anymore after
the GpuBuddy instance has been constructed.
> + let base_offset = params.base_offset_bytes;
> + let size = params.physical_memory_size_bytes;
> + let chunk_size = params.chunk_size_bytes;
> +
> + try_pin_init!(Self {
> + inner <- Opaque::try_ffi_init(|ptr| {
> + // SAFETY: ptr points to valid uninitialized memory from the pin-init
> + // infrastructure. gpu_buddy_init will initialize the structure.
> + to_result(unsafe { bindings::gpu_buddy_init(ptr, size, chunk_size) })
> + }),
> + lock <- new_mutex!(()),
> + base_offset: base_offset,
> + chunk_size: chunk_size,
> + size: size,
> + })
> + }
<snip>
> +/// GPU buddy allocator instance.
> +///
> +/// This structure wraps the C `gpu_buddy` allocator using reference counting.
> +/// The allocator is automatically cleaned up when all references are dropped.
> +///
> +/// # Invariants
> +///
> +/// The inner [`Arc`] points to a valid, initialized GPU buddy allocator.
> +pub struct GpuBuddy(Arc<GpuBuddyInner>);
> +
> +impl GpuBuddy {
> + /// Create a new buddy allocator.
> + ///
> + /// Creates a buddy allocator that manages a contiguous address space of the given
> + /// size, with the specified minimum allocation unit (chunk_size must be at least 4KB).
> + pub fn new(params: &GpuBuddyParams) -> Result<Self> {
Same here, we should be able to take this by value.
> + Ok(Self(Arc::pin_init(
> + GpuBuddyInner::new(params),
> + GFP_KERNEL,
> + )?))
> + }
<snip>
> + /// Allocate blocks from the buddy allocator.
> + ///
> + /// Returns an [`Arc<AllocatedBlocks>`] structure that owns the allocated blocks
> + /// and automatically frees them when all references are dropped.
> + ///
> + /// Takes `&self` instead of `&mut self` because the internal [`Mutex`] provides
> + /// synchronization - no external `&mut` exclusivity needed.
> + pub fn alloc_blocks(&self, params: &GpuBuddyAllocParams) -> Result<Arc<AllocatedBlocks>> {
Why do we force a reference count here? I think we should just return
impl PinInit<AllocatedBlocks, Error> and let the driver decide where to
initialize the object, no?
I.e. what if the driver wants to store additional data in a driver private
structure? Then we'd need two allocations otherwise and another reference count
in the worst case.
> + let buddy_arc = Arc::clone(&self.0);
> +
> + // Create pin-initializer that initializes list and allocates blocks.
> + let init = try_pin_init!(AllocatedBlocks {
> + buddy: Arc::clone(&buddy_arc),
> + list <- CListHead::new(),
> + flags: params.buddy_flags,
> + _: {
> + // Lock while allocating to serialize with concurrent frees.
> + let guard = buddy.lock();
> +
> + // SAFETY: `guard` provides exclusive access to the buddy allocator.
> + to_result(unsafe {
> + bindings::gpu_buddy_alloc_blocks(
> + guard.as_raw(),
> + params.start_range_address,
> + params.end_range_address,
> + params.size_bytes,
> + params.min_block_size_bytes,
> + list.as_raw(),
> + params.buddy_flags.as_raw(),
> + )
> + })?
> + }
> + });
> +
> + Arc::pin_init(init, GFP_KERNEL)
> + }
> +}
WARNING: multiple messages have this Message-ID (diff)
From: "Danilo Krummrich" <dakr@kernel.org>
To: "Joel Fernandes" <joelagnelf@nvidia.com>
Cc: linux-kernel@vger.kernel.org,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Simona Vetter" <simona@ffwll.ch>,
"Jonathan Corbet" <corbet@lwn.net>,
"Alex Deucher" <alexander.deucher@amd.com>,
"Christian König" <christian.koenig@amd.com>,
"Jani Nikula" <jani.nikula@linux.intel.com>,
"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
"Tvrtko Ursulin" <tursulin@ursulin.net>,
"Huang Rui" <ray.huang@amd.com>,
"Matthew Auld" <matthew.auld@intel.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Lucas De Marchi" <lucas.demarchi@intel.com>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Helge Deller" <deller@gmx.de>,
"Alice Ryhl" <aliceryhl@google.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Alistair Popple" <apopple@nvidia.com>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Andrea Righi" <arighi@nvidia.com>, "Zhi Wang" <zhiw@nvidia.com>,
"Philipp Stanner" <phasta@kernel.org>,
"Elle Rhumsaa" <elle@weathered-steel.dev>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
joel@joelfernandes.org, nouveau@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
linux-doc@vger.kernel.org, amd-gfx@lists.freedesktop.org,
intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
linux-fbdev@vger.kernel.org
Subject: Re: [PATCH -next v8 2/3] rust: gpu: Add GPU buddy allocator bindings
Date: Tue, 10 Feb 2026 12:55:01 +0100 [thread overview]
Message-ID: <DGB9G697GSWO.3VBFGU5MKFPMR@kernel.org> (raw)
In-Reply-To: <20260209214246.2783990-3-joelagnelf@nvidia.com>
On Mon Feb 9, 2026 at 10:42 PM CET, Joel Fernandes wrote:
[...]
> +//! params.size_bytes = SZ_8M as u64;
It looks there are ~30 occurences of `as u64` in this example code, which seems
quite inconvinient for drivers.
In nova-core I proposed to have FromSafeCast / IntoSafeCast for usize, u32 and
u64, which would help here as well, once factored out.
But even this seems pretty annoying. I wonder if we should just have separate
64-bit size constants, as they'd be pretty useful in other places as well, e.g.
GPUVM.
> +/// Inner structure holding the actual buddy allocator.
> +///
> +/// # Synchronization
> +///
> +/// The C `gpu_buddy` API requires synchronization (see `include/linux/gpu_buddy.h`).
> +/// The internal [`GpuBuddyGuard`] ensures that the lock is held for all
> +/// allocator and free operations, preventing races between concurrent allocations
> +/// and the freeing that occurs when [`AllocatedBlocks`] is dropped.
> +///
> +/// # Invariants
> +///
> +/// The inner [`Opaque`] contains a valid, initialized buddy allocator.
> +#[pin_data(PinnedDrop)]
> +struct GpuBuddyInner {
> + #[pin]
> + inner: Opaque<bindings::gpu_buddy>,
> + #[pin]
> + lock: Mutex<()>,
Why don't we have the mutex around the Opaque<bindings::gpu_buddy>? It's the
only field the mutex does protect.
Is it because mutex does not take an impl PinInit? If so, we should add a
comment with a proper TODO.
> + /// Base offset for all allocations (does not change after init).
> + base_offset: u64,
> + /// Cached chunk size (does not change after init).
> + chunk_size: u64,
> + /// Cached total size (does not change after init).
> + size: u64,
> +}
> +
> +impl GpuBuddyInner {
> + /// Create a pin-initializer for the buddy allocator.
> + fn new(params: &GpuBuddyParams) -> impl PinInit<Self, Error> {
I think we can just pass them by value, they shouldn't be needed anymore after
the GpuBuddy instance has been constructed.
> + let base_offset = params.base_offset_bytes;
> + let size = params.physical_memory_size_bytes;
> + let chunk_size = params.chunk_size_bytes;
> +
> + try_pin_init!(Self {
> + inner <- Opaque::try_ffi_init(|ptr| {
> + // SAFETY: ptr points to valid uninitialized memory from the pin-init
> + // infrastructure. gpu_buddy_init will initialize the structure.
> + to_result(unsafe { bindings::gpu_buddy_init(ptr, size, chunk_size) })
> + }),
> + lock <- new_mutex!(()),
> + base_offset: base_offset,
> + chunk_size: chunk_size,
> + size: size,
> + })
> + }
<snip>
> +/// GPU buddy allocator instance.
> +///
> +/// This structure wraps the C `gpu_buddy` allocator using reference counting.
> +/// The allocator is automatically cleaned up when all references are dropped.
> +///
> +/// # Invariants
> +///
> +/// The inner [`Arc`] points to a valid, initialized GPU buddy allocator.
> +pub struct GpuBuddy(Arc<GpuBuddyInner>);
> +
> +impl GpuBuddy {
> + /// Create a new buddy allocator.
> + ///
> + /// Creates a buddy allocator that manages a contiguous address space of the given
> + /// size, with the specified minimum allocation unit (chunk_size must be at least 4KB).
> + pub fn new(params: &GpuBuddyParams) -> Result<Self> {
Same here, we should be able to take this by value.
> + Ok(Self(Arc::pin_init(
> + GpuBuddyInner::new(params),
> + GFP_KERNEL,
> + )?))
> + }
<snip>
> + /// Allocate blocks from the buddy allocator.
> + ///
> + /// Returns an [`Arc<AllocatedBlocks>`] structure that owns the allocated blocks
> + /// and automatically frees them when all references are dropped.
> + ///
> + /// Takes `&self` instead of `&mut self` because the internal [`Mutex`] provides
> + /// synchronization - no external `&mut` exclusivity needed.
> + pub fn alloc_blocks(&self, params: &GpuBuddyAllocParams) -> Result<Arc<AllocatedBlocks>> {
Why do we force a reference count here? I think we should just return
impl PinInit<AllocatedBlocks, Error> and let the driver decide where to
initialize the object, no?
I.e. what if the driver wants to store additional data in a driver private
structure? Then we'd need two allocations otherwise and another reference count
in the worst case.
> + let buddy_arc = Arc::clone(&self.0);
> +
> + // Create pin-initializer that initializes list and allocates blocks.
> + let init = try_pin_init!(AllocatedBlocks {
> + buddy: Arc::clone(&buddy_arc),
> + list <- CListHead::new(),
> + flags: params.buddy_flags,
> + _: {
> + // Lock while allocating to serialize with concurrent frees.
> + let guard = buddy.lock();
> +
> + // SAFETY: `guard` provides exclusive access to the buddy allocator.
> + to_result(unsafe {
> + bindings::gpu_buddy_alloc_blocks(
> + guard.as_raw(),
> + params.start_range_address,
> + params.end_range_address,
> + params.size_bytes,
> + params.min_block_size_bytes,
> + list.as_raw(),
> + params.buddy_flags.as_raw(),
> + )
> + })?
> + }
> + });
> +
> + Arc::pin_init(init, GFP_KERNEL)
> + }
> +}
next prev parent reply other threads:[~2026-02-10 11:55 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-09 21:42 [PATCH -next v8 0/3] rust: Add CList and GPU buddy allocator bindings Joel Fernandes
2026-02-09 21:42 ` Joel Fernandes
2026-02-09 21:42 ` [PATCH -next v8 1/3] rust: clist: Add support to interface with C linked lists Joel Fernandes
2026-02-09 21:42 ` Joel Fernandes
2026-02-10 6:51 ` kernel test robot
2026-02-10 9:20 ` Miguel Ojeda
2026-02-10 10:07 ` Danilo Krummrich
2026-02-10 10:07 ` Danilo Krummrich
2026-02-11 21:09 ` Joel Fernandes
2026-02-11 21:17 ` Danilo Krummrich
2026-02-10 17:15 ` Daniel Almeida
2026-02-10 17:15 ` Daniel Almeida
2026-02-09 21:42 ` [PATCH -next v8 2/3] rust: gpu: Add GPU buddy allocator bindings Joel Fernandes
2026-02-09 21:42 ` Joel Fernandes
2026-02-10 7:25 ` kernel test robot
2026-02-10 11:55 ` Danilo Krummrich [this message]
2026-02-10 11:55 ` Danilo Krummrich
2026-02-10 20:09 ` Joel Fernandes
2026-02-10 20:09 ` Joel Fernandes
2026-02-10 21:10 ` Danilo Krummrich
2026-02-10 21:10 ` Danilo Krummrich
2026-02-10 21:43 ` Joel Fernandes
2026-02-10 21:43 ` Joel Fernandes
2026-02-10 22:06 ` Joel Fernandes
2026-02-10 22:06 ` Joel Fernandes
2026-02-10 23:23 ` Danilo Krummrich
2026-02-10 23:23 ` Danilo Krummrich
2026-02-10 23:33 ` Joel Fernandes
2026-02-10 23:33 ` Joel Fernandes
2026-02-10 12:12 ` kernel test robot
2026-02-09 21:42 ` [PATCH -next v8 3/3] nova-core: mm: Select GPU_BUDDY for VRAM allocation Joel Fernandes
2026-02-09 21:42 ` Joel Fernandes
2026-02-10 10:10 ` Danilo Krummrich
2026-02-10 10:10 ` Danilo Krummrich
2026-02-09 22:15 ` ✗ Fi.CI.BUILD: failure for rust: Add CList and GPU buddy allocator bindings (rev2) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DGB9G697GSWO.3VBFGU5MKFPMR@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=alexander.deucher@amd.com \
--cc=aliceryhl@google.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=apopple@nvidia.com \
--cc=arighi@nvidia.com \
--cc=aritger@nvidia.com \
--cc=balbirs@nvidia.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=christian.koenig@amd.com \
--cc=corbet@lwn.net \
--cc=daniel.almeida@collabora.com \
--cc=deller@gmx.de \
--cc=dri-devel@lists.freedesktop.org \
--cc=elle@weathered-steel.dev \
--cc=epeer@nvidia.com \
--cc=gary@garyguo.net \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=jhubbard@nvidia.com \
--cc=joel@joelfernandes.org \
--cc=joelagnelf@nvidia.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=lucas.demarchi@intel.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=matthew.auld@intel.com \
--cc=matthew.brost@intel.com \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=phasta@kernel.org \
--cc=ray.huang@amd.com \
--cc=rodrigo.vivi@intel.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=thomas.hellstrom@linux.intel.com \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=tursulin@ursulin.net \
--cc=tzimmermann@suse.de \
--cc=zhiw@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.