[PATCH 0/2] pinctrl: fix group/function table leaks on consumer re-probe

From: A. Sverdlin

Date: Thu Oct 01 2026 - 05:06:27 EST


From: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxxxx>

Pinctrl drivers that create their groups/functions lazily from the
consumer's device-tree node in .dt_node_to_map() leak the per-mapping
tables when the same node is mapped again. The core deduplicates
groups/functions by name and keeps the first instance for the controller's
lifetime, so it silently drops the copies built on every subsequent
mapping - e.g. on each re-probe of the consumer device. kmemleak does not
flag them because they stay reachable from the controller's devres list.

Reproducer (patch 1, pinctrl-single) - any board where a device referencing
a pinctrl-single state is repeatedly re-probed; here an I2C TPM whose node
has a "default" pinctrl state:

while modprobe tpm_tis_i2c; do rmmod tpm_tis_i2c; done

The tables land in a generic kmalloc-N cache (kmalloc-192 on arm64, where
ARCH_KMALLOC_MINALIGN pads every devres allocation; the bucket differs by
config), so watch it cache-independently by diffing /proc/slabinfo after
dropping the reclaimable slab:

sync; echo 3 > /proc/sys/vm/drop_caches
cat /proc/slabinfo | awk 'NR>2{print $1,$2}' | sort > /tmp/a
<run N cycles>
sync; echo 3 > /proc/sys/vm/drop_caches
cat /proc/slabinfo | awk 'NR>2{print $1,$2}' | sort > /tmp/b
join /tmp/a /tmp/b | awk '$3>$2{print $1,$3-$2}'

Patch 1 (pinctrl-single) was found and fixed with the above test on real
hardware. Patch 2 (ti-iodelay) has the same bug pattern - plus a missing
.dt_free_map that leaks the mapping table as well - but was found by code
review only and is compile-tested only; I have no such hardware to
reproduce it.

Alexander Sverdlin (2):
pinctrl: single: don't leak group/function tables on consumer re-probe
pinctrl: ti-iodelay: fix memory leaks on consumer re-probe

drivers/pinctrl/pinctrl-single.c | 21 +++++++++++++++++++++
drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 24 ++++++++++++++++++++++++
2 files changed, 45 insertions(+)

--
2.55.0