Skip to contentSkip to conversation

regulator: core: Move regulator release to avoid deadlock

PATCH Applied Charles Keepax 3 participants 4 messages Oct 29, 2012 – Oct 31, 2012 Voltage and current regulator framework

lore
Share & tools
lore
#0 lore raw

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
index 5c4829c..e68754c 100644
@@ -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(&regulator_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
Applied
#1 lore raw
Quoted 3 lines · Charles Keepax

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.

Applied, thanks.

#2 lore raw
Quoted 7 lines · Mark Brown

* PGP Signed by an unknown key

Quoted 3 lines · Charles Keepax

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.

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?

#3 lore raw
Quoted 7 lines · Laxman Dewangan
Quoted 6 lines · Mark Brown

* PGP Signed by an unknown key

Quoted 3 lines · Charles Keepax

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.

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 and rdev->supply at this point shows NULL but when call the function device_unregister(&rdev->dev), the rdev->supply becomes 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.