regulator: core: Move regulator release to avoid deadlock
PATCH 1/1 regulator: core: Move regulator release to avoid deadlock
regulator_put function was called whilst holding the regulator_list_mutex, which is also locked from regulator_put. This causes deadlock when failing to register a regulator.
This patch adds a second exit point for the regulator_register function which releases the mutex and then cleans up the supply.
--- drivers/regulator/core.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
drivers/regulator/core.c +6 -3
@@ -3444,15 +3444,18 @@ unset_supplies:unset_regulator_supplies (rdev); scrub: -if (rdev->supply) -regulator_put (rdev->supply);if (rdev->ena_gpio)gpio_free (rdev->ena_gpio);kfree (rdev->constraints);device_unregister (&rdev->dev); + +mutex_unlock (®ulator_list_mutex); +if (rdev->supply) +regulator_put (rdev->supply); +/* device core frees rdev */ rdev =ERR_PTR (ret); - goto out; +return rdev; clean:kfree (rdev);
Signature · 1 line
1.7.2.5
Mark Brown
AppliedQuoted 3 lines · Charles Keepax
regulator_putfunction was called whilst holding theregulator_list_mutex, which is also locked fromregulator_put. This causes deadlock when failing to register a regulator.
Applied, thanks.
Quoted 7 lines · Mark Brown
* PGP Signed by an unknown key
Quoted 3 lines · Charles Keepax
regulator_putfunction was called whilst holding theregulator_list_mutex, which is also locked fromregulator_put. This causes deadlock when failing to register a regulator.Applied, thanks.
This patch create the crash in following case:
- If there is of rail supply and supply does not found. In this case it goes to scrub and rdev->supply at this point shows NULL but when call the function device_unregister(&rdev->dev), the rdev->supply becomes random pointer.
What happen if we do the device_unregister() outside the mutex lock?
Quoted 7 lines · Laxman Dewangan
Quoted 6 lines · Mark Brown
* PGP Signed by an unknown key
Quoted 3 lines · Charles Keepax
regulator_putfunction was called whilst holding theregulator_list_mutex, which is also locked fromregulator_put. This causes deadlock when failing to register a regulator.
Quoted 7 lines
Quoted 1 line
Applied, thanks.
This patch create the crash in following case:
- If there is of rail supply and supply does not found. In this case it goes to scrub andrdev->supplyat this point shows NULL but when call the functiondevice_unregister(&rdev->dev), therdev->supplybecomes random pointer.
Yeah that is a problem, sorry for missing this.
Quoted 2 lines
What happen if we do the
device_unregister()outside the mutex lock?
It would look reasonable to me, but I think it is going to make more sense for someone with more experience than myself to have a closer look at what can be done.