linux/rust/helpers/scatterlist.c
Danilo Krummrich 05aa6fb1c2 rust: scatterlist: Add abstraction for sg_table
Add a safe Rust abstraction for the kernel's scatter-gather list
facilities (`struct scatterlist` and `struct sg_table`).

This commit introduces `SGTable<T>`, a wrapper that uses a generic
parameter to provide compile-time guarantees about ownership and lifetime.

The abstraction provides two primary states:
- `SGTable<Owned<P>>`: Represents a table whose resources are fully
  managed by Rust. It takes ownership of a page provider `P`, allocates
  the underlying `struct sg_table`, maps it for DMA, and handles all
  cleanup automatically upon drop. The DMA mapping's lifetime is tied to
  the associated device using `Devres`, ensuring it is correctly unmapped
  before the device is unbound.
- `SGTable<Borrowed>` (or just `SGTable`): A zero-cost representation of
  an externally managed `struct sg_table`. It is created from a raw
  pointer using `SGTable::from_raw()` and provides a lifetime-bound
  reference (`&'a SGTable`) for operations like iteration.

The API exposes a safe iterator that yields `&SGEntry` references,
allowing drivers to easily access the DMA address and length of each
segment in the list.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Co-developed-by: Abdiel Janulgue <abdiel.janulgue@gmail.com>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@gmail.com>
Link: https://lore.kernel.org/r/20250828133323.53311-4-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-09-04 23:33:50 +02:00

24 lines
532 B
C

// SPDX-License-Identifier: GPL-2.0
#include <linux/dma-direction.h>
dma_addr_t rust_helper_sg_dma_address(struct scatterlist *sg)
{
return sg_dma_address(sg);
}
unsigned int rust_helper_sg_dma_len(struct scatterlist *sg)
{
return sg_dma_len(sg);
}
struct scatterlist *rust_helper_sg_next(struct scatterlist *sg)
{
return sg_next(sg);
}
void rust_helper_dma_unmap_sgtable(struct device *dev, struct sg_table *sgt,
enum dma_data_direction dir, unsigned long attrs)
{
return dma_unmap_sgtable(dev, sgt, dir, attrs);
}