diff options
author | David Collins <collinsd@codeaurora.org> | 2021-01-07 17:16:02 -0800 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-01-08 18:22:59 +0000 |
commit | eaa7995c529b54d68d97a30f6344cc6ca2f214a7 (patch) | |
tree | c61a3f1650674d236e491cbc7f89ef994944f6e9 /drivers/regulator/arizona-ldo1.c | |
parent | 36836f5b377b5a75c16f5bdc5c0f97f9f51212e1 (diff) |
regulator: core: avoid regulator_resolve_supply() race condition
The final step in regulator_register() is to call
regulator_resolve_supply() for each registered regulator
(including the one in the process of being registered). The
regulator_resolve_supply() function first checks if rdev->supply
is NULL, then it performs various steps to try to find the supply.
If successful, rdev->supply is set inside of set_supply().
This procedure can encounter a race condition if two concurrent
tasks call regulator_register() near to each other on separate CPUs
and one of the regulators has rdev->supply_name specified. There
is currently nothing guaranteeing atomicity between the rdev->supply
check and set steps. Thus, both tasks can observe rdev->supply==NULL
in their regulator_resolve_supply() calls. This then results in
both creating a struct regulator for the supply. One ends up
actually stored in rdev->supply and the other is lost (though still
present in the supply's consumer_list).
Here is a kernel log snippet showing the issue:
[ 12.421768] gpu_cc_gx_gdsc: supplied by pm8350_s5_level
[ 12.425854] gpu_cc_gx_gdsc: supplied by pm8350_s5_level
[ 12.429064] debugfs: Directory 'regulator.4-SUPPLY' with parent
'17a00000.rsc:rpmh-regulator-gfxlvl-pm8350_s5_level'
already present!
Avoid this race condition by holding the rdev->mutex lock inside
of regulator_resolve_supply() while checking and setting
rdev->supply.
Signed-off-by: David Collins <collinsd@codeaurora.org>
Link: https://lore.kernel.org/r/1610068562-4410-1-git-send-email-collinsd@codeaurora.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator/arizona-ldo1.c')
0 files changed, 0 insertions, 0 deletions