Commit d25d8694 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Grant Likely

of: Fix locking vs. interrupts

The OF code uses irqsafe locks everywhere except in a handful of functions
for no obvious reasons. Since the conversion from the old rwlocks, this
now triggers lockdep warnings when used at interrupt time. At least one
driver (ibmvscsi) seems to be doing that from softirq context.

This converts the few non-irqsafe locks into irqsafe ones, making them
consistent with the rest of the code.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGrant Likely <grant.likely@linaro.org>
parent b0a4d8b3
...@@ -54,6 +54,7 @@ EXPORT_SYMBOL(of_set_property_mutex); ...@@ -54,6 +54,7 @@ EXPORT_SYMBOL(of_set_property_mutex);
int of_set_property(struct device_node *dp, const char *name, void *val, int len) int of_set_property(struct device_node *dp, const char *name, void *val, int len)
{ {
struct property **prevp; struct property **prevp;
unsigned long flags;
void *new_val; void *new_val;
int err; int err;
...@@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len ...@@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
err = -ENODEV; err = -ENODEV;
mutex_lock(&of_set_property_mutex); mutex_lock(&of_set_property_mutex);
raw_spin_lock(&devtree_lock); raw_spin_lock_irqsave(&devtree_lock, flags);
prevp = &dp->properties; prevp = &dp->properties;
while (*prevp) { while (*prevp) {
struct property *prop = *prevp; struct property *prop = *prevp;
...@@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len ...@@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
} }
prevp = &(*prevp)->next; prevp = &(*prevp)->next;
} }
raw_spin_unlock(&devtree_lock); raw_spin_unlock_irqrestore(&devtree_lock, flags);
mutex_unlock(&of_set_property_mutex); mutex_unlock(&of_set_property_mutex);
/* XXX Upate procfs if necessary... */ /* XXX Upate procfs if necessary... */
......
...@@ -192,14 +192,15 @@ EXPORT_SYMBOL(of_find_property); ...@@ -192,14 +192,15 @@ EXPORT_SYMBOL(of_find_property);
struct device_node *of_find_all_nodes(struct device_node *prev) struct device_node *of_find_all_nodes(struct device_node *prev)
{ {
struct device_node *np; struct device_node *np;
unsigned long flags;
raw_spin_lock(&devtree_lock); raw_spin_lock_irqsave(&devtree_lock, flags);
np = prev ? prev->allnext : of_allnodes; np = prev ? prev->allnext : of_allnodes;
for (; np != NULL; np = np->allnext) for (; np != NULL; np = np->allnext)
if (of_node_get(np)) if (of_node_get(np))
break; break;
of_node_put(prev); of_node_put(prev);
raw_spin_unlock(&devtree_lock); raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np; return np;
} }
EXPORT_SYMBOL(of_find_all_nodes); EXPORT_SYMBOL(of_find_all_nodes);
...@@ -421,8 +422,9 @@ struct device_node *of_get_next_available_child(const struct device_node *node, ...@@ -421,8 +422,9 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
struct device_node *prev) struct device_node *prev)
{ {
struct device_node *next; struct device_node *next;
unsigned long flags;
raw_spin_lock(&devtree_lock); raw_spin_lock_irqsave(&devtree_lock, flags);
next = prev ? prev->sibling : node->child; next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling) { for (; next; next = next->sibling) {
if (!__of_device_is_available(next)) if (!__of_device_is_available(next))
...@@ -431,7 +433,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node, ...@@ -431,7 +433,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
break; break;
} }
of_node_put(prev); of_node_put(prev);
raw_spin_unlock(&devtree_lock); raw_spin_unlock_irqrestore(&devtree_lock, flags);
return next; return next;
} }
EXPORT_SYMBOL(of_get_next_available_child); EXPORT_SYMBOL(of_get_next_available_child);
...@@ -735,13 +737,14 @@ EXPORT_SYMBOL_GPL(of_modalias_node); ...@@ -735,13 +737,14 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
struct device_node *of_find_node_by_phandle(phandle handle) struct device_node *of_find_node_by_phandle(phandle handle)
{ {
struct device_node *np; struct device_node *np;
unsigned long flags;
raw_spin_lock(&devtree_lock); raw_spin_lock_irqsave(&devtree_lock, flags);
for (np = of_allnodes; np; np = np->allnext) for (np = of_allnodes; np; np = np->allnext)
if (np->phandle == handle) if (np->phandle == handle)
break; break;
of_node_get(np); of_node_get(np);
raw_spin_unlock(&devtree_lock); raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np; return np;
} }
EXPORT_SYMBOL(of_find_node_by_phandle); EXPORT_SYMBOL(of_find_node_by_phandle);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment