Skip to content

Commit 4239930

Browse files
lsgunthChristoph Hellwig
authored andcommitted
lib/scatterlist: add flag for indicating P2PDMA segments in an SGL
Introduce a dma_flags field in struct scatterlist. These flags will be used by dma_[un]map_sg_p2pdma() to determine when a given SGL segments dma_address points to a PCI bus address. dma_unmap_sg_p2pdma() will need to perform different cleanup when a segment is marked as a bus address. The dma_flags field will fit in the existing padding on 64BIT systems (assuming CONFIG_NEED_SG_DMA_LENGTH is also set). The new bit will only be used when CONFIG_PCI_P2PDMA is set; this means PCI P2PDMA will require CONFIG_64BIT. This should be acceptable as the majority of P2PDMA use cases are restricted to newer root complexes and roughly require the extra address space for memory BARs used in the transactions. Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 7231180 commit 4239930

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

drivers/pci/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ config PCI_PASID
164164
config PCI_P2PDMA
165165
bool "PCI peer-to-peer transfer support"
166166
depends on ZONE_DEVICE
167+
#
168+
# The need for the scatterlist DMA bus address flag means PCI P2PDMA
169+
# requires 64bit
170+
#
171+
depends on 64BIT
167172
select GENERIC_ALLOCATOR
168173
help
169174
Enableѕ drivers to do PCI peer-to-peer transactions to and from

include/linux/scatterlist.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ struct scatterlist {
1616
#ifdef CONFIG_NEED_SG_DMA_LENGTH
1717
unsigned int dma_length;
1818
#endif
19+
#ifdef CONFIG_PCI_P2PDMA
20+
unsigned int dma_flags;
21+
#endif
1922
};
2023

2124
/*
@@ -245,6 +248,72 @@ static inline void sg_unmark_end(struct scatterlist *sg)
245248
sg->page_link &= ~SG_END;
246249
}
247250

251+
/*
252+
* CONFGI_PCI_P2PDMA depends on CONFIG_64BIT which means there is 4 bytes
253+
* in struct scatterlist (assuming also CONFIG_NEED_SG_DMA_LENGTH is set).
254+
* Use this padding for DMA flags bits to indicate when a specific
255+
* dma address is a bus address.
256+
*/
257+
#ifdef CONFIG_PCI_P2PDMA
258+
259+
#define SG_DMA_BUS_ADDRESS (1 << 0)
260+
261+
/**
262+
* sg_dma_is_bus address - Return whether a given segment was marked
263+
* as a bus address
264+
* @sg: SG entry
265+
*
266+
* Description:
267+
* Returns true if sg_dma_mark_bus_address() has been called on
268+
* this segment.
269+
**/
270+
static inline bool sg_is_dma_bus_address(struct scatterlist *sg)
271+
{
272+
return sg->dma_flags & SG_DMA_BUS_ADDRESS;
273+
}
274+
275+
/**
276+
* sg_dma_mark_bus address - Mark the scatterlist entry as a bus address
277+
* @sg: SG entry
278+
*
279+
* Description:
280+
* Marks the passed in sg entry to indicate that the dma_address is
281+
* a bus address and doesn't need to be unmapped. This should only be
282+
* used by dma_map_sg() implementations to mark bus addresses
283+
* so they can be properly cleaned up in dma_unmap_sg().
284+
**/
285+
static inline void sg_dma_mark_bus_address(struct scatterlist *sg)
286+
{
287+
sg->dma_flags |= SG_DMA_BUS_ADDRESS;
288+
}
289+
290+
/**
291+
* sg_unmark_bus_address - Unmark the scatterlist entry as a bus address
292+
* @sg: SG entry
293+
*
294+
* Description:
295+
* Clears the bus address mark.
296+
**/
297+
static inline void sg_dma_unmark_bus_address(struct scatterlist *sg)
298+
{
299+
sg->dma_flags &= ~SG_DMA_BUS_ADDRESS;
300+
}
301+
302+
#else
303+
304+
static inline bool sg_is_dma_bus_address(struct scatterlist *sg)
305+
{
306+
return false;
307+
}
308+
static inline void sg_dma_mark_bus_address(struct scatterlist *sg)
309+
{
310+
}
311+
static inline void sg_dma_unmark_bus_address(struct scatterlist *sg)
312+
{
313+
}
314+
315+
#endif
316+
248317
/**
249318
* sg_phys - Return physical address of an sg entry
250319
* @sg: SG entry

0 commit comments

Comments
 (0)