Skip to content

Commit

Permalink
regulator: core: fix deadlock on regulator enable
Browse files Browse the repository at this point in the history
commit cb3543c upstream.

When updating the operating mode as part of regulator enable, the caller
has already locked the regulator tree and drms_uA_update() must not try
to do the same in order not to trigger a deadlock.

The lock inversion is reported by lockdep as:

  ======================================================
  WARNING: possible circular locking dependency detected
  6.1.0-next-20221215 Freescale#142 Not tainted
  ------------------------------------------------------
  udevd/154 is trying to acquire lock:
  ffffc11f123d7e50 (regulator_list_mutex){+.+.}-{3:3}, at: regulator_lock_dependent+0x54/0x280

  but task is already holding lock:
  ffff80000e4c36e8 (regulator_ww_class_acquire){+.+.}-{0:0}, at: regulator_enable+0x34/0x80

  which lock already depends on the new lock.

  ...

   Possible unsafe locking scenario:

         CPU0                    CPU1
         ----                    ----
    lock(regulator_ww_class_acquire);
                                 lock(regulator_list_mutex);
                                 lock(regulator_ww_class_acquire);
    lock(regulator_list_mutex);

   *** DEADLOCK ***

just before probe of a Qualcomm UFS controller (occasionally) deadlocks
when enabling one of its regulators.

Fixes: 9243a19 ("regulator: core: Change voltage setting path")
Fixes: f8702f9 ("regulator: core: Use ww_mutex for regulators locking")
Cc: [email protected]      # 5.0
Signed-off-by: Johan Hovold <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
jhovold authored and gregkh committed Jan 18, 2023
1 parent fb0407d commit 328f3c0
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
/* get input voltage */
input_uV = 0;
if (rdev->supply)
input_uV = regulator_get_voltage(rdev->supply);
input_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
if (input_uV <= 0)
input_uV = rdev->constraints->input_uV;
if (input_uV <= 0) {
Expand Down

0 comments on commit 328f3c0

Please sign in to comment.