Skip to content

Commit c6eb8d2

Browse files
Baochen Qianggregkh
authored andcommitted
dma-debug: don't enforce dma mapping check on noncoherent allocations
[ Upstream commit 7e2368a ] As discussed in [1], there is no need to enforce dma mapping check on noncoherent allocations, a simple test on the returned CPU address is good enough. Add a new pair of debug helpers and use them for noncoherent alloc/free to fix this issue. Fixes: efa70f2 ("dma-mapping: add a new dma_alloc_pages API") Link: https://lore.kernel.org/all/[email protected] # 1 Signed-off-by: Baochen Qiang <[email protected]> Signed-off-by: Marek Szyprowski <[email protected]> Link: https://lore.kernel.org/r/20250828-dma-debug-fix-noncoherent-dma-check-v1-1-76e9be0dd7fc@oss.qualcomm.com Signed-off-by: Sasha Levin <[email protected]>
1 parent 245eb0b commit c6eb8d2

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

kernel/dma/debug.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum {
3939
dma_debug_sg,
4040
dma_debug_coherent,
4141
dma_debug_resource,
42+
dma_debug_noncoherent,
4243
};
4344

4445
enum map_err_types {
@@ -141,6 +142,7 @@ static const char *type2name[] = {
141142
[dma_debug_sg] = "scatter-gather",
142143
[dma_debug_coherent] = "coherent",
143144
[dma_debug_resource] = "resource",
145+
[dma_debug_noncoherent] = "noncoherent",
144146
};
145147

146148
static const char *dir2name[] = {
@@ -993,7 +995,8 @@ static void check_unmap(struct dma_debug_entry *ref)
993995
"[mapped as %s] [unmapped as %s]\n",
994996
ref->dev_addr, ref->size,
995997
type2name[entry->type], type2name[ref->type]);
996-
} else if (entry->type == dma_debug_coherent &&
998+
} else if ((entry->type == dma_debug_coherent ||
999+
entry->type == dma_debug_noncoherent) &&
9971000
ref->paddr != entry->paddr) {
9981001
err_printk(ref->dev, entry, "device driver frees "
9991002
"DMA memory with different CPU address "
@@ -1573,6 +1576,49 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
15731576
}
15741577
}
15751578

1579+
void debug_dma_alloc_pages(struct device *dev, struct page *page,
1580+
size_t size, int direction,
1581+
dma_addr_t dma_addr,
1582+
unsigned long attrs)
1583+
{
1584+
struct dma_debug_entry *entry;
1585+
1586+
if (unlikely(dma_debug_disabled()))
1587+
return;
1588+
1589+
entry = dma_entry_alloc();
1590+
if (!entry)
1591+
return;
1592+
1593+
entry->type = dma_debug_noncoherent;
1594+
entry->dev = dev;
1595+
entry->paddr = page_to_phys(page);
1596+
entry->size = size;
1597+
entry->dev_addr = dma_addr;
1598+
entry->direction = direction;
1599+
1600+
add_dma_entry(entry, attrs);
1601+
}
1602+
1603+
void debug_dma_free_pages(struct device *dev, struct page *page,
1604+
size_t size, int direction,
1605+
dma_addr_t dma_addr)
1606+
{
1607+
struct dma_debug_entry ref = {
1608+
.type = dma_debug_noncoherent,
1609+
.dev = dev,
1610+
.paddr = page_to_phys(page),
1611+
.dev_addr = dma_addr,
1612+
.size = size,
1613+
.direction = direction,
1614+
};
1615+
1616+
if (unlikely(dma_debug_disabled()))
1617+
return;
1618+
1619+
check_unmap(&ref);
1620+
}
1621+
15761622
static int __init dma_debug_driver_setup(char *str)
15771623
{
15781624
int i;

kernel/dma/debug.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ extern void debug_dma_sync_sg_for_cpu(struct device *dev,
5454
extern void debug_dma_sync_sg_for_device(struct device *dev,
5555
struct scatterlist *sg,
5656
int nelems, int direction);
57+
extern void debug_dma_alloc_pages(struct device *dev, struct page *page,
58+
size_t size, int direction,
59+
dma_addr_t dma_addr,
60+
unsigned long attrs);
61+
extern void debug_dma_free_pages(struct device *dev, struct page *page,
62+
size_t size, int direction,
63+
dma_addr_t dma_addr);
5764
#else /* CONFIG_DMA_API_DEBUG */
5865
static inline void debug_dma_map_page(struct device *dev, struct page *page,
5966
size_t offset, size_t size,
@@ -126,5 +133,18 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev,
126133
int nelems, int direction)
127134
{
128135
}
136+
137+
static inline void debug_dma_alloc_pages(struct device *dev, struct page *page,
138+
size_t size, int direction,
139+
dma_addr_t dma_addr,
140+
unsigned long attrs)
141+
{
142+
}
143+
144+
static inline void debug_dma_free_pages(struct device *dev, struct page *page,
145+
size_t size, int direction,
146+
dma_addr_t dma_addr)
147+
{
148+
}
129149
#endif /* CONFIG_DMA_API_DEBUG */
130150
#endif /* _KERNEL_DMA_DEBUG_H */

kernel/dma/mapping.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ struct page *dma_alloc_pages(struct device *dev, size_t size,
694694
if (page) {
695695
trace_dma_alloc_pages(dev, page_to_virt(page), *dma_handle,
696696
size, dir, gfp, 0);
697-
debug_dma_map_page(dev, page, 0, size, dir, *dma_handle, 0);
697+
debug_dma_alloc_pages(dev, page, size, dir, *dma_handle, 0);
698698
} else {
699699
trace_dma_alloc_pages(dev, NULL, 0, size, dir, gfp, 0);
700700
}
@@ -720,7 +720,7 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page,
720720
dma_addr_t dma_handle, enum dma_data_direction dir)
721721
{
722722
trace_dma_free_pages(dev, page_to_virt(page), dma_handle, size, dir, 0);
723-
debug_dma_unmap_page(dev, dma_handle, size, dir);
723+
debug_dma_free_pages(dev, page, size, dir, dma_handle);
724724
__dma_free_pages(dev, size, page, dma_handle, dir);
725725
}
726726
EXPORT_SYMBOL_GPL(dma_free_pages);

0 commit comments

Comments
 (0)