Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: dma: add from-slice constructors for Coherent and CoherentBox

A very common pattern is to create a block of coherent memory with the
content of an already-existing slice of bytes (e.g. a loaded firmware
blob).

`CoherentBox` makes this easier, but still implies a potentially
panicking operation with `copy_from_slice` that requires a `PANIC`
comment.

Add `from_slice_with_attrs` and `from_slice` methods to both `Coherent`
and `CoherentBox` to turn this into a trivial one-step operation.

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260327-b4-nova-dma-removal-v2-1-616e1d0b5cb3@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>

+107
+107
rust/kernel/dma.rs
··· 453 453 454 454 Ok(()) 455 455 } 456 + 457 + /// Allocates a region of coherent memory of the same size as `data` and initializes it with a 458 + /// copy of its contents. 459 + /// 460 + /// This is the [`CoherentBox`] variant of [`Coherent::from_slice_with_attrs`]. 461 + /// 462 + /// # Examples 463 + /// 464 + /// ``` 465 + /// use core::ops::Deref; 466 + /// 467 + /// # use kernel::device::{Bound, Device}; 468 + /// use kernel::dma::{ 469 + /// attrs::*, 470 + /// CoherentBox 471 + /// }; 472 + /// 473 + /// # fn test(dev: &Device<Bound>) -> Result { 474 + /// let data = [0u8, 1u8, 2u8, 3u8]; 475 + /// let c: CoherentBox<[u8]> = 476 + /// CoherentBox::from_slice_with_attrs(dev, &data, GFP_KERNEL, DMA_ATTR_NO_WARN)?; 477 + /// 478 + /// assert_eq!(c.deref(), &data); 479 + /// # Ok::<(), Error>(()) } 480 + /// ``` 481 + pub fn from_slice_with_attrs( 482 + dev: &device::Device<Bound>, 483 + data: &[T], 484 + gfp_flags: kernel::alloc::Flags, 485 + dma_attrs: Attrs, 486 + ) -> Result<Self> 487 + where 488 + T: Copy, 489 + { 490 + let mut slice = Self(Coherent::<T>::alloc_slice_with_attrs( 491 + dev, 492 + data.len(), 493 + gfp_flags, 494 + dma_attrs, 495 + )?); 496 + 497 + // PANIC: `slice` was created with length `data.len()`. 498 + slice.copy_from_slice(data); 499 + 500 + Ok(slice) 501 + } 502 + 503 + /// Performs the same functionality as [`CoherentBox::from_slice_with_attrs`], except the 504 + /// `dma_attrs` is 0 by default. 505 + #[inline] 506 + pub fn from_slice( 507 + dev: &device::Device<Bound>, 508 + data: &[T], 509 + gfp_flags: kernel::alloc::Flags, 510 + ) -> Result<Self> 511 + where 512 + T: Copy, 513 + { 514 + Self::from_slice_with_attrs(dev, data, gfp_flags, Attrs(0)) 515 + } 456 516 } 457 517 458 518 impl<T: AsBytes + FromBytes> CoherentBox<T> { ··· 898 838 gfp_flags: kernel::alloc::Flags, 899 839 ) -> Result<Coherent<[T]>> { 900 840 Self::zeroed_slice_with_attrs(dev, len, gfp_flags, Attrs(0)) 841 + } 842 + 843 + /// Allocates a region of coherent memory of the same size as `data` and initializes it with a 844 + /// copy of its contents. 845 + /// 846 + /// # Examples 847 + /// 848 + /// ``` 849 + /// # use kernel::device::{Bound, Device}; 850 + /// use kernel::dma::{ 851 + /// attrs::*, 852 + /// Coherent 853 + /// }; 854 + /// 855 + /// # fn test(dev: &Device<Bound>) -> Result { 856 + /// let data = [0u8, 1u8, 2u8, 3u8]; 857 + /// // `c` has the same content as `data`. 858 + /// let c: Coherent<[u8]> = 859 + /// Coherent::from_slice_with_attrs(dev, &data, GFP_KERNEL, DMA_ATTR_NO_WARN)?; 860 + /// 861 + /// # Ok::<(), Error>(()) } 862 + /// ``` 863 + #[inline] 864 + pub fn from_slice_with_attrs( 865 + dev: &device::Device<Bound>, 866 + data: &[T], 867 + gfp_flags: kernel::alloc::Flags, 868 + dma_attrs: Attrs, 869 + ) -> Result<Coherent<[T]>> 870 + where 871 + T: Copy, 872 + { 873 + CoherentBox::from_slice_with_attrs(dev, data, gfp_flags, dma_attrs).map(Into::into) 874 + } 875 + 876 + /// Performs the same functionality as [`Coherent::from_slice_with_attrs`], except the 877 + /// `dma_attrs` is 0 by default. 878 + #[inline] 879 + pub fn from_slice( 880 + dev: &device::Device<Bound>, 881 + data: &[T], 882 + gfp_flags: kernel::alloc::Flags, 883 + ) -> Result<Coherent<[T]>> 884 + where 885 + T: Copy, 886 + { 887 + Self::from_slice_with_attrs(dev, data, gfp_flags, Attrs(0)) 901 888 } 902 889 } 903 890