From 885be03b069131d242506f0f717d38659b2bdb6c Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 29 Oct 2007 17:20:41 +0800 Subject: [PATCH] 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 Signed-off-by: Bryan Wu --- arch/blackfin/kernel/traps.c | 30 ++++++++++++++++++------------ 1 file 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) int kstack_depth_to_print = 48; #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 task_struct *p; struct mm_struct *mm; - unsigned long offset; + unsigned long flags, offset; + unsigned int in_exception = bfin_read_IPEND() & 0x10; #ifdef CONFIG_KALLSYMS unsigned long symsize; @@ -75,9 +76,10 @@ static int printk_address(unsigned long address) /* yeah! kernel space! */ if (!modname) 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, (unsigned long)offset); + return; } #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 * bit more specific */ - write_lock_irq(&tasklist_lock); + write_lock_irqsave(&tasklist_lock, flags); for_each_process(p) { - mm = get_task_mm(p); + mm = (in_exception ? p->mm : get_task_mm(p)); if (!mm) continue; @@ -117,20 +119,24 @@ static int printk_address(unsigned long address) else offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); - write_unlock_irq(&tasklist_lock); - mmput(mm); - return printk("<0x%p> [ %s + 0x%lx ]", - (void *)address, name, offset); + printk("<0x%p> [ %s + 0x%lx ]", + (void *)address, name, offset); + if (!in_exception) + mmput(mm); + goto done; } vml = vml->next; } - mmput(mm); + if (!in_exception) + mmput(mm); } - write_unlock_irq(&tasklist_lock); /* 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