From: Pablo Martin-Gomez pmartin-gomez@freebox.fr
[ Upstream commit 6463cbe08b0cbf9bba8763306764f5fd643023e1 ]
Memory allocated for the ECC engine conf is not released during spinand cleanup. Below kmemleak trace is seen for this memory leak:
unreferenced object 0xffffff80064f00e0 (size 8): comm "swapper/0", pid 1, jiffies 4294937458 hex dump (first 8 bytes): 00 00 00 00 00 00 00 00 ........ backtrace (crc 0): kmemleak_alloc+0x30/0x40 __kmalloc_cache_noprof+0x208/0x3c0 spinand_ondie_ecc_init_ctx+0x114/0x200 nand_ecc_init_ctx+0x70/0xa8 nanddev_ecc_engine_init+0xec/0x27c spinand_probe+0xa2c/0x1620 spi_mem_probe+0x130/0x21c spi_probe+0xf0/0x170 really_probe+0x17c/0x6e8 __driver_probe_device+0x17c/0x21c driver_probe_device+0x58/0x180 __device_attach_driver+0x15c/0x1f8 bus_for_each_drv+0xec/0x150 __device_attach+0x188/0x24c device_initial_probe+0x10/0x20 bus_probe_device+0x11c/0x160
Fix the leak by calling nanddev_ecc_engine_cleanup() inside spinand_cleanup().
Signed-off-by: Pablo Martin-Gomez pmartin-gomez@freebox.fr Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org ---
**YES**
This commit should be backported to stable kernel trees for the following reasons:
1. **Clear Memory Leak Bug**: The commit fixes a concrete memory leak where the ECC engine configuration memory (allocated in `spinand_ondie_ecc_init_ctx()` at line 272 via `kzalloc()`) is never freed. The kmemleak trace clearly shows this 8-byte allocation is leaked on every spinand device initialization.
2. **Small and Contained Fix**: The fix is minimal - it only adds a single line `nanddev_ecc_engine_cleanup(nand);` to the existing `spinand_cleanup()` function. This follows the established cleanup pattern already used in the error path (`err_cleanup_ecc_engine:` at line 1569).
3. **No Architectural Changes**: The commit doesn't introduce any new features or change any architecture. It simply ensures proper cleanup of already-allocated resources by calling an existing cleanup function.
4. **Follows Established Patterns**: The fix mirrors the cleanup already performed in the error handling path during `spinand_init()`. If initialization fails after `nanddev_ecc_engine_init()`, the code already calls `nanddev_ecc_engine_cleanup()`. This commit ensures the same cleanup happens during normal device removal.
5. **Clear Impact on Users**: Memory leaks affect system stability over time, especially in systems that frequently probe/remove SPI NAND devices (e.g., during development, testing, or hot-plug scenarios). Each leak is small (8 bytes) but cumulative.
6. **Low Risk**: The cleanup function `nanddev_ecc_engine_cleanup()` already checks if the engine exists before attempting cleanup (`if (nand->ecc.engine)`), making it safe to call even in edge cases.
7. **Similar to Backported Commits**: Like the backported commit "atm: idt77252: fix kmemleak when rmmod idt77252", this fixes a clear resource leak found by kmemleak, with a simple addition of the appropriate cleanup call in the removal path.
The commit follows stable tree rules perfectly: it's a small, important bugfix with minimal regression risk that addresses a real memory leak issue affecting users.
drivers/mtd/nand/spi/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 4d76f9f71a0e9..241f6a4df16c1 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1496,6 +1496,7 @@ static void spinand_cleanup(struct spinand_device *spinand) { struct nand_device *nand = spinand_to_nand(spinand);
+ nanddev_ecc_engine_cleanup(nand); nanddev_cleanup(nand); spinand_manufacturer_cleanup(spinand); kfree(spinand->databuf);