dma-mapping updates for Linux 7.2:

- added more checks for DMA attributes in the debug code, especially
   to ensure that mappings are created and released with matching
   attributes (Leon Romanovsky)
 
 - better default configuration for CMA on NUMA machines (Feng Tang)
 
 - little code cleanup in dma benchmark tool (Rosen Penev)
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQSrngzkoBtlA8uaaJ+Jp1EFxbsSRAUCajESmAAKCRCJp1EFxbsS
 RKEuAQCpRF+ifclSitwzKYEUX0OY+ZqBcP+L2wqQRkjqbicv7gD+OcE5BhoctdP1
 sXUaoZRHHeQ+Pz5kjS2ppSmrG2tT8AQ=
 =t3Sk
 -----END PGP SIGNATURE-----

Merge tag 'dma-mapping-7.2-2026-06-16' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux

Pull dma-mapping updates from Marek Szyprowski:

 - added checks for DMA attributes in the debug code, especially to
   ensure that mappings are created and released with matching
   attributes (Leon Romanovsky)

 - better default configuration for CMA on NUMA machines (Feng Tang)

 - code cleanup in dma benchmark tool (Rosen Penev)

* tag 'dma-mapping-7.2-2026-06-16' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux:
  dma: map_benchmark: turn dma_sg_map_param buf into a flexible array
  dma-contiguous: simplify numa cma area handling
  dma-contiguous: add kconfig option to setup numa cma area if not configured explicitly
  dma-debug: Ensure mappings are created and released with matching attributes
  dma-debug: Feed DMA attribute for unmapping flows too
  dma-debug: Record DMA attributes in debug entry
  dma-debug: Remove unused DMA attribute parameter
  ntb: Use consistent DMA attributes when freeing DMA mappings
  ntb: Store original DMA address for future release
This commit is contained in:
Linus Torvalds 2026-06-17 12:20:21 -07:00
commit 4cc14386e3
8 changed files with 136 additions and 99 deletions

View File

@ -872,6 +872,10 @@ Kernel parameters
contiguous memory allocations. It will reserve CMA
area for the specified node.
If it is setup together with upper 'cmd_pernuma='
(unlikely), its size setting takes priority for the
specified numa nodes.
With numa CMA enabled, DMA users on node nid will
first try to allocate buffer from the numa area
which is located in node nid, if the allocation fails,

View File

@ -223,6 +223,7 @@ struct ntb_transport_mw {
void *alloc_addr;
void *virt_addr;
dma_addr_t dma_addr;
dma_addr_t original_dma_addr;
};
struct ntb_transport_client_dev {
@ -765,8 +766,8 @@ static void ntb_free_mw(struct ntb_transport_ctx *nt, int num_mw)
return;
ntb_mw_clear_trans(nt->ndev, PIDX, num_mw);
dma_free_coherent(dma_dev, mw->alloc_size,
mw->alloc_addr, mw->dma_addr);
dma_free_attrs(dma_dev, mw->alloc_size, mw->alloc_addr,
mw->original_dma_addr, DMA_ATTR_FORCE_CONTIGUOUS);
mw->xlat_size = 0;
mw->buff_size = 0;
mw->alloc_size = 0;
@ -802,6 +803,7 @@ static int ntb_alloc_mw_buffer(struct ntb_transport_mw *mw,
return -ENOMEM;
}
virt_addr = alloc_addr;
mw->original_dma_addr = dma_addr;
/*
* we must ensure that the memory address allocated is BAR size
@ -826,8 +828,8 @@ static int ntb_alloc_mw_buffer(struct ntb_transport_mw *mw,
return 0;
err:
dma_free_coherent(ntb_dev, mw->alloc_size, alloc_addr, dma_addr);
dma_free_attrs(ntb_dev, mw->alloc_size, alloc_addr, dma_addr,
DMA_ATTR_FORCE_CONTIGUOUS);
return rc;
}

View File

@ -179,7 +179,19 @@ config DMA_NUMA_CMA
You can set the size of pernuma CMA by specifying "cma_pernuma=size"
or set the node id and its size of CMA by specifying "numa_cma=
<node>:size[,<node>:size]" on the kernel's command line.
<node>:size[,<node>:size]" on the kernel's command line. And in
rare case that the above 2 are both setup, then the "numa_cma="
takes priority for the specified numa nodes.
config CMA_SIZE_PERNUMA
bool "Default CMA area per NUMA node"
depends on DMA_NUMA_CMA
default y
help
On systems with more than one NUMA node, the selected CMA
area size will be also allocated on each additional node,
so that most devices may have benefit from better DMA
locality without an explicit command-line opt-in.
comment "Default contiguous memory area size:"

View File

@ -134,8 +134,8 @@ EXPORT_SYMBOL_GPL(dev_get_cma_area);
static struct cma *dma_contiguous_numa_area[MAX_NUMNODES];
static phys_addr_t numa_cma_size[MAX_NUMNODES] __initdata;
static struct cma *dma_contiguous_pernuma_area[MAX_NUMNODES];
static phys_addr_t pernuma_size_bytes __initdata;
static bool numa_cma_configured __initdata;
static int __init early_numa_cma(char *p)
{
@ -164,6 +164,7 @@ static int __init early_numa_cma(char *p)
break;
}
numa_cma_configured = true;
return 0;
}
early_param("numa_cma", early_numa_cma);
@ -171,6 +172,7 @@ early_param("numa_cma", early_numa_cma);
static int __init early_cma_pernuma(char *p)
{
pernuma_size_bytes = memparse(p, &p);
numa_cma_configured = true;
return 0;
}
early_param("cma_pernuma", early_cma_pernuma);
@ -199,8 +201,13 @@ static void __init dma_numa_cma_reserve(void)
{
int nid;
if (IS_ENABLED(CONFIG_CMA_SIZE_PERNUMA) &&
!numa_cma_configured && dma_contiguous_default_area &&
nr_online_nodes > 1)
pernuma_size_bytes = cma_get_size(dma_contiguous_default_area);
for_each_node(nid) {
int ret;
int size, ret;
char name[CMA_MAX_NAME];
struct cma **cma;
@ -210,27 +217,17 @@ static void __init dma_numa_cma_reserve(void)
continue;
}
if (pernuma_size_bytes) {
/* per-node numa setting has the priority */
size = numa_cma_size[nid] ?: pernuma_size_bytes;
if (!size)
continue;
cma = &dma_contiguous_pernuma_area[nid];
snprintf(name, sizeof(name), "pernuma%d", nid);
ret = cma_declare_contiguous_nid(0, pernuma_size_bytes, 0, 0,
0, false, name, cma, nid);
if (ret)
pr_warn("%s: reservation failed: err %d, node %d", __func__,
ret, nid);
}
if (numa_cma_size[nid]) {
cma = &dma_contiguous_numa_area[nid];
snprintf(name, sizeof(name), "numa%d", nid);
ret = cma_declare_contiguous_nid(0, numa_cma_size[nid], 0, 0, 0, false,
name, cma, nid);
if (ret)
pr_warn("%s: reservation failed: err %d, node %d", __func__,
ret, nid);
}
cma = &dma_contiguous_numa_area[nid];
snprintf(name, sizeof(name), "numa%d", nid);
ret = cma_declare_contiguous_nid(0, size, 0, 0, 0, false, name, cma, nid);
if (ret)
pr_warn("%s: reservation failed: err %d, node %d", __func__,
ret, nid);
}
}
#else
@ -255,8 +252,6 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
phys_addr_t selected_limit = limit;
bool fixed = false;
dma_numa_cma_reserve();
pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
if (size_cmdline != -1) {
@ -312,6 +307,8 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
if (ret)
pr_warn("Couldn't queue default CMA region for heap creation.");
}
dma_numa_cma_reserve();
}
void __weak
@ -429,16 +426,8 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
#ifdef CONFIG_DMA_NUMA_CMA
if (nid != NUMA_NO_NODE && !(gfp & (GFP_DMA | GFP_DMA32))) {
struct cma *cma = dma_contiguous_pernuma_area[nid];
struct cma *cma = dma_contiguous_numa_area[nid];
struct page *page;
if (cma) {
page = cma_alloc_aligned(cma, size, gfp);
if (page)
return page;
}
cma = dma_contiguous_numa_area[nid];
if (cma) {
page = cma_alloc_aligned(cma, size, gfp);
if (page)
@ -476,9 +465,6 @@ void dma_free_contiguous(struct device *dev, struct page *page, size_t size)
* otherwise, page is from either per-numa cma or default cma
*/
#ifdef CONFIG_DMA_NUMA_CMA
if (cma_release(dma_contiguous_pernuma_area[page_to_nid(page)],
page, count))
return;
if (cma_release(dma_contiguous_numa_area[page_to_nid(page)],
page, count))
return;

View File

@ -63,7 +63,7 @@ enum map_err_types {
* @sg_mapped_ents: 'mapped_ents' from dma_map_sg
* @paddr: physical start address of the mapping
* @map_err_type: track whether dma_mapping_error() was checked
* @is_cache_clean: driver promises not to write to buffer while mapped
* @attrs: dma attributes
* @stack_len: number of backtrace entries in @stack_entries
* @stack_entries: stack of backtrace history
*/
@ -78,7 +78,7 @@ struct dma_debug_entry {
int sg_mapped_ents;
phys_addr_t paddr;
enum map_err_types map_err_type;
bool is_cache_clean;
unsigned long attrs;
#ifdef CONFIG_STACKTRACE
unsigned int stack_len;
unsigned long stack_entries[DMA_DEBUG_STACKTRACE_ENTRIES];
@ -478,6 +478,9 @@ static int active_cacheline_insert(struct dma_debug_entry *entry,
bool *overlap_cache_clean)
{
phys_addr_t cln = to_cacheline_number(entry);
bool is_cache_clean = entry->attrs &
(DMA_ATTR_DEBUGGING_IGNORE_CACHELINES |
DMA_ATTR_REQUIRE_COHERENT);
unsigned long flags;
int rc;
@ -495,12 +498,15 @@ static int active_cacheline_insert(struct dma_debug_entry *entry,
if (rc == -EEXIST) {
struct dma_debug_entry *existing;
active_cacheline_inc_overlap(cln, entry->is_cache_clean);
active_cacheline_inc_overlap(cln, is_cache_clean);
existing = radix_tree_lookup(&dma_active_cacheline, cln);
/* A lookup failure here after we got -EEXIST is unexpected. */
WARN_ON(!existing);
if (existing)
*overlap_cache_clean = existing->is_cache_clean;
*overlap_cache_clean =
existing->attrs &
(DMA_ATTR_DEBUGGING_IGNORE_CACHELINES |
DMA_ATTR_REQUIRE_COHERENT);
}
spin_unlock_irqrestore(&radix_lock, flags);
@ -544,12 +550,13 @@ void debug_dma_dump_mappings(struct device *dev)
if (!dev || dev == entry->dev) {
cln = to_cacheline_number(entry);
dev_info(entry->dev,
"%s idx %d P=%pa D=%llx L=%llx cln=%pa %s %s\n",
"%s idx %d P=%pa D=%llx L=%llx cln=%pa %s %s attrs=0x%lx\n",
type2name[entry->type], idx,
&entry->paddr, entry->dev_addr,
entry->size, &cln,
dir2name[entry->direction],
maperr2str[entry->map_err_type]);
maperr2str[entry->map_err_type],
entry->attrs);
}
}
spin_unlock_irqrestore(&bucket->lock, flags);
@ -575,14 +582,15 @@ static int dump_show(struct seq_file *seq, void *v)
list_for_each_entry(entry, &bucket->list, list) {
cln = to_cacheline_number(entry);
seq_printf(seq,
"%s %s %s idx %d P=%pa D=%llx L=%llx cln=%pa %s %s\n",
"%s %s %s idx %d P=%pa D=%llx L=%llx cln=%pa %s %s attrs=0x%lx\n",
dev_driver_string(entry->dev),
dev_name(entry->dev),
type2name[entry->type], idx,
&entry->paddr, entry->dev_addr,
entry->size, &cln,
dir2name[entry->direction],
maperr2str[entry->map_err_type]);
maperr2str[entry->map_err_type],
entry->attrs);
}
spin_unlock_irqrestore(&bucket->lock, flags);
}
@ -594,16 +602,14 @@ DEFINE_SHOW_ATTRIBUTE(dump);
* Wrapper function for adding an entry to the hash.
* This function takes care of locking itself.
*/
static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs)
static void add_dma_entry(struct dma_debug_entry *entry)
{
unsigned long attrs = entry->attrs;
bool overlap_cache_clean;
struct hash_bucket *bucket;
unsigned long flags;
int rc;
entry->is_cache_clean = attrs & (DMA_ATTR_DEBUGGING_IGNORE_CACHELINES |
DMA_ATTR_REQUIRE_COHERENT);
bucket = get_hash_bucket(entry, &flags);
hash_bucket_add(bucket, entry);
put_hash_bucket(bucket, flags);
@ -612,9 +618,10 @@ static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs)
if (rc == -ENOMEM) {
pr_err_once("cacheline tracking ENOMEM, dma-debug disabled\n");
global_disable = true;
} else if (rc == -EEXIST &&
!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
!(entry->is_cache_clean && overlap_cache_clean) &&
} else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
!(attrs & (DMA_ATTR_DEBUGGING_IGNORE_CACHELINES |
DMA_ATTR_REQUIRE_COHERENT) &&
overlap_cache_clean) &&
dma_get_cache_alignment() >= L1_CACHE_BYTES &&
!(IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) &&
is_swiotlb_active(entry->dev))) {
@ -1067,6 +1074,29 @@ static void check_unmap(struct dma_debug_entry *ref)
type2name[entry->type]);
}
/*
* This may be no bug in reality - but DMA API still expects
* that entry is unmapped with same attributes as it was mapped.
*
* DMA_ATTR_UNMAP_VALID lists the attributes that must be identical
* between map and unmap. Any attribute outside this set (e.g.
* DMA_ATTR_NO_WARN, DMA_ATTR_SKIP_CPU_SYNC) is allowed to differ.
*/
#define DMA_ATTR_UNMAP_VALID \
(DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_FORCE_CONTIGUOUS | \
DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT | DMA_ATTR_PRIVILEGED | \
DMA_ATTR_CC_SHARED)
if ((ref->attrs & DMA_ATTR_UNMAP_VALID) !=
(entry->attrs & DMA_ATTR_UNMAP_VALID)) {
err_printk(ref->dev, entry,
"device driver frees "
"DMA memory with different attributes "
"[device address=0x%016llx] [size=%llu bytes] "
"[mapped with 0x%lx] [unmapped with 0x%lx]\n",
ref->dev_addr, ref->size, entry->attrs, ref->attrs);
}
#undef DMA_ATTR_UNMAP_VALID
hash_bucket_del(entry);
put_hash_bucket(bucket, flags);
@ -1250,6 +1280,7 @@ void debug_dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,
entry->size = size;
entry->direction = direction;
entry->map_err_type = MAP_ERR_NOT_CHECKED;
entry->attrs = attrs;
if (attrs & DMA_ATTR_MMIO) {
unsigned long pfn = PHYS_PFN(phys);
@ -1265,7 +1296,7 @@ void debug_dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,
check_for_illegal_area(dev, phys_to_virt(phys), size);
}
add_dma_entry(entry, attrs);
add_dma_entry(entry);
}
void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
@ -1306,8 +1337,8 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
}
EXPORT_SYMBOL(debug_dma_mapping_error);
void debug_dma_unmap_phys(struct device *dev, dma_addr_t dma_addr,
size_t size, int direction)
void debug_dma_unmap_phys(struct device *dev, dma_addr_t dma_addr, size_t size,
int direction, unsigned long attrs)
{
struct dma_debug_entry ref = {
.type = dma_debug_phy,
@ -1315,6 +1346,7 @@ void debug_dma_unmap_phys(struct device *dev, dma_addr_t dma_addr,
.dev_addr = dma_addr,
.size = size,
.direction = direction,
.attrs = attrs,
};
if (unlikely(dma_debug_disabled()))
@ -1352,10 +1384,11 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
entry->direction = direction;
entry->sg_call_ents = nents;
entry->sg_mapped_ents = mapped_ents;
entry->attrs = attrs;
check_sg_segment(dev, s);
add_dma_entry(entry, attrs);
add_dma_entry(entry);
}
}
@ -1379,7 +1412,7 @@ static int get_nr_mapped_entries(struct device *dev,
}
void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
int nelems, int dir)
int nelems, int dir, unsigned long attrs)
{
struct scatterlist *s;
int mapped_ents = 0, i;
@ -1397,6 +1430,7 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
.size = sg_dma_len(s),
.direction = dir,
.sg_call_ents = nelems,
.attrs = attrs,
};
if (mapped_ents && i >= mapped_ents)
@ -1447,12 +1481,13 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size,
entry->size = size;
entry->dev_addr = dma_addr;
entry->direction = DMA_BIDIRECTIONAL;
entry->attrs = attrs;
add_dma_entry(entry, attrs);
add_dma_entry(entry);
}
void debug_dma_free_coherent(struct device *dev, size_t size,
void *virt, dma_addr_t dma_addr)
void debug_dma_free_coherent(struct device *dev, size_t size, void *virt,
dma_addr_t dma_addr, unsigned long attrs)
{
struct dma_debug_entry ref = {
.type = dma_debug_coherent,
@ -1460,6 +1495,7 @@ void debug_dma_free_coherent(struct device *dev, size_t size,
.dev_addr = dma_addr,
.size = size,
.direction = DMA_BIDIRECTIONAL,
.attrs = attrs,
};
/* handle vmalloc and linear addresses */
@ -1574,8 +1610,7 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
void debug_dma_alloc_pages(struct device *dev, struct page *page,
size_t size, int direction,
dma_addr_t dma_addr,
unsigned long attrs)
dma_addr_t dma_addr)
{
struct dma_debug_entry *entry;
@ -1593,7 +1628,7 @@ void debug_dma_alloc_pages(struct device *dev, struct page *page,
entry->dev_addr = dma_addr;
entry->direction = direction;
add_dma_entry(entry, attrs);
add_dma_entry(entry);
}
void debug_dma_free_pages(struct device *dev, struct page *page,

View File

@ -14,21 +14,22 @@ extern void debug_dma_map_phys(struct device *dev, phys_addr_t phys,
unsigned long attrs);
extern void debug_dma_unmap_phys(struct device *dev, dma_addr_t addr,
size_t size, int direction);
size_t size, int direction,
unsigned long attrs);
extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, int mapped_ents, int direction,
unsigned long attrs);
extern void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
int nelems, int dir);
int nelems, int dir, unsigned long attrs);
extern void debug_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t dma_addr, void *virt,
unsigned long attrs);
extern void debug_dma_free_coherent(struct device *dev, size_t size,
void *virt, dma_addr_t addr);
extern void debug_dma_free_coherent(struct device *dev, size_t size, void *virt,
dma_addr_t addr, unsigned long attrs);
extern void debug_dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
@ -47,8 +48,7 @@ extern void debug_dma_sync_sg_for_device(struct device *dev,
int nelems, int direction);
extern void debug_dma_alloc_pages(struct device *dev, struct page *page,
size_t size, int direction,
dma_addr_t dma_addr,
unsigned long attrs);
dma_addr_t dma_addr);
extern void debug_dma_free_pages(struct device *dev, struct page *page,
size_t size, int direction,
dma_addr_t dma_addr);
@ -60,7 +60,8 @@ static inline void debug_dma_map_phys(struct device *dev, phys_addr_t phys,
}
static inline void debug_dma_unmap_phys(struct device *dev, dma_addr_t addr,
size_t size, int direction)
size_t size, int direction,
unsigned long attrs)
{
}
@ -71,8 +72,8 @@ static inline void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
}
static inline void debug_dma_unmap_sg(struct device *dev,
struct scatterlist *sglist,
int nelems, int dir)
struct scatterlist *sglist, int nelems,
int dir, unsigned long attrs)
{
}
@ -83,7 +84,8 @@ static inline void debug_dma_alloc_coherent(struct device *dev, size_t size,
}
static inline void debug_dma_free_coherent(struct device *dev, size_t size,
void *virt, dma_addr_t addr)
void *virt, dma_addr_t addr,
unsigned long attrs)
{
}
@ -113,8 +115,7 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev,
static inline void debug_dma_alloc_pages(struct device *dev, struct page *page,
size_t size, int direction,
dma_addr_t dma_addr,
unsigned long attrs)
dma_addr_t dma_addr)
{
}

View File

@ -121,35 +121,35 @@ static struct map_benchmark_ops dma_single_map_benchmark_ops = {
struct dma_sg_map_param {
struct sg_table sgt;
struct device *dev;
void **buf;
u32 npages;
u32 dma_dir;
void *buf[] __counted_by(npages);
};
static void *dma_sg_map_benchmark_prepare(struct map_benchmark_data *map)
{
struct dma_sg_map_param *params;
struct scatterlist *sg;
u32 npages;
int i;
struct dma_sg_map_param *params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params)
return NULL;
/*
* Set the number of scatterlist entries based on the granule.
* In SG mode, 'granule' represents the number of scatterlist entries.
* Each scatterlist entry corresponds to a single page.
*/
params->npages = map->bparam.granule;
npages = map->bparam.granule;
params = kzalloc_flex(*params, buf, npages);
if (!params)
return NULL;
params->npages = npages;
params->dma_dir = map->bparam.dma_dir;
params->dev = map->dev;
params->buf = kmalloc_array(params->npages, sizeof(*params->buf),
GFP_KERNEL);
if (!params->buf)
goto out;
if (sg_alloc_table(&params->sgt, params->npages, GFP_KERNEL))
goto free_buf;
goto free_params;
for_each_sgtable_sg(&params->sgt, sg, i) {
params->buf[i] = (void *)__get_free_page(GFP_KERNEL);
@ -166,9 +166,7 @@ static void *dma_sg_map_benchmark_prepare(struct map_benchmark_data *map)
free_page((unsigned long)params->buf[i]);
sg_free_table(&params->sgt);
free_buf:
kfree(params->buf);
out:
free_params:
kfree(params);
return NULL;
}
@ -183,7 +181,6 @@ static void dma_sg_map_benchmark_unprepare(void *mparam)
sg_free_table(&params->sgt);
kfree(params->buf);
kfree(params);
}

View File

@ -223,7 +223,7 @@ void dma_unmap_phys(struct device *dev, dma_addr_t addr, size_t size,
else if (ops->unmap_phys)
ops->unmap_phys(dev, addr, size, dir, attrs);
trace_dma_unmap_phys(dev, addr, size, dir, attrs);
debug_dma_unmap_phys(dev, addr, size, dir);
debug_dma_unmap_phys(dev, addr, size, dir, attrs);
}
EXPORT_SYMBOL_GPL(dma_unmap_phys);
@ -349,7 +349,7 @@ void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
BUG_ON(!valid_dma_direction(dir));
trace_dma_unmap_sg(dev, sg, nents, dir, attrs);
debug_dma_unmap_sg(dev, sg, nents, dir);
debug_dma_unmap_sg(dev, sg, nents, dir, attrs);
if (dma_map_direct(dev, ops) ||
arch_dma_unmap_sg_direct(dev, sg, nents))
dma_direct_unmap_sg(dev, sg, nents, dir, attrs);
@ -687,7 +687,7 @@ void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr,
if (!cpu_addr)
return;
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle, attrs);
if (dma_alloc_direct(dev, ops) || arch_dma_free_direct(dev, dma_handle))
dma_direct_free(dev, size, cpu_addr, dma_handle, attrs);
else if (use_dma_iommu(dev))
@ -727,7 +727,7 @@ struct page *dma_alloc_pages(struct device *dev, size_t size,
if (page) {
trace_dma_alloc_pages(dev, page_to_virt(page), *dma_handle,
size, dir, gfp, 0);
debug_dma_alloc_pages(dev, page, size, dir, *dma_handle, 0);
debug_dma_alloc_pages(dev, page, size, dir, *dma_handle);
} else {
trace_dma_alloc_pages(dev, NULL, 0, size, dir, gfp, 0);
}
@ -834,7 +834,7 @@ void dma_free_noncontiguous(struct device *dev, size_t size,
struct sg_table *sgt, enum dma_data_direction dir)
{
trace_dma_free_sgt(dev, sgt, size, dir);
debug_dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir);
debug_dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir, 0);
if (use_dma_iommu(dev))
iommu_dma_free_noncontiguous(dev, size, sgt, dir);