Skip to content

Commit 7e2368a

Browse files
Baochen Qiangmszyprow
authored andcommitted
dma-debug: don't enforce dma mapping check on noncoherent allocations
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
1 parent 89a2d21 commit 7e2368a

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 "
@@ -1581,6 +1584,49 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
15811584
}
15821585
}
15831586

1587+
void debug_dma_alloc_pages(struct device *dev, struct page *page,
1588+
size_t size, int direction,
1589+
dma_addr_t dma_addr,
1590+
unsigned long attrs)
1591+
{
1592+
struct dma_debug_entry *entry;
1593+
1594+
if (unlikely(dma_debug_disabled()))
1595+
return;
1596+
1597+
entry = dma_entry_alloc();
1598+
if (!entry)
1599+
return;
1600+
1601+
entry->type = dma_debug_noncoherent;
1602+
entry->dev = dev;
1603+
entry->paddr = page_to_phys(page);
1604+
entry->size = size;
1605+
entry->dev_addr = dma_addr;
1606+
entry->direction = direction;
1607+
1608+
add_dma_entry(entry, attrs);
1609+
}
1610+
1611+
void debug_dma_free_pages(struct device *dev, struct page *page,
1612+
size_t size, int direction,
1613+
dma_addr_t dma_addr)
1614+
{
1615+
struct dma_debug_entry ref = {
1616+
.type = dma_debug_noncoherent,
1617+
.dev = dev,
1618+
.paddr = page_to_phys(page),
1619+
.dev_addr = dma_addr,
1620+
.size = size,
1621+
.direction = direction,
1622+
};
1623+
1624+
if (unlikely(dma_debug_disabled()))
1625+
return;
1626+
1627+
check_unmap(&ref);
1628+
}
1629+
15841630
static int __init dma_debug_driver_setup(char *str)
15851631
{
15861632
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
@@ -712,7 +712,7 @@ struct page *dma_alloc_pages(struct device *dev, size_t size,
712712
if (page) {
713713
trace_dma_alloc_pages(dev, page_to_virt(page), *dma_handle,
714714
size, dir, gfp, 0);
715-
debug_dma_map_page(dev, page, 0, size, dir, *dma_handle, 0);
715+
debug_dma_alloc_pages(dev, page, size, dir, *dma_handle, 0);
716716
} else {
717717
trace_dma_alloc_pages(dev, NULL, 0, size, dir, gfp, 0);
718718
}
@@ -738,7 +738,7 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page,
738738
dma_addr_t dma_handle, enum dma_data_direction dir)
739739
{
740740
trace_dma_free_pages(dev, page_to_virt(page), dma_handle, size, dir, 0);
741-
debug_dma_unmap_page(dev, dma_handle, size, dir);
741+
debug_dma_free_pages(dev, page, size, dir, dma_handle);
742742
__dma_free_pages(dev, size, page, dma_handle, dir);
743743
}
744744
EXPORT_SYMBOL_GPL(dma_free_pages);

0 commit comments

Comments
 (0)