diff options
author | Robin Getz <robin.getz@analog.com> | 2007-10-29 05:20:41 -0400 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-10-29 05:20:41 -0400 |
commit | 885be03b069131d242506f0f717d38659b2bdb6c (patch) | |
tree | 52c1858645ee28b9d0bc7166744da3eef5bc6f1f /arch/blackfin | |
parent | 64307f7db3690140a16c6748e65068f8a279877c (diff) |
Blackfin arch: fix bug: kernel prints out error message twice
This fixes two things:
- stop calling write_lock_irq/write_unlock_irq which can turn modify
irq levels
- don't calling mmput when handing exceptions - since this might_sleep,
which does a rti, and leaves us in kernel space (irq15, rather
than irq5).
Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index afd044e78af6..ce86659f9b65 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -54,12 +54,13 @@ void __init trap_init(void) | |||
54 | int kstack_depth_to_print = 48; | 54 | int kstack_depth_to_print = 48; |
55 | 55 | ||
56 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | 56 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
57 | static int printk_address(unsigned long address) | 57 | static void printk_address(unsigned long address) |
58 | { | 58 | { |
59 | struct vm_list_struct *vml; | 59 | struct vm_list_struct *vml; |
60 | struct task_struct *p; | 60 | struct task_struct *p; |
61 | struct mm_struct *mm; | 61 | struct mm_struct *mm; |
62 | unsigned long offset; | 62 | unsigned long flags, offset; |
63 | unsigned int in_exception = bfin_read_IPEND() & 0x10; | ||
63 | 64 | ||
64 | #ifdef CONFIG_KALLSYMS | 65 | #ifdef CONFIG_KALLSYMS |
65 | unsigned long symsize; | 66 | unsigned long symsize; |
@@ -75,9 +76,10 @@ static int printk_address(unsigned long address) | |||
75 | /* yeah! kernel space! */ | 76 | /* yeah! kernel space! */ |
76 | if (!modname) | 77 | if (!modname) |
77 | modname = delim = ""; | 78 | modname = delim = ""; |
78 | return printk("<0x%p> { %s%s%s%s + 0x%lx }", | 79 | printk("<0x%p> { %s%s%s%s + 0x%lx }", |
79 | (void *)address, delim, modname, delim, symname, | 80 | (void *)address, delim, modname, delim, symname, |
80 | (unsigned long)offset); | 81 | (unsigned long)offset); |
82 | return; | ||
81 | 83 | ||
82 | } | 84 | } |
83 | #endif | 85 | #endif |
@@ -86,9 +88,9 @@ static int printk_address(unsigned long address) | |||
86 | * mappings of all our processes and see if we can't be a whee | 88 | * mappings of all our processes and see if we can't be a whee |
87 | * bit more specific | 89 | * bit more specific |
88 | */ | 90 | */ |
89 | write_lock_irq(&tasklist_lock); | 91 | write_lock_irqsave(&tasklist_lock, flags); |
90 | for_each_process(p) { | 92 | for_each_process(p) { |
91 | mm = get_task_mm(p); | 93 | mm = (in_exception ? p->mm : get_task_mm(p)); |
92 | if (!mm) | 94 | if (!mm) |
93 | continue; | 95 | continue; |
94 | 96 | ||
@@ -117,20 +119,24 @@ static int printk_address(unsigned long address) | |||
117 | else | 119 | else |
118 | offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | 120 | offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); |
119 | 121 | ||
120 | write_unlock_irq(&tasklist_lock); | 122 | printk("<0x%p> [ %s + 0x%lx ]", |
121 | mmput(mm); | 123 | (void *)address, name, offset); |
122 | return printk("<0x%p> [ %s + 0x%lx ]", | 124 | if (!in_exception) |
123 | (void *)address, name, offset); | 125 | mmput(mm); |
126 | goto done; | ||
124 | } | 127 | } |
125 | 128 | ||
126 | vml = vml->next; | 129 | vml = vml->next; |
127 | } | 130 | } |
128 | mmput(mm); | 131 | if (!in_exception) |
132 | mmput(mm); | ||
129 | } | 133 | } |
130 | write_unlock_irq(&tasklist_lock); | ||
131 | 134 | ||
132 | /* we were unable to find this address anywhere */ | 135 | /* we were unable to find this address anywhere */ |
133 | return printk("[<0x%p>]", (void *)address); | 136 | printk("[<0x%p>]", (void *)address); |
137 | |||
138 | done: | ||
139 | write_unlock_irqrestore(&tasklist_lock, flags); | ||
134 | } | 140 | } |
135 | #endif | 141 | #endif |
136 | 142 | ||