Skip to content

Commit 87fe29b

Browse files
osctobebroonie
authored andcommitted
regulator: push allocations in create_regulator() outside of lock
Move all allocations outside of the regulator_lock()ed section. ====================================================== WARNING: possible circular locking dependency detected 5.7.13+ #535 Not tainted ------------------------------------------------------ f2fs_discard-179:7/702 is trying to acquire lock: c0e5d920 (regulator_list_mutex){+.+.}-{3:3}, at: regulator_lock_dependent+0x54/0x2c0 but task is already holding lock: cb95b080 (&dcc->cmd_lock){+.+.}-{3:3}, at: __issue_discard_cmd+0xec/0x5f8 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: [...] -> #3 (fs_reclaim){+.+.}-{0:0}: fs_reclaim_acquire.part.11+0x40/0x50 fs_reclaim_acquire+0x24/0x28 __kmalloc_track_caller+0x54/0x218 kstrdup+0x40/0x5c create_regulator+0xf4/0x368 regulator_resolve_supply+0x1a0/0x200 regulator_register+0x9c8/0x163c [...] other info that might help us debug this: Chain exists of: regulator_list_mutex --> &sit_i->sentry_lock --> &dcc->cmd_lock [...] Fixes: f8702f9 ("regulator: core: Use ww_mutex for regulators locking") Signed-off-by: Michał Mirosław <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/6eebc99b2474f4ffaa0405b15178ece0e7e4f608.1597195321.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown <[email protected]>
1 parent 467bf30 commit 87fe29b

File tree

1 file changed

+28
-25
lines changed

1 file changed

+28
-25
lines changed

drivers/regulator/core.c

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,44 +1580,53 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
15801580
const char *supply_name)
15811581
{
15821582
struct regulator *regulator;
1583-
char buf[REG_STR_SIZE];
1584-
int err, size;
1583+
int err;
1584+
1585+
if (dev) {
1586+
char buf[REG_STR_SIZE];
1587+
int size;
1588+
1589+
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
1590+
dev->kobj.name, supply_name);
1591+
if (size >= REG_STR_SIZE)
1592+
return NULL;
1593+
1594+
supply_name = kstrdup(buf, GFP_KERNEL);
1595+
if (supply_name == NULL)
1596+
return NULL;
1597+
} else {
1598+
supply_name = kstrdup_const(supply_name, GFP_KERNEL);
1599+
if (supply_name == NULL)
1600+
return NULL;
1601+
}
15851602

15861603
regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
1587-
if (regulator == NULL)
1604+
if (regulator == NULL) {
1605+
kfree(supply_name);
15881606
return NULL;
1607+
}
15891608

1590-
regulator_lock(rdev);
15911609
regulator->rdev = rdev;
1610+
regulator->supply_name = supply_name;
1611+
1612+
regulator_lock(rdev);
15921613
list_add(&regulator->list, &rdev->consumer_list);
1614+
regulator_unlock(rdev);
15931615

15941616
if (dev) {
15951617
regulator->dev = dev;
15961618

15971619
/* Add a link to the device sysfs entry */
1598-
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
1599-
dev->kobj.name, supply_name);
1600-
if (size >= REG_STR_SIZE)
1601-
goto overflow_err;
1602-
1603-
regulator->supply_name = kstrdup(buf, GFP_KERNEL);
1604-
if (regulator->supply_name == NULL)
1605-
goto overflow_err;
1606-
16071620
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
1608-
buf);
1621+
supply_name);
16091622
if (err) {
16101623
rdev_dbg(rdev, "could not add device link %s err %d\n",
16111624
dev->kobj.name, err);
16121625
/* non-fatal */
16131626
}
1614-
} else {
1615-
regulator->supply_name = kstrdup_const(supply_name, GFP_KERNEL);
1616-
if (regulator->supply_name == NULL)
1617-
goto overflow_err;
16181627
}
16191628

1620-
regulator->debugfs = debugfs_create_dir(regulator->supply_name,
1629+
regulator->debugfs = debugfs_create_dir(supply_name,
16211630
rdev->debugfs);
16221631
if (!regulator->debugfs) {
16231632
rdev_dbg(rdev, "Failed to create debugfs directory\n");
@@ -1642,13 +1651,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
16421651
_regulator_is_enabled(rdev))
16431652
regulator->always_on = true;
16441653

1645-
regulator_unlock(rdev);
16461654
return regulator;
1647-
overflow_err:
1648-
list_del(&regulator->list);
1649-
kfree(regulator);
1650-
regulator_unlock(rdev);
1651-
return NULL;
16521655
}
16531656

16541657
static int _regulator_get_enable_time(struct regulator_dev *rdev)

0 commit comments

Comments
 (0)