]>
Commit | Line | Data |
---|---|---|
04fd09d4 SL |
1 | From dea216e616ece75a0ec4d5f5cd130e4c72320286 Mon Sep 17 00:00:00 2001 |
2 | From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> | |
3 | Date: Wed, 13 Feb 2019 17:14:42 +0100 | |
4 | Subject: ARM: 8840/1: use a raw_spinlock_t in unwind | |
5 | ||
6 | [ Upstream commit 74ffe79ae538283bbf7c155e62339f1e5c87b55a ] | |
7 | ||
8 | Mostly unwind is done with irqs enabled however SLUB may call it with | |
9 | irqs disabled while creating a new SLUB cache. | |
10 | ||
11 | I had system freeze while loading a module which called | |
12 | kmem_cache_create() on init. That means SLUB's __slab_alloc() disabled | |
13 | interrupts and then | |
14 | ||
15 | ->new_slab_objects() | |
16 | ->new_slab() | |
17 | ->setup_object() | |
18 | ->setup_object_debug() | |
19 | ->init_tracking() | |
20 | ->set_track() | |
21 | ->save_stack_trace() | |
22 | ->save_stack_trace_tsk() | |
23 | ->walk_stackframe() | |
24 | ->unwind_frame() | |
25 | ->unwind_find_idx() | |
26 | =>spin_lock_irqsave(&unwind_lock); | |
27 | ||
28 | Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> | |
29 | Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |
30 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
31 | --- | |
32 | arch/arm/kernel/unwind.c | 14 +++++++------- | |
33 | 1 file changed, 7 insertions(+), 7 deletions(-) | |
34 | ||
35 | diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c | |
36 | index 0bee233fef9a..314cfb232a63 100644 | |
37 | --- a/arch/arm/kernel/unwind.c | |
38 | +++ b/arch/arm/kernel/unwind.c | |
39 | @@ -93,7 +93,7 @@ extern const struct unwind_idx __start_unwind_idx[]; | |
40 | static const struct unwind_idx *__origin_unwind_idx; | |
41 | extern const struct unwind_idx __stop_unwind_idx[]; | |
42 | ||
43 | -static DEFINE_SPINLOCK(unwind_lock); | |
44 | +static DEFINE_RAW_SPINLOCK(unwind_lock); | |
45 | static LIST_HEAD(unwind_tables); | |
46 | ||
47 | /* Convert a prel31 symbol to an absolute address */ | |
48 | @@ -201,7 +201,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) | |
49 | /* module unwind tables */ | |
50 | struct unwind_table *table; | |
51 | ||
52 | - spin_lock_irqsave(&unwind_lock, flags); | |
53 | + raw_spin_lock_irqsave(&unwind_lock, flags); | |
54 | list_for_each_entry(table, &unwind_tables, list) { | |
55 | if (addr >= table->begin_addr && | |
56 | addr < table->end_addr) { | |
57 | @@ -213,7 +213,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) | |
58 | break; | |
59 | } | |
60 | } | |
61 | - spin_unlock_irqrestore(&unwind_lock, flags); | |
62 | + raw_spin_unlock_irqrestore(&unwind_lock, flags); | |
63 | } | |
64 | ||
65 | pr_debug("%s: idx = %p\n", __func__, idx); | |
66 | @@ -529,9 +529,9 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, | |
67 | tab->begin_addr = text_addr; | |
68 | tab->end_addr = text_addr + text_size; | |
69 | ||
70 | - spin_lock_irqsave(&unwind_lock, flags); | |
71 | + raw_spin_lock_irqsave(&unwind_lock, flags); | |
72 | list_add_tail(&tab->list, &unwind_tables); | |
73 | - spin_unlock_irqrestore(&unwind_lock, flags); | |
74 | + raw_spin_unlock_irqrestore(&unwind_lock, flags); | |
75 | ||
76 | return tab; | |
77 | } | |
78 | @@ -543,9 +543,9 @@ void unwind_table_del(struct unwind_table *tab) | |
79 | if (!tab) | |
80 | return; | |
81 | ||
82 | - spin_lock_irqsave(&unwind_lock, flags); | |
83 | + raw_spin_lock_irqsave(&unwind_lock, flags); | |
84 | list_del(&tab->list); | |
85 | - spin_unlock_irqrestore(&unwind_lock, flags); | |
86 | + raw_spin_unlock_irqrestore(&unwind_lock, flags); | |
87 | ||
88 | kfree(tab); | |
89 | } | |
90 | -- | |
91 | 2.19.1 | |
92 |