Skip to content

Commit

Permalink
of: Fix locking vs. interrupts
Browse files Browse the repository at this point in the history
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: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Grant Likely <grant.likely@linaro.org>
  • Loading branch information
Benjamin Herrenschmidt authored and Grant Likely committed Jun 13, 2013
1 parent b0a4d8b commit d25d869
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 8 deletions.
5 changes: 3 additions & 2 deletions arch/sparc/kernel/prom_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct property **prevp;
unsigned long flags;
void *new_val;
int err;

Expand All @@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
err = -ENODEV;

mutex_lock(&of_set_property_mutex);
raw_spin_lock(&devtree_lock);
raw_spin_lock_irqsave(&devtree_lock, flags);
prevp = &dp->properties;
while (*prevp) {
struct property *prop = *prevp;
Expand All @@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
}
prevp = &(*prevp)->next;
}
raw_spin_unlock(&devtree_lock);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
mutex_unlock(&of_set_property_mutex);

/* XXX Upate procfs if necessary... */
Expand Down
15 changes: 9 additions & 6 deletions drivers/of/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,15 @@ EXPORT_SYMBOL(of_find_property);
struct device_node *of_find_all_nodes(struct device_node *prev)
{
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;
for (; np != NULL; np = np->allnext)
if (of_node_get(np))
break;
of_node_put(prev);
raw_spin_unlock(&devtree_lock);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np;
}
EXPORT_SYMBOL(of_find_all_nodes);
Expand Down Expand Up @@ -421,8 +422,9 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
struct device_node *prev)
{
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;
for (; next; next = next->sibling) {
if (!__of_device_is_available(next))
Expand All @@ -431,7 +433,7 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
break;
}
of_node_put(prev);
raw_spin_unlock(&devtree_lock);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return next;
}
EXPORT_SYMBOL(of_get_next_available_child);
Expand Down Expand Up @@ -735,13 +737,14 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
struct device_node *of_find_node_by_phandle(phandle handle)
{
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)
if (np->phandle == handle)
break;
of_node_get(np);
raw_spin_unlock(&devtree_lock);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np;
}
EXPORT_SYMBOL(of_find_node_by_phandle);
Expand Down

0 comments on commit d25d869

Please sign in to comment.