mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 01:34:14 +08:00
regulator: core: fix kobject release warning and memory leak in regulator_register()
Here is a warning report about lack of registered release()
from kobject lib:
Device '(null)' does not have a release() function, it is broken and must be fixed.
WARNING: CPU: 0 PID: 48430 at drivers/base/core.c:2332 device_release+0x104/0x120
Call Trace:
kobject_put+0xdc/0x180
put_device+0x1b/0x30
regulator_register+0x651/0x1170
devm_regulator_register+0x4f/0xb0
When regulator_register() returns fail and directly goto `clean` symbol,
rdev->dev has not registered release() function yet (which is registered
by regulator_class in the following), so rdev needs to be freed manually.
If rdev->dev.of_node is not NULL, which means the of_node has gotten by
regulator_of_get_init_data(), it needs to call of_node_put() to avoid
refcount leak.
Otherwise, only calling put_device() would lead memory leak of rdev
in further:
unreferenced object 0xffff88810d0b1000 (size 2048):
comm "107-i2c-rtq6752", pid 48430, jiffies 4342258431 (age 1341.780s)
backtrace:
kmalloc_trace+0x22/0x110
regulator_register+0x184/0x1170
devm_regulator_register+0x4f/0xb0
When regulator_register() returns fail and goto `wash` symbol,
rdev->dev has registered release() function, so directly call
put_device() to cleanup everything.
Fixes: d3c731564e
("regulator: plug of_node leak in regulator_register()'s error path")
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
Link: https://lore.kernel.org/r/20221116074339.1024240-1-zengheng4@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
392cc0a4a0
commit
5f4b204b6b
@ -5639,11 +5639,15 @@ wash:
|
|||||||
mutex_lock(®ulator_list_mutex);
|
mutex_lock(®ulator_list_mutex);
|
||||||
regulator_ena_gpio_free(rdev);
|
regulator_ena_gpio_free(rdev);
|
||||||
mutex_unlock(®ulator_list_mutex);
|
mutex_unlock(®ulator_list_mutex);
|
||||||
|
put_device(&rdev->dev);
|
||||||
|
rdev = NULL;
|
||||||
clean:
|
clean:
|
||||||
if (dangling_of_gpiod)
|
if (dangling_of_gpiod)
|
||||||
gpiod_put(config->ena_gpiod);
|
gpiod_put(config->ena_gpiod);
|
||||||
|
if (rdev && rdev->dev.of_node)
|
||||||
|
of_node_put(rdev->dev.of_node);
|
||||||
|
kfree(rdev);
|
||||||
kfree(config);
|
kfree(config);
|
||||||
put_device(&rdev->dev);
|
|
||||||
rinse:
|
rinse:
|
||||||
if (dangling_cfg_gpiod)
|
if (dangling_cfg_gpiod)
|
||||||
gpiod_put(cfg->ena_gpiod);
|
gpiod_put(cfg->ena_gpiod);
|
||||||
|
Loading…
Reference in New Issue
Block a user