All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] of: dma_configure: Reuse existing DMA map range
@ 2022-02-14 15:32 Mårten Lindahl
  2022-02-15 22:58 ` Rob Herring
  0 siblings, 1 reply; 4+ messages in thread
From: Mårten Lindahl @ 2022-02-14 15:32 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand; +Cc: kernel, devicetree, Mårten Lindahl

When unbinding/binding a driver with DMA mapped memory, the DMA map is
not freed when the driver is reloaded. This leads to a memory leak when
the DMA map is overwritten when reprobing the driver.

This can be reproduced with a platform driver having a dma-range:

dummy {
	...
	#address-cells = <0x2>;
	#size-cells = <0x2>;
	ranges;
	dma-ranges = <...>;
	...
};

and then unbinding/binding it:

~# echo soc:dummy >/sys/bus/platform/drivers/<driver>/unbind

DMA map object 0xffffff800b0ae540 still being held by &pdev->dev

~# echo soc:dummy >/sys/bus/platform/drivers/<driver>/bind
~# echo scan > /sys/kernel/debug/kmemleak
~# cat /sys/kernel/debug/kmemleak
unreferenced object 0xffffff800b0ae540 (size 64):
  comm "sh", pid 833, jiffies 4295174550 (age 2535.352s)
  hex dump (first 32 bytes):
    00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 80 00 00 00 00 00 00 00 80 00 00 00 00  ................
  backtrace:
    [<ffffffefd1694708>] create_object.isra.0+0x108/0x344
    [<ffffffefd1d1a850>] kmemleak_alloc+0x8c/0xd0
    [<ffffffefd167e2d0>] __kmalloc+0x440/0x6f0
    [<ffffffefd1a960a4>] of_dma_get_range+0x124/0x220
    [<ffffffefd1a8ce90>] of_dma_configure_id+0x40/0x2d0
    [<ffffffefd198b68c>] platform_dma_configure+0x5c/0xa4
    [<ffffffefd198846c>] really_probe+0x8c/0x514
    [<ffffffefd1988990>] __driver_probe_device+0x9c/0x19c
    [<ffffffefd1988cd8>] device_driver_attach+0x54/0xbc
    [<ffffffefd1986634>] bind_store+0xc4/0x120
    [<ffffffefd19856e0>] drv_attr_store+0x30/0x44
    [<ffffffefd173c9b0>] sysfs_kf_write+0x50/0x60
    [<ffffffefd173c1c4>] kernfs_fop_write_iter+0x124/0x1b4
    [<ffffffefd16a013c>] new_sync_write+0xdc/0x160
    [<ffffffefd16a256c>] vfs_write+0x23c/0x2a0
    [<ffffffefd16a2758>] ksys_write+0x64/0xec

Don't get a new dma_range_map if there already is one. Check for an
existing map and reuse it, or else get the map as before. This will
prevent overwriting the old map which is still valid.

Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
---

v2:
 - Reuse range map instead of getting a new and freeing the old.

 drivers/of/device.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 874f031442dc..7e5d8066ffff 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -116,9 +116,14 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	u64 dma_start = 0;
 	u64 mask, end, size = 0;
 	bool coherent;
-	int ret;
+	int ret = 0;
+
+	/* Don't get a new DMA range map if we already have one */
+	if (dev->dma_range_map)
+		map = dev->dma_range_map;
+	else
+		ret = of_dma_get_range(np, &map);
 
-	ret = of_dma_get_range(np, &map);
 	if (ret < 0) {
 		/*
 		 * For legacy reasons, we have to assume some devices need
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-02-16  1:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-14 15:32 [PATCH v2] of: dma_configure: Reuse existing DMA map range Mårten Lindahl
2022-02-15 22:58 ` Rob Herring
2022-02-15 23:59   ` Rob Herring
2022-02-16  1:15     ` Marten Lindahl

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.