Skip to content

Commit 914d9d8

Browse files
committed
of: dynamic: Refactor action prints to not use "%pOF" inside devtree_lock
While originally it was fine to format strings using "%pOF" while holding devtree_lock, this now causes a deadlock. Lockdep reports: of_get_parent from of_fwnode_get_parent+0x18/0x24 ^^^^^^^^^^^^^ of_fwnode_get_parent from fwnode_count_parents+0xc/0x28 fwnode_count_parents from fwnode_full_name_string+0x18/0xac fwnode_full_name_string from device_node_string+0x1a0/0x404 device_node_string from pointer+0x3c0/0x534 pointer from vsnprintf+0x248/0x36c vsnprintf from vprintk_store+0x130/0x3b4 Fix this by moving the printing in __of_changeset_entry_apply() outside the lock. As the only difference in the multiple prints is the action name, use the existing "action_names" to refactor the prints into a single print. Fixes: a92eb76 ("lib/vsprintf: Make use of fwnode API to obtain node names and separators") Cc: stable@vger.kernel.org Reported-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://lore.kernel.org/r/20230801-dt-changeset-fixes-v3-2-5f0410e007dd@kernel.org Signed-off-by: Rob Herring <robh@kernel.org>
1 parent 0aeae37 commit 914d9d8

File tree

1 file changed

+9
-22
lines changed

1 file changed

+9
-22
lines changed

drivers/of/dynamic.c

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,14 @@ int of_reconfig_notifier_unregister(struct notifier_block *nb)
6363
}
6464
EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
6565

66-
#ifdef DEBUG
67-
const char *action_names[] = {
66+
static const char *action_names[] = {
67+
[0] = "INVALID",
6868
[OF_RECONFIG_ATTACH_NODE] = "ATTACH_NODE",
6969
[OF_RECONFIG_DETACH_NODE] = "DETACH_NODE",
7070
[OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY",
7171
[OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY",
7272
[OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY",
7373
};
74-
#endif
7574

7675
int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
7776
{
@@ -620,21 +619,9 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
620619
}
621620

622621
ret = __of_add_property(ce->np, ce->prop);
623-
if (ret) {
624-
pr_err("changeset: add_property failed @%pOF/%s\n",
625-
ce->np,
626-
ce->prop->name);
627-
break;
628-
}
629622
break;
630623
case OF_RECONFIG_REMOVE_PROPERTY:
631624
ret = __of_remove_property(ce->np, ce->prop);
632-
if (ret) {
633-
pr_err("changeset: remove_property failed @%pOF/%s\n",
634-
ce->np,
635-
ce->prop->name);
636-
break;
637-
}
638625
break;
639626

640627
case OF_RECONFIG_UPDATE_PROPERTY:
@@ -648,20 +635,17 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
648635
}
649636

650637
ret = __of_update_property(ce->np, ce->prop, &old_prop);
651-
if (ret) {
652-
pr_err("changeset: update_property failed @%pOF/%s\n",
653-
ce->np,
654-
ce->prop->name);
655-
break;
656-
}
657638
break;
658639
default:
659640
ret = -EINVAL;
660641
}
661642
raw_spin_unlock_irqrestore(&devtree_lock, flags);
662643

663-
if (ret)
644+
if (ret) {
645+
pr_err("changeset: apply failed: %-15s %pOF:%s\n",
646+
action_names[ce->action], ce->np, ce->prop->name);
664647
return ret;
648+
}
665649

666650
switch (ce->action) {
667651
case OF_RECONFIG_ATTACH_NODE:
@@ -947,6 +931,9 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action,
947931
if (!ce)
948932
return -ENOMEM;
949933

934+
if (WARN_ON(action >= ARRAY_SIZE(action_names)))
935+
return -EINVAL;
936+
950937
/* get a reference to the node */
951938
ce->action = action;
952939
ce->np = of_node_get(np);

0 commit comments

Comments
 (0)