On Thu, Apr 24, 2025 at 03:19:00PM -0400, Joel Fernandes wrote: > On Wed, Apr 23, 2025 at 05:02:58PM +0200, Danilo Krummrich wrote: > > [..] > > > > >> + data.extend_with(len, 0, GFP_KERNEL)?; > > > >> + with_bar!(?bar0, |bar0_ref| { > > > >> + let dst = &mut data[current_len..current_len + len]; > > > >> + for (idx, chunk) in dst > > > >> + .chunks_exact_mut(core::mem::size_of::<u32>()) > > > >> + .enumerate() > > > >> + { > > > >> + let addr = start + (idx * > > > >> core::mem::size_of::<u32>()); > > > >> + // Convert the u32 to a 4 byte array. We use the > > > >> .to_ne_bytes() > > > >> + // method out of convenience to convert the 32-bit > > > >> integer as it > > > >> + // is in memory into a byte array without any > > > >> endianness > > > >> + // conversion or byte-swapping. > > > >> + > > > >> chunk.copy_from_slice(&bar0_ref.try_read32(addr)?.to_ne_bytes()); > > > >> + } > > > >> + Ok(()) > > > >> + })?; > > > >> + > > > >> + Ok(()) > > > >> + } > > > ..actually initially was: > > > > > > + with_bar!(self.bar0, |bar0| { > > > + // Get current length > > > + let current_len = self.data.len(); > > > + > > > + // Read ROM data bytes push directly to vector > > > + for i in 0..bytes as usize { > > > + // Read byte from the VBIOS ROM and push it to the data > > > vector > > > + let rom_addr = ROM_OFFSET + current_len + i; > > > + let byte = bar0.try_readb(rom_addr)?; > > > + self.data.push(byte, GFP_KERNEL)?; > > > > > > Where this bit could result in a lot of allocation. > > > > > > There was an unsafe() way of not having to do this but we settled with > > > extends_with(). > > > > > > Thoughts? > > > > If I understand you correctly, you just want to make sure that subsequent > > push() > > calls don't re-allocate? If so, you can just use reserve() [1] and keep the > > subsequent push() calls. > > > > [1] > > https://rust.docs.kernel.org/kernel/alloc/kvec/struct.Vec.html#method.reserve > > > > Ok that does turn out to be cleaner! I replaced it with the following and it > works. > > Let me know if it looks good now? Here's a preview: > > - data.extend_with(len, 0, GFP_KERNEL)?; > + data.reserve(len, GFP_KERNEL)?; > + > with_bar_res!(bar0, |bar0_ref| { > - let dst = &mut data[current_len..current_len + len]; > - for (idx, chunk) in dst > - .chunks_exact_mut(core::mem::size_of::<u32>()) > - .enumerate() > - { > - let addr = start + (idx * core::mem::size_of::<u32>()); > - // Convert the u32 to a 4 byte array. We use the > .to_ne_bytes() > - // method out of convenience to convert the 32-bit integer > as it > - // is in memory into a byte array without any endianness > - // conversion or byte-swapping. > - > chunk.copy_from_slice(&bar0_ref.try_read32(addr)?.to_ne_bytes()); > + // Read ROM data bytes and push directly to vector > + for i in 0..len { > + // Read 32-bit word from the VBIOS ROM > + let rom_addr = start + i * core::mem::size_of::<u32>(); > + let word = bar0_ref.try_read32(rom_addr)?; > + > + // Convert the u32 to a 4 byte array and push each byte > + word.to_ne_bytes().iter().try_for_each(|&b| data.push(b, > GFP_KERNEL))?; > }
Looks good to me, thanks!