Commit d25d86949b6799c35d78f4910498c2b65a3f0841
Committed by
Grant Likely
1 parent
b0a4d8b3cf
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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... */ |
drivers/of/base.c
... | ... | @@ -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); |