Commit 9dd1835e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'dma-mapping-6.17-2025-09-09' of...

Merge tag 'dma-mapping-6.17-2025-09-09' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux

Pull dma-mapping fix from Marek Szyprowski:

 - one more fix for DMA API debugging infrastructure (Baochen Qiang)

* tag 'dma-mapping-6.17-2025-09-09' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux:
  dma-debug: don't enforce dma mapping check on noncoherent allocations
parents f777d111 7e2368a2
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ enum {
	dma_debug_sg,
	dma_debug_coherent,
	dma_debug_resource,
	dma_debug_noncoherent,
};

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

static const char *dir2name[] = {
@@ -993,7 +995,8 @@ static void check_unmap(struct dma_debug_entry *ref)
			   "[mapped as %s] [unmapped as %s]\n",
			   ref->dev_addr, ref->size,
			   type2name[entry->type], type2name[ref->type]);
	} else if (entry->type == dma_debug_coherent &&
	} else if ((entry->type == dma_debug_coherent ||
		    entry->type == dma_debug_noncoherent) &&
		   ref->paddr != entry->paddr) {
		err_printk(ref->dev, entry, "device driver frees "
			   "DMA memory with different CPU address "
@@ -1581,6 +1584,49 @@ 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)
{
	struct dma_debug_entry *entry;

	if (unlikely(dma_debug_disabled()))
		return;

	entry = dma_entry_alloc();
	if (!entry)
		return;

	entry->type      = dma_debug_noncoherent;
	entry->dev       = dev;
	entry->paddr	 = page_to_phys(page);
	entry->size      = size;
	entry->dev_addr  = dma_addr;
	entry->direction = direction;

	add_dma_entry(entry, attrs);
}

void debug_dma_free_pages(struct device *dev, struct page *page,
			  size_t size, int direction,
			  dma_addr_t dma_addr)
{
	struct dma_debug_entry ref = {
		.type           = dma_debug_noncoherent,
		.dev            = dev,
		.paddr		= page_to_phys(page),
		.dev_addr       = dma_addr,
		.size           = size,
		.direction      = direction,
	};

	if (unlikely(dma_debug_disabled()))
		return;

	check_unmap(&ref);
}

static int __init dma_debug_driver_setup(char *str)
{
	int i;
+20 −0
Original line number Diff line number Diff line
@@ -54,6 +54,13 @@ extern void debug_dma_sync_sg_for_cpu(struct device *dev,
extern void debug_dma_sync_sg_for_device(struct device *dev,
					 struct scatterlist *sg,
					 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);
extern void debug_dma_free_pages(struct device *dev, struct page *page,
				 size_t size, int direction,
				 dma_addr_t dma_addr);
#else /* CONFIG_DMA_API_DEBUG */
static inline void debug_dma_map_page(struct device *dev, struct page *page,
				      size_t offset, size_t size,
@@ -126,5 +133,18 @@ static inline void debug_dma_sync_sg_for_device(struct device *dev,
						int nelems, int direction)
{
}

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)
{
}

static inline void debug_dma_free_pages(struct device *dev, struct page *page,
					size_t size, int direction,
					dma_addr_t dma_addr)
{
}
#endif /* CONFIG_DMA_API_DEBUG */
#endif /* _KERNEL_DMA_DEBUG_H */
+2 −2
Original line number Diff line number Diff line
@@ -712,7 +712,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_map_page(dev, page, 0, size, dir, *dma_handle, 0);
		debug_dma_alloc_pages(dev, page, size, dir, *dma_handle, 0);
	} else {
		trace_dma_alloc_pages(dev, NULL, 0, size, dir, gfp, 0);
	}
@@ -738,7 +738,7 @@ void dma_free_pages(struct device *dev, size_t size, struct page *page,
		dma_addr_t dma_handle, enum dma_data_direction dir)
{
	trace_dma_free_pages(dev, page_to_virt(page), dma_handle, size, dir, 0);
	debug_dma_unmap_page(dev, dma_handle, size, dir);
	debug_dma_free_pages(dev, page, size, dir, dma_handle);
	__dma_free_pages(dev, size, page, dma_handle, dir);
}
EXPORT_SYMBOL_GPL(dma_free_pages);