From: Rob Herring <robh@kernel.org>
To: Frank Rowand <frowand.list@gmail.com>,
"Enrico Weigelt, metux IT consult" <info@metux.net>,
"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
Petr Mladek <pmladek@suse.com>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Geert Uytterhoeven <geert+renesas@glider.be>
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 6/6] of: Refactor node and property manipulation function locking
Date: Fri, 18 Aug 2023 15:41:01 -0500 [thread overview]
Message-ID: <20230801-dt-changeset-fixes-v3-6-5f0410e007dd@kernel.org> (raw)
In-Reply-To: <20230801-dt-changeset-fixes-v3-0-5f0410e007dd@kernel.org>
All callers of __of_{add,remove,update}_property() and
__of_{attach,detach}_node() wrap the call with the devtree_lock
spinlock. Let's move the spinlock into the functions. This allows moving
the sysfs update functions into those functions as well.
Signed-off-by: Rob Herring <robh@kernel.org>
---
v3:
- Rebase due to changes in prior patch
v2:
- Re-arrange exit handling
---
drivers/of/base.c | 65 ++++++++++++++++++++++++++--------------------------
drivers/of/dynamic.c | 51 +++++++++++++----------------------------
2 files changed, 49 insertions(+), 67 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3f9ddd18ff4b..4b24bed894ad 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1551,21 +1551,32 @@ static struct property *__of_remove_property_from_list(struct property **list, s
*/
int __of_add_property(struct device_node *np, struct property *prop)
{
+ int rc = 0;
+ unsigned long flags;
struct property **next;
+ raw_spin_lock_irqsave(&devtree_lock, flags);
+
__of_remove_property_from_list(&np->deadprops, prop);
prop->next = NULL;
next = &np->properties;
while (*next) {
- if (strcmp(prop->name, (*next)->name) == 0)
+ if (strcmp(prop->name, (*next)->name) == 0) {
/* duplicate ! don't insert it */
- return -EEXIST;
-
+ rc = -EEXIST;
+ goto out_unlock;
+ }
next = &(*next)->next;
}
*next = prop;
+out_unlock:
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ if (rc)
+ return rc;
+
+ __of_add_property_sysfs(np, prop);
return 0;
}
@@ -1576,37 +1587,36 @@ int __of_add_property(struct device_node *np, struct property *prop)
*/
int of_add_property(struct device_node *np, struct property *prop)
{
- unsigned long flags;
int rc;
mutex_lock(&of_mutex);
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
rc = __of_add_property(np, prop);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
-
- if (!rc)
- __of_add_property_sysfs(np, prop);
-
mutex_unlock(&of_mutex);
- if (!rc)
- of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
-
return rc;
}
EXPORT_SYMBOL_GPL(of_add_property);
int __of_remove_property(struct device_node *np, struct property *prop)
{
+ unsigned long flags;
+ int rc = -ENODEV;
+
+ raw_spin_lock_irqsave(&devtree_lock, flags);
+
if (__of_remove_property_from_list(&np->properties, prop)) {
/* Found the property, add it to deadprops list */
prop->next = np->deadprops;
np->deadprops = prop;
- return 0;
+ rc = 0;
}
- return -ENODEV;
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+ if (rc)
+ return rc;
+
+ __of_remove_property_sysfs(np, prop);
+ return 0;
}
/**
@@ -1621,21 +1631,13 @@ int __of_remove_property(struct device_node *np, struct property *prop)
*/
int of_remove_property(struct device_node *np, struct property *prop)
{
- unsigned long flags;
int rc;
if (!prop)
return -ENODEV;
mutex_lock(&of_mutex);
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
rc = __of_remove_property(np, prop);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
-
- if (!rc)
- __of_remove_property_sysfs(np, prop);
-
mutex_unlock(&of_mutex);
if (!rc)
@@ -1649,6 +1651,9 @@ int __of_update_property(struct device_node *np, struct property *newprop,
struct property **oldpropp)
{
struct property **next, *oldprop;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&devtree_lock, flags);
__of_remove_property_from_list(&np->deadprops, newprop);
@@ -1670,6 +1675,10 @@ int __of_update_property(struct device_node *np, struct property *newprop,
*next = newprop;
}
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+
+ __of_update_property_sysfs(np, newprop, oldprop);
+
return 0;
}
@@ -1685,21 +1694,13 @@ int __of_update_property(struct device_node *np, struct property *newprop,
int of_update_property(struct device_node *np, struct property *newprop)
{
struct property *oldprop;
- unsigned long flags;
int rc;
if (!newprop->name)
return -EINVAL;
mutex_lock(&of_mutex);
-
- raw_spin_lock_irqsave(&devtree_lock, flags);
rc = __of_update_property(np, newprop, &oldprop);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
-
- if (!rc)
- __of_update_property_sysfs(np, newprop, oldprop);
-
mutex_unlock(&of_mutex);
if (!rc)
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index d3ad970ad7b8..9252641de507 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -198,6 +198,9 @@ static void __of_attach_node(struct device_node *np)
{
const __be32 *phandle;
int sz;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&devtree_lock, flags);
if (!of_node_check_flag(np, OF_OVERLAY)) {
np->name = __of_get_property(np, "name", NULL);
@@ -220,6 +223,10 @@ static void __of_attach_node(struct device_node *np)
np->parent->child = np;
of_node_clear_flag(np, OF_DETACHED);
np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE;
+
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+
+ __of_attach_node_sysfs(np);
}
/**
@@ -229,17 +236,12 @@ static void __of_attach_node(struct device_node *np)
int of_attach_node(struct device_node *np)
{
struct of_reconfig_data rd;
- unsigned long flags;
memset(&rd, 0, sizeof(rd));
rd.dn = np;
mutex_lock(&of_mutex);
- raw_spin_lock_irqsave(&devtree_lock, flags);
__of_attach_node(np);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
-
- __of_attach_node_sysfs(np);
mutex_unlock(&of_mutex);
of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd);
@@ -250,13 +252,15 @@ int of_attach_node(struct device_node *np)
void __of_detach_node(struct device_node *np)
{
struct device_node *parent;
+ unsigned long flags;
- if (WARN_ON(of_node_check_flag(np, OF_DETACHED)))
- return;
+ raw_spin_lock_irqsave(&devtree_lock, flags);
parent = np->parent;
- if (WARN_ON(!parent))
+ if (WARN_ON(of_node_check_flag(np, OF_DETACHED) || !parent)) {
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
return;
+ }
if (parent->child == np)
parent->child = np->sibling;
@@ -273,6 +277,10 @@ void __of_detach_node(struct device_node *np)
/* race with of_find_node_by_phandle() prevented by devtree_lock */
__of_phandle_cache_inv_entry(np->phandle);
+
+ raw_spin_unlock_irqrestore(&devtree_lock, flags);
+
+ __of_detach_node_sysfs(np);
}
/**
@@ -282,17 +290,12 @@ void __of_detach_node(struct device_node *np)
int of_detach_node(struct device_node *np)
{
struct of_reconfig_data rd;
- unsigned long flags;
memset(&rd, 0, sizeof(rd));
rd.dn = np;
mutex_lock(&of_mutex);
- raw_spin_lock_irqsave(&devtree_lock, flags);
__of_detach_node(np);
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
-
- __of_detach_node_sysfs(np);
mutex_unlock(&of_mutex);
of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd);
@@ -564,12 +567,10 @@ static int __of_changeset_entry_notify(struct of_changeset_entry *ce,
static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
{
- unsigned long flags;
int ret = 0;
of_changeset_action_debug("applying: ", ce->action, ce->np, ce->prop);
- raw_spin_lock_irqsave(&devtree_lock, flags);
switch (ce->action) {
case OF_RECONFIG_ATTACH_NODE:
__of_attach_node(ce->np);
@@ -590,32 +591,12 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
default:
ret = -EINVAL;
}
- raw_spin_unlock_irqrestore(&devtree_lock, flags);
if (ret) {
of_changeset_action_err("apply failed: ", ce->action, ce->np, ce->prop);
return ret;
}
- switch (ce->action) {
- case OF_RECONFIG_ATTACH_NODE:
- __of_attach_node_sysfs(ce->np);
- break;
- case OF_RECONFIG_DETACH_NODE:
- __of_detach_node_sysfs(ce->np);
- break;
- case OF_RECONFIG_ADD_PROPERTY:
- /* ignore duplicate names */
- __of_add_property_sysfs(ce->np, ce->prop);
- break;
- case OF_RECONFIG_REMOVE_PROPERTY:
- __of_remove_property_sysfs(ce->np, ce->prop);
- break;
- case OF_RECONFIG_UPDATE_PROPERTY:
- __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop);
- break;
- }
-
return 0;
}
--
2.40.1
next prev parent reply other threads:[~2023-08-18 20:42 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-18 20:40 [PATCH v3 0/6] dt: changeset fixes and cleanups Rob Herring
2023-08-18 20:40 ` [PATCH v3 1/6] of: unittest: Fix EXPECT for parse_phandle_with_args_map() test Rob Herring
2023-08-18 20:40 ` [PATCH v3 2/6] of: dynamic: Refactor action prints to not use "%pOF" inside devtree_lock Rob Herring
2023-08-21 11:52 ` Geert Uytterhoeven
2023-08-18 20:40 ` [PATCH v3 3/6] of: dynamic: Refactor changeset action printing to common helpers Rob Herring
2023-08-21 12:09 ` Geert Uytterhoeven
2023-08-18 20:40 ` [PATCH v3 4/6] of: dynamic: Fix race in getting old property when updating property Rob Herring
2023-08-21 12:53 ` Geert Uytterhoeven
2023-08-18 20:41 ` [PATCH v3 5/6] of: dynamic: Move dead property list check into property add/update functions Rob Herring
2023-08-21 10:49 ` Andy Shevchenko
2023-08-21 10:52 ` Andy Shevchenko
2023-08-21 12:24 ` Rob Herring
2023-08-21 12:35 ` Andy Shevchenko
2023-08-21 13:05 ` Geert Uytterhoeven
2023-08-21 14:23 ` Rob Herring
2023-08-18 20:41 ` Rob Herring [this message]
2023-08-21 10:51 ` [PATCH v3 6/6] of: Refactor node and property manipulation function locking Andy Shevchenko
2023-08-21 13:18 ` Geert Uytterhoeven
2023-08-21 19:00 ` Rob Herring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230801-dt-changeset-fixes-v3-6-5f0410e007dd@kernel.org \
--to=robh@kernel.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=devicetree@vger.kernel.org \
--cc=frowand.list@gmail.com \
--cc=geert+renesas@glider.be \
--cc=info@metux.net \
--cc=linux-kernel@vger.kernel.org \
--cc=pmladek@suse.com \
--cc=rafael.j.wysocki@intel.com \
--cc=sakari.ailus@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.