public inbox for rust-for-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: gary@garyguo.net
To: Danilo Krummrich <dakr@kernel.org>
Cc: "Tim Kovalenko via B4 Relay"
	<devnull+tim.kovalenko.proton.me@kernel.org>,
	tim.kovalenko@proton.me,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org
Subject: Re: [PATCH v2] gpu: nova-core: fix stack overflow in GSP memory allocation
Date: Fri, 13 Feb 2026 23:50:34 +0000	[thread overview]
Message-ID: <e6df0b7ebd86d0c84ffd4b15cee15716@garyguo.net> (raw)
In-Reply-To: <DGE5NO2W48YJ.34YKFNI6VS63A@kernel.org>

(Sorry Danilo, resending as I didn't hit "Reply All". I was travelling 
and not on my usual email setup).

On 2026-02-13 21:34, Danilo Krummrich wrote:
> On Fri Feb 13, 2026 at 8:40 PM CET, Tim Kovalenko via B4 Relay wrote:
>> @@ -159,7 +158,7 @@ struct Msgq {
>>  #[repr(C)]
>>  struct GspMem {
>>      /// Self-mapping page table entries.
>> -    ptes: PteArray<{ GSP_PAGE_SIZE / size_of::<u64>() }>,
>> +    ptes: [u64; GSP_PAGE_SIZE / size_of::<u64>()],
>>      /// CPU queue: the driver writes commands here, and the GSP reads 
>> them. It also contains the
>>      /// write and read pointers that the CPU updates.
>>      ///
>> @@ -201,7 +200,29 @@ fn new(dev: &device::Device<device::Bound>) -> 
>> Result<Self> {
>> 
>>          let gsp_mem =
>>              CoherentAllocation::<GspMem>::alloc_coherent(dev, 1, 
>> GFP_KERNEL | __GFP_ZERO)?;
>> -        dma_write!(gsp_mem[0].ptes = 
>> PteArray::new(gsp_mem.dma_handle())?)?;
>> +        const NUM_PAGES: usize = GSP_PAGE_SIZE / size_of::<u64>();
>> +
>> +        // One by one GSP Page write to the memory to avoid stack 
>> overflow when allocating
>> +        // the whole array at once.
>> +        let item = gsp_mem.item_from_index(0)?;
>> +        for i in 0..NUM_PAGES {
>> +            let pte_value = gsp_mem
>> +                .dma_handle()
>> +                .checked_add(num::usize_as_u64(i) << GSP_PAGE_SHIFT)
>> +                .ok_or(EOVERFLOW)?;
>> +
>> +            // SAFETY: `item_from_index` ensures that `item` is 
>> always a valid pointer and can be
>> +            // dereferenced. The compiler also further validates the 
>> expression on whether `field`
>> +            // is a member of `item` when expanded by the macro.
>> +            //
>> +            // Further, this is dma_write! macro expanded and 
>> modified to allow for individual
>> +            // page write.
>> +            unsafe {
> 
> Both of the statements below are unsafe and should be within an 
> individual
> unsafe block with their corresponding justification.
> 
>> +                let ptr_field = 
>> core::ptr::addr_of_mut!((*item).ptes[i]);
> 
> This should use &raw mut instead.
> 
>> +                gsp_mem.field_write(ptr_field, pte_value);
> 
> Formally, we won't be able to justify the safety requirement of this 
> method. :)
> 
> The good thing is, we don't have to:
> 
> I understand it seems like the problem here is that dma_read!() does 
> not support
> index projections. Well, it actually is a problem, which I think will 
> be
> resolved by Gary's work. However, I think the real problem here is a 
> different
> one:

Yes, this will be fixed. In fact, I've already got a working version. If 
you prefer,
I can send out a version with just improved projections without all the 
generic I/O
improvement stuff.

> 
> This code does not need volatile writes in the first place. We just 
> allocated
> the DMA memory and haven't published the corresponding address to the 
> device
> yet.
> 
> So, for such initialization code we shouldn't have to use dma_write!() 
> /
> dma_read!() in the first place.
> 
> I think the proper solution for this is to provide an API that allows 
> for
> initialization with a "normal" reference / slice.
> 
> For instance, we could provide a `alloc_coherent_init()` function that 
> takes a
> closure which has `&mut [T]` argument, such that the closure can do the
> initialization before dma::CoherentAllocation::alloc_coherent() even 
> returns.

I've already suggested that in
ttps://rust-for-linux.zulipchat.com/#narrow/channel/509436-Nova/topic/.60Cmdq.3A.3Anew.60.20uses.20excessive.20stack.20size/near/570456463.
The issue is that however the PTE array needs the actual DMA address to 
initialize,
which Alex and I feel that we shouldn't provide to the initializer when
`dma::CoherentAllocation` is not yet constructed.

Best,
Gary

> 
> Another option would be a new type, e.g. dma::InitCoherentAllocation 
> which has
> safe as_slice() and as_slice_mut() methods, but does *not* provide a 
> method to
> get the DMA address. Subsequently, it can be converted to a "real"
> dma::CoherentAllocation.
> 
> With this, I would also keep the PteArray type and change 
> PteArray::new() to
> PteArray::init() taking a &mut self.
> 
> This way the PteArray init logic remains nicely structured and 
> isolated.
> 
> Thanks,
> Danilo
> 
>> +            }
>> +        }
>> +
>>          dma_write!(gsp_mem[0].cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, 
>> RX_HDR_OFF, MSGQ_NUM_PAGES))?;
>>          dma_write!(gsp_mem[0].cpuq.rx = MsgqRxHeader::new())?;

  reply	other threads:[~2026-02-13 23:50 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-13 19:40 [PATCH v2] gpu: nova-core: fix stack overflow in GSP memory allocation Tim Kovalenko via B4 Relay
2026-02-13 21:34 ` Danilo Krummrich
2026-02-13 23:50   ` gary [this message]
2026-02-14  0:09     ` Danilo Krummrich
2026-02-14  0:18       ` Gary Guo
2026-02-14  0:29         ` Danilo Krummrich

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=e6df0b7ebd86d0c84ffd4b15cee15716@garyguo.net \
    --to=gary@garyguo.net \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=devnull+tim.kovalenko.proton.me@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tim.kovalenko@proton.me \
    --cc=tmgross@umich.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox