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.

gpu: nova-core: convert to new dma::Coherent API

Remove all usages of dma::CoherentAllocation and use the new
dma::Coherent type instead.

Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260320194626.36263-9-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

authored by

Gary Guo and committed by
Danilo Krummrich
f343012e 7f3e836e

+47 -65
+9 -10
drivers/gpu/nova-core/dma.rs
··· 9 9 10 10 use kernel::{ 11 11 device, 12 - dma::CoherentAllocation, 12 + dma::Coherent, 13 13 page::PAGE_SIZE, 14 14 prelude::*, // 15 15 }; 16 16 17 17 pub(crate) struct DmaObject { 18 - dma: CoherentAllocation<u8>, 18 + dma: Coherent<[u8]>, 19 19 } 20 20 21 21 impl DmaObject { ··· 24 24 .map_err(|_| EINVAL)? 25 25 .pad_to_align() 26 26 .size(); 27 - let dma = CoherentAllocation::alloc_coherent(dev, len, GFP_KERNEL | __GFP_ZERO)?; 27 + let dma = Coherent::zeroed_slice(dev, len, GFP_KERNEL)?; 28 28 29 29 Ok(Self { dma }) 30 30 } 31 31 32 32 pub(crate) fn from_data(dev: &device::Device<device::Bound>, data: &[u8]) -> Result<Self> { 33 - Self::new(dev, data.len()).and_then(|mut dma_obj| { 34 - // SAFETY: We have just allocated the DMA memory, we are the only users and 35 - // we haven't made the device aware of the handle yet. 36 - unsafe { dma_obj.write(data, 0)? } 37 - Ok(dma_obj) 38 - }) 33 + let dma_obj = Self::new(dev, data.len())?; 34 + // SAFETY: We have just allocated the DMA memory, we are the only users and 35 + // we haven't made the device aware of the handle yet. 36 + unsafe { dma_obj.as_mut()[..data.len()].copy_from_slice(data) }; 37 + Ok(dma_obj) 39 38 } 40 39 } 41 40 42 41 impl Deref for DmaObject { 43 - type Target = CoherentAllocation<u8>; 42 + type Target = Coherent<[u8]>; 44 43 45 44 fn deref(&self) -> &Self::Target { 46 45 &self.dma
+2 -3
drivers/gpu/nova-core/falcon.rs
··· 26 26 gpu::Chipset, 27 27 num::{ 28 28 self, 29 - FromSafeCast, 30 - IntoSafeCast, // 29 + FromSafeCast, // 31 30 }, 32 31 regs, 33 32 regs::macros::RegisterBase, // ··· 652 653 } 653 654 FalconMem::Dmem => ( 654 655 0, 655 - dma_obj.dma_handle_with_offset(load_offsets.src_start.into_safe_cast())?, 656 + dma_obj.dma_handle() + DmaAddress::from(load_offsets.src_start), 656 657 ), 657 658 }; 658 659 if dma_start % DmaAddress::from(DMA_LEN) > 0 {
+12 -9
drivers/gpu/nova-core/gsp.rs
··· 6 6 device, 7 7 dma::{ 8 8 Coherent, 9 - CoherentAllocation, 10 9 CoherentBox, 11 10 DmaAddress, // 12 11 }, 13 12 pci, 14 13 prelude::*, 15 - transmute::AsBytes, // 14 + transmute::{ 15 + AsBytes, 16 + FromBytes, // 17 + }, // 16 18 }; 17 19 18 20 pub(crate) mod cmdq; ··· 46 44 #[repr(C)] 47 45 struct PteArray<const NUM_ENTRIES: usize>([u64; NUM_ENTRIES]); 48 46 47 + /// SAFETY: arrays of `u64` implement `FromBytes` and we are but a wrapper around one. 48 + unsafe impl<const NUM_ENTRIES: usize> FromBytes for PteArray<NUM_ENTRIES> {} 49 + 49 50 /// SAFETY: arrays of `u64` implement `AsBytes` and we are but a wrapper around one. 50 51 unsafe impl<const NUM_ENTRIES: usize> AsBytes for PteArray<NUM_ENTRIES> {} 51 52 ··· 76 71 /// then pp points to index into the buffer where the next logging entry will 77 72 /// be written. Therefore, the logging data is valid if: 78 73 /// 1 <= pp < sizeof(buffer)/sizeof(u64) 79 - struct LogBuffer(CoherentAllocation<u8>); 74 + struct LogBuffer(Coherent<[u8]>); 80 75 81 76 impl LogBuffer { 82 77 /// Creates a new `LogBuffer` mapped on `dev`. 83 78 fn new(dev: &device::Device<device::Bound>) -> Result<Self> { 84 79 const NUM_PAGES: usize = RM_LOG_BUFFER_NUM_PAGES; 85 80 86 - let mut obj = Self(CoherentAllocation::<u8>::alloc_coherent( 81 + let obj = Self(Coherent::<u8>::zeroed_slice( 87 82 dev, 88 83 NUM_PAGES * GSP_PAGE_SIZE, 89 - GFP_KERNEL | __GFP_ZERO, 84 + GFP_KERNEL, 90 85 )?); 91 86 92 87 let start_addr = obj.0.dma_handle(); 93 88 94 89 // SAFETY: `obj` has just been created and we are its sole user. 95 - let pte_region = unsafe { 96 - obj.0 97 - .as_slice_mut(size_of::<u64>(), NUM_PAGES * size_of::<u64>())? 98 - }; 90 + let pte_region = 91 + unsafe { &mut obj.0.as_mut()[size_of::<u64>()..][..NUM_PAGES * size_of::<u64>()] }; 99 92 100 93 // Write values one by one to avoid an on-stack instance of `PteArray`. 101 94 for (i, chunk) in pte_region.chunks_exact_mut(size_of::<u64>()).enumerate() {
+9 -12
drivers/gpu/nova-core/gsp/cmdq.rs
··· 7 7 use kernel::{ 8 8 device, 9 9 dma::{ 10 - CoherentAllocation, 10 + Coherent, 11 11 DmaAddress, // 12 12 }, 13 13 dma_write, ··· 207 207 // that is not a problem because they are not used outside the kernel. 208 208 unsafe impl FromBytes for GspMem {} 209 209 210 - /// Wrapper around [`GspMem`] to share it with the GPU using a [`CoherentAllocation`]. 210 + /// Wrapper around [`GspMem`] to share it with the GPU using a [`Coherent`]. 211 211 /// 212 212 /// This provides the low-level functionality to communicate with the GSP, including allocation of 213 213 /// queue space to write messages to and management of read/write pointers. ··· 218 218 /// pointer and the GSP read pointer. This region is returned by [`Self::driver_write_area`]. 219 219 /// * The driver owns (i.e. can read from) the part of the GSP message queue between the CPU read 220 220 /// pointer and the GSP write pointer. This region is returned by [`Self::driver_read_area`]. 221 - struct DmaGspMem(CoherentAllocation<GspMem>); 221 + struct DmaGspMem(Coherent<GspMem>); 222 222 223 223 impl DmaGspMem { 224 224 /// Allocate a new instance and map it for `dev`. ··· 226 226 const MSGQ_SIZE: u32 = num::usize_into_u32::<{ size_of::<Msgq>() }>(); 227 227 const RX_HDR_OFF: u32 = num::usize_into_u32::<{ mem::offset_of!(Msgq, rx) }>(); 228 228 229 - let gsp_mem = 230 - CoherentAllocation::<GspMem>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?; 229 + let gsp_mem = Coherent::<GspMem>::zeroed(dev, GFP_KERNEL)?; 231 230 232 231 let start = gsp_mem.dma_handle(); 233 232 // Write values one by one to avoid an on-stack instance of `PteArray`. 234 233 for i in 0..GspMem::PTE_ARRAY_SIZE { 235 - dma_write!(gsp_mem, [0]?.ptes.0[i], PteArray::<0>::entry(start, i)?); 234 + dma_write!(gsp_mem, .ptes.0[i], PteArray::<0>::entry(start, i)?); 236 235 } 237 236 238 237 dma_write!( 239 238 gsp_mem, 240 - [0]?.cpuq.tx, 239 + .cpuq.tx, 241 240 MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES) 242 241 ); 243 - dma_write!(gsp_mem, [0]?.cpuq.rx, MsgqRxHeader::new()); 242 + dma_write!(gsp_mem, .cpuq.rx, MsgqRxHeader::new()); 244 243 245 244 Ok(Self(gsp_mem)) 246 245 } ··· 254 255 let rx = self.gsp_read_ptr() as usize; 255 256 256 257 // SAFETY: 257 - // - The `CoherentAllocation` contains exactly one object. 258 258 // - We will only access the driver-owned part of the shared memory. 259 259 // - Per the safety statement of the function, no concurrent access will be performed. 260 - let gsp_mem = &mut unsafe { self.0.as_slice_mut(0, 1) }.unwrap()[0]; 260 + let gsp_mem = unsafe { &mut *self.0.as_mut() }; 261 261 // PANIC: per the invariant of `cpu_write_ptr`, `tx` is `< MSGQ_NUM_PAGES`. 262 262 let (before_tx, after_tx) = gsp_mem.cpuq.msgq.data.split_at_mut(tx); 263 263 ··· 307 309 let rx = self.cpu_read_ptr() as usize; 308 310 309 311 // SAFETY: 310 - // - The `CoherentAllocation` contains exactly one object. 311 312 // - We will only access the driver-owned part of the shared memory. 312 313 // - Per the safety statement of the function, no concurrent access will be performed. 313 - let gsp_mem = &unsafe { self.0.as_slice(0, 1) }.unwrap()[0]; 314 + let gsp_mem = unsafe { &*self.0.as_ptr() }; 314 315 let data = &gsp_mem.gspq.msgq.data; 315 316 316 317 // The area starting at `rx` and ending at `tx - 1` modulo MSGQ_NUM_PAGES, inclusive,
+15 -31
drivers/gpu/nova-core/gsp/fw.rs
··· 40 40 }, 41 41 }; 42 42 43 - // TODO: Replace with `IoView` projections once available; the `unwrap()` calls go away once we 44 - // switch to the new `dma::Coherent` API. 43 + // TODO: Replace with `IoView` projections once available. 45 44 pub(super) mod gsp_mem { 46 45 use core::sync::atomic::{ 47 46 fence, ··· 48 49 }; 49 50 50 51 use kernel::{ 51 - dma::CoherentAllocation, 52 + dma::Coherent, 52 53 dma_read, 53 - dma_write, 54 - prelude::*, // 54 + dma_write, // 55 55 }; 56 56 57 57 use crate::gsp::cmdq::{ ··· 58 60 MSGQ_NUM_PAGES, // 59 61 }; 60 62 61 - pub(in crate::gsp) fn gsp_write_ptr(qs: &CoherentAllocation<GspMem>) -> u32 { 62 - // PANIC: A `dma::CoherentAllocation` always contains at least one element. 63 - || -> Result<u32> { Ok(dma_read!(qs, [0]?.gspq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap() 63 + pub(in crate::gsp) fn gsp_write_ptr(qs: &Coherent<GspMem>) -> u32 { 64 + dma_read!(qs, .gspq.tx.0.writePtr) % MSGQ_NUM_PAGES 64 65 } 65 66 66 - pub(in crate::gsp) fn gsp_read_ptr(qs: &CoherentAllocation<GspMem>) -> u32 { 67 - // PANIC: A `dma::CoherentAllocation` always contains at least one element. 68 - || -> Result<u32> { Ok(dma_read!(qs, [0]?.gspq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap() 67 + pub(in crate::gsp) fn gsp_read_ptr(qs: &Coherent<GspMem>) -> u32 { 68 + dma_read!(qs, .gspq.rx.0.readPtr) % MSGQ_NUM_PAGES 69 69 } 70 70 71 - pub(in crate::gsp) fn cpu_read_ptr(qs: &CoherentAllocation<GspMem>) -> u32 { 72 - // PANIC: A `dma::CoherentAllocation` always contains at least one element. 73 - || -> Result<u32> { Ok(dma_read!(qs, [0]?.cpuq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap() 71 + pub(in crate::gsp) fn cpu_read_ptr(qs: &Coherent<GspMem>) -> u32 { 72 + dma_read!(qs, .cpuq.rx.0.readPtr) % MSGQ_NUM_PAGES 74 73 } 75 74 76 - pub(in crate::gsp) fn advance_cpu_read_ptr(qs: &CoherentAllocation<GspMem>, count: u32) { 75 + pub(in crate::gsp) fn advance_cpu_read_ptr(qs: &Coherent<GspMem>, count: u32) { 77 76 let rptr = cpu_read_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES; 78 77 79 78 // Ensure read pointer is properly ordered. 80 79 fence(Ordering::SeqCst); 81 80 82 - // PANIC: A `dma::CoherentAllocation` always contains at least one element. 83 - || -> Result { 84 - dma_write!(qs, [0]?.cpuq.rx.0.readPtr, rptr); 85 - Ok(()) 86 - }() 87 - .unwrap() 81 + dma_write!(qs, .cpuq.rx.0.readPtr, rptr); 88 82 } 89 83 90 - pub(in crate::gsp) fn cpu_write_ptr(qs: &CoherentAllocation<GspMem>) -> u32 { 91 - // PANIC: A `dma::CoherentAllocation` always contains at least one element. 92 - || -> Result<u32> { Ok(dma_read!(qs, [0]?.cpuq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap() 84 + pub(in crate::gsp) fn cpu_write_ptr(qs: &Coherent<GspMem>) -> u32 { 85 + dma_read!(qs, .cpuq.tx.0.writePtr) % MSGQ_NUM_PAGES 93 86 } 94 87 95 - pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &CoherentAllocation<GspMem>, count: u32) { 88 + pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &Coherent<GspMem>, count: u32) { 96 89 let wptr = cpu_write_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES; 97 90 98 - // PANIC: A `dma::CoherentAllocation` always contains at least one element. 99 - || -> Result { 100 - dma_write!(qs, [0]?.cpuq.tx.0.writePtr, wptr); 101 - Ok(()) 102 - }() 103 - .unwrap(); 91 + dma_write!(qs, .cpuq.tx.0.writePtr, wptr); 104 92 105 93 // Ensure all command data is visible before triggering the GSP read. 106 94 fence(Ordering::SeqCst);