Commit d25d86949b6799c35d78f4910498c2b65a3f0841

Authored by Benjamin Herrenschmidt
Committed by Grant Likely
1 parent b0a4d8b3cf

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: 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>

Showing 2 changed files with 12 additions and 8 deletions Side-by-side Diff

arch/sparc/kernel/prom_common.c
... ... @@ -54,6 +54,7 @@
54 54 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
55 55 {
56 56 struct property **prevp;
  57 + unsigned long flags;
57 58 void *new_val;
58 59 int err;
59 60  
... ... @@ -64,7 +65,7 @@
64 65 err = -ENODEV;
65 66  
66 67 mutex_lock(&of_set_property_mutex);
67   - raw_spin_lock(&devtree_lock);
  68 + raw_spin_lock_irqsave(&devtree_lock, flags);
68 69 prevp = &dp->properties;
69 70 while (*prevp) {
70 71 struct property *prop = *prevp;
... ... @@ -91,7 +92,7 @@
91 92 }
92 93 prevp = &(*prevp)->next;
93 94 }
94   - raw_spin_unlock(&devtree_lock);
  95 + raw_spin_unlock_irqrestore(&devtree_lock, flags);
95 96 mutex_unlock(&of_set_property_mutex);
96 97  
97 98 /* XXX Upate procfs if necessary... */
... ... @@ -192,14 +192,15 @@
192 192 struct device_node *of_find_all_nodes(struct device_node *prev)
193 193 {
194 194 struct device_node *np;
  195 + unsigned long flags;
195 196  
196   - raw_spin_lock(&devtree_lock);
  197 + raw_spin_lock_irqsave(&devtree_lock, flags);
197 198 np = prev ? prev->allnext : of_allnodes;
198 199 for (; np != NULL; np = np->allnext)
199 200 if (of_node_get(np))
200 201 break;
201 202 of_node_put(prev);
202   - raw_spin_unlock(&devtree_lock);
  203 + raw_spin_unlock_irqrestore(&devtree_lock, flags);
203 204 return np;
204 205 }
205 206 EXPORT_SYMBOL(of_find_all_nodes);
206 207  
... ... @@ -421,8 +422,9 @@
421 422 struct device_node *prev)
422 423 {
423 424 struct device_node *next;
  425 + unsigned long flags;
424 426  
425   - raw_spin_lock(&devtree_lock);
  427 + raw_spin_lock_irqsave(&devtree_lock, flags);
426 428 next = prev ? prev->sibling : node->child;
427 429 for (; next; next = next->sibling) {
428 430 if (!__of_device_is_available(next))
... ... @@ -431,7 +433,7 @@
431 433 break;
432 434 }
433 435 of_node_put(prev);
434   - raw_spin_unlock(&devtree_lock);
  436 + raw_spin_unlock_irqrestore(&devtree_lock, flags);
435 437 return next;
436 438 }
437 439 EXPORT_SYMBOL(of_get_next_available_child);
438 440  
439 441  
... ... @@ -735,13 +737,14 @@
735 737 struct device_node *of_find_node_by_phandle(phandle handle)
736 738 {
737 739 struct device_node *np;
  740 + unsigned long flags;
738 741  
739   - raw_spin_lock(&devtree_lock);
  742 + raw_spin_lock_irqsave(&devtree_lock, flags);
740 743 for (np = of_allnodes; np; np = np->allnext)
741 744 if (np->phandle == handle)
742 745 break;
743 746 of_node_get(np);
744   - raw_spin_unlock(&devtree_lock);
  747 + raw_spin_unlock_irqrestore(&devtree_lock, flags);
745 748 return np;
746 749 }
747 750 EXPORT_SYMBOL(of_find_node_by_phandle);