mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 23:53:55 +08:00
df05c6f6e0
This patch adds the DMA_ATTR_ALLOC_SINGLE_PAGES attribute to the DMA-mapping subsystem. This attribute can be used as a hint to the DMA-mapping subsystem that it's likely not worth it to try to allocate large pages behind the scenes. Large pages are likely to make an IOMMU TLB work more efficiently but may not be worth it. See the Documentation contained in this patch for more details about this attribute and when to use it. Note that the name of the hint (DMA_ATTR_ALLOC_SINGLE_PAGES) is loosely based on the name MADV_NOHUGEPAGE. Just as there is MADV_NOHUGEPAGE vs. MADV_HUGEPAGE we could also add an "opposite" attribute to DMA_ATTR_ALLOC_SINGLE_PAGES. Without having the "opposite" attribute the lack of DMA_ATTR_ALLOC_SINGLE_PAGES means "use your best judgement about whether to use small pages or large pages". Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Tested-by: Javier Martinez Canillas <javier@osg.samsung.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
72 lines
1.6 KiB
C
72 lines
1.6 KiB
C
#ifndef _DMA_ATTR_H
|
|
#define _DMA_ATTR_H
|
|
|
|
#include <linux/bitmap.h>
|
|
#include <linux/bitops.h>
|
|
#include <linux/bug.h>
|
|
|
|
/**
|
|
* an enum dma_attr represents an attribute associated with a DMA
|
|
* mapping. The semantics of each attribute should be defined in
|
|
* Documentation/DMA-attributes.txt.
|
|
*/
|
|
enum dma_attr {
|
|
DMA_ATTR_WRITE_BARRIER,
|
|
DMA_ATTR_WEAK_ORDERING,
|
|
DMA_ATTR_WRITE_COMBINE,
|
|
DMA_ATTR_NON_CONSISTENT,
|
|
DMA_ATTR_NO_KERNEL_MAPPING,
|
|
DMA_ATTR_SKIP_CPU_SYNC,
|
|
DMA_ATTR_FORCE_CONTIGUOUS,
|
|
DMA_ATTR_ALLOC_SINGLE_PAGES,
|
|
DMA_ATTR_MAX,
|
|
};
|
|
|
|
#define __DMA_ATTRS_LONGS BITS_TO_LONGS(DMA_ATTR_MAX)
|
|
|
|
/**
|
|
* struct dma_attrs - an opaque container for DMA attributes
|
|
* @flags - bitmask representing a collection of enum dma_attr
|
|
*/
|
|
struct dma_attrs {
|
|
unsigned long flags[__DMA_ATTRS_LONGS];
|
|
};
|
|
|
|
#define DEFINE_DMA_ATTRS(x) \
|
|
struct dma_attrs x = { \
|
|
.flags = { [0 ... __DMA_ATTRS_LONGS-1] = 0 }, \
|
|
}
|
|
|
|
static inline void init_dma_attrs(struct dma_attrs *attrs)
|
|
{
|
|
bitmap_zero(attrs->flags, __DMA_ATTRS_LONGS);
|
|
}
|
|
|
|
/**
|
|
* dma_set_attr - set a specific attribute
|
|
* @attr: attribute to set
|
|
* @attrs: struct dma_attrs (may be NULL)
|
|
*/
|
|
static inline void dma_set_attr(enum dma_attr attr, struct dma_attrs *attrs)
|
|
{
|
|
if (attrs == NULL)
|
|
return;
|
|
BUG_ON(attr >= DMA_ATTR_MAX);
|
|
__set_bit(attr, attrs->flags);
|
|
}
|
|
|
|
/**
|
|
* dma_get_attr - check for a specific attribute
|
|
* @attr: attribute to set
|
|
* @attrs: struct dma_attrs (may be NULL)
|
|
*/
|
|
static inline int dma_get_attr(enum dma_attr attr, struct dma_attrs *attrs)
|
|
{
|
|
if (attrs == NULL)
|
|
return 0;
|
|
BUG_ON(attr >= DMA_ATTR_MAX);
|
|
return test_bit(attr, attrs->flags);
|
|
}
|
|
|
|
#endif /* _DMA_ATTR_H */
|