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>
This commit is contained in:
Robin Getz 2007-10-29 17:20:41 +08:00 committed by Bryan Wu
parent 64307f7db3
commit 885be03b06
1 changed files with 18 additions and 12 deletions

View File

@ -54,12 +54,13 @@ void __init trap_init(void)
int kstack_depth_to_print = 48; int kstack_depth_to_print = 48;
#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
static int printk_address(unsigned long address) static void printk_address(unsigned long address)
{ {
struct vm_list_struct *vml; struct vm_list_struct *vml;
struct task_struct *p; struct task_struct *p;
struct mm_struct *mm; struct mm_struct *mm;
unsigned long offset; unsigned long flags, offset;
unsigned int in_exception = bfin_read_IPEND() & 0x10;
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
unsigned long symsize; unsigned long symsize;
@ -75,9 +76,10 @@ static int printk_address(unsigned long address)
/* yeah! kernel space! */ /* yeah! kernel space! */
if (!modname) if (!modname)
modname = delim = ""; modname = delim = "";
return printk("<0x%p> { %s%s%s%s + 0x%lx }", printk("<0x%p> { %s%s%s%s + 0x%lx }",
(void *)address, delim, modname, delim, symname, (void *)address, delim, modname, delim, symname,
(unsigned long)offset); (unsigned long)offset);
return;
} }
#endif #endif
@ -86,9 +88,9 @@ static int printk_address(unsigned long address)
* mappings of all our processes and see if we can't be a whee * mappings of all our processes and see if we can't be a whee
* bit more specific * bit more specific
*/ */
write_lock_irq(&tasklist_lock); write_lock_irqsave(&tasklist_lock, flags);
for_each_process(p) { for_each_process(p) {
mm = get_task_mm(p); mm = (in_exception ? p->mm : get_task_mm(p));
if (!mm) if (!mm)
continue; continue;
@ -117,20 +119,24 @@ static int printk_address(unsigned long address)
else else
offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
write_unlock_irq(&tasklist_lock); printk("<0x%p> [ %s + 0x%lx ]",
mmput(mm); (void *)address, name, offset);
return printk("<0x%p> [ %s + 0x%lx ]", if (!in_exception)
(void *)address, name, offset); mmput(mm);
goto done;
} }
vml = vml->next; vml = vml->next;
} }
mmput(mm); if (!in_exception)
mmput(mm);
} }
write_unlock_irq(&tasklist_lock);
/* we were unable to find this address anywhere */ /* we were unable to find this address anywhere */
return printk("[<0x%p>]", (void *)address); printk("[<0x%p>]", (void *)address);
done:
write_unlock_irqrestore(&tasklist_lock, flags);
} }
#endif #endif