ARM Kernel Oops when interrupts are enabled in page fault handler or with preemptive scheduling -


can enable interrupts in page fault handler? there arm kernel contention preemptive scheduling?

i got arm kernel oops in udp receiving code config_preempt, or when interrupt enabled in fault handler.

the problem similar what user reported here. in case when send 110% load udp packets system (system drops 10% packets), kernel oops in few minutes. happens if there busybox shell scripts running, not if udp receiving program running. i've tracked data addresses looks good, buffer allocated , used before freed.

there 2 ways avoid it:

[1] when changing scheduling preempt (config_preempt) preempt_voluntary, problem goes away. known issue arm on kernel 2.6.39? preempt scheduling see problem in jffs2 after long while, not preempt_voluntary.

for moment suspected ethernet dma utilized bus blocking cpu loading tlb entry causing page fault. i'm deducing because busybox scripts need in picture, when script spawned creates address space , load many tlb entries overloading bus. if preempt_voluntary solution, can dma blocking bus ruled out?

the test i'm running ltib kernel 2.6.39.4 lpclinux on phy3250 based system.

[2] more tests showed page fault handler nested ethernet interrupts. when disabling interrupts in kernel page fault handler __dabt_svc, keep enabled in user page fault handler __dabt_user, problem goes away. if not, nest level goes 4 , oops'ed. question is: enabling interrupts in page fault handler correct?

the test code [2] goes below. lines @@@@ added or modified. capture nesting level in do_dataabort().

file arch/arm/kernel/entry-armv.s: __dabt_svc:     svc_entry ... ...     @     @ set desired irq state, call main handler     @     debug_entry r1     @@@@not_enable_irq_in_dabtsvc     ldr r2, =armv_dabtsvc_count @@@@     ldr r3, [r2]    @@@@     add r3, r3, #1  @@@@     str r3, [r2]    @@@@     msr cpsr_c, r9 @@@@disable thisk     mov r2, r2 @@@@add inst     mov r2, sp     bl  do_dataabort      @     @ irqs off again before pulling preserved data off stack     @     disable_irq_notrace      ldr r2, =armv_dabtsvc_count @@@@     ldr r3, [r2]    @@@@     sub r3, r3, #1  @@@@     str r3, [r2]    @@@@     @     @ restore spsr , restart instruction     @     ldr r2, [sp, #s_psr]     svc_exit r2             @ return exception  unwind(.fnend      ) endproc(__dabt_svc) 

and add variable file too:

file arch/arm/kernel/entry-armv.s: @@@@save nesting level:     .data            @@@@     .align           @@@@ armv_dabtsvc_count:  @@@@     .long   0   @ count svc entry    @@@@ 

i'm trying link these up. can kernel experts see whether tests make sense? disabling interrupts in page fault handler valid solution?

edit: oops in page fault handler not first failure. there "do_bad_area" in proceeding alignment handler. subsequently failed fixup unaligned access caused page fault. yes commented below, fixing unaligned access troublesome. unaligned accesses ip_input, ip_fragment, , udp stack. once fixed in stack, problem gone.

edit again: problem 2 operations in alignment handler: fetches instruction, , fetches data instruction refers to. oops reported data access, cause fetching instruction failed first page fault failure. since fetch instruction in kernel space, page valid, indicates silicon bug. if change code fetch again succeed, confirms more silicon bug. interrupt gets picture because of excess tlb flushing brings in. short, tlb loading automatic fetching instruction in kernel space cannot fail. still failed.

i guess answer (incomplete, tested):

there problem when enabling interrupt early. __get_user() assumed used in atomic context when used interrupt enabled in do_alignment(). if interrupt-enabling deferred after point, should ok.

please 2 kernel commits. first 1 on jun 25 2011, defers interrupt-enabling. second 1 on feb 25 2013 changes uses of __get_user() probling_kernel_address().

the first commit:

the 3.x kernel removed interrupt-enabling in low-level handlers __dabt_svc , __dabt_user etc. commit message:

git diff 8b418616..02fe2845 entry-armv.s commit 02fe2845d6a837ab02f0738f6cf4591a02cc88d4 author: russell king <rmk+kernel@rm.linux.org.uk> date:   sat jun 25 11:44:06 2011 +0100      arm: entry: avoid enabling interrupts in prefetch/data abort handlers      avoid enabling interrupts if parent context had interrupts enabled     in abort handler assembly code, , move breakpoint/     page/alignment fault handlers instead.      gets rid of special-casing breakpoint fault handlers     low level abort handler path.      acked-by: deacon <will.deacon@arm.com>     signed-off-by: russell king <rmk+kernel@arm.linux.org.uk>  commit 8b4186160b7894ca4583f702a562856d5d9e9118 author: russell king <rmk+kernel@rm.linux.org.uk> date:   sat jun 25 19:25:02 2011 +0100 

and code diff snippet:

diff --git a/arch/arm/kernel/entry-armv.s b/arch/arm/kernel/entry-armv.s index d644d02..c46bafa 100644 --- a/arch/arm/kernel/entry-armv.s +++ b/arch/arm/kernel/entry-armv.s @@ -185,20 +185,15 @@ endproc(__und_invalid)  __dabt_svc:         svc_entry ... ...         dabt_helper          @ -       @ set desired irq state, call main handler +       @ call main handler         @ -       debug_entry r1 -       msr     cpsr_c, r9         mov     r2, sp         bl      do_dataabort ...... 

that confirms interrupts not need enabled in fault handlers.

the second commit:

commit b255188f90e2bade1bd11a986dd1ca4861869f4d author: russell king <rmk+kernel@arm.linux.org.uk> date:   mon feb 25 16:10:42 2013 +0000      arm: fix scheduling while atomic warning in alignment handling code      paolo pisati reports ipv6 triggers warning:      bug: scheduling while atomic: swapper/0/0/0x40000100     [<c001b1c4>] (unwind_backtrace+0x0/0xf0) [<c0503c5c>] (__schedule_bug+0x48/0x5c)     [<c0503c5c>] (__schedule_bug+0x48/0x5c) [<c0508608>] (__schedule+0x700/0x740)     [<c0508608>] (__schedule+0x700/0x740) [<c007007c>] (__cond_resched+0x24/0x34)     [<c007007c>] (__cond_resched+0x24/0x34) [<c05086dc>] (_cond_resched+0x3c/0x44)     [<c05086dc>] (_cond_resched+0x3c/0x44) [<c0021f6c>] (do_alignment+0x178/0x78c)     [<c0021f6c>] (do_alignment+0x178/0x78c) [<c00083e0>] (do_dataabort+0x34/0x98)     [<c00083e0>] (do_dataabort+0x34/0x98) [<c0509a60>] (__dabt_svc+0x40/0x60)     exception stack(0xc0763d70 0xc0763db8)     [<c0509a60>] (__dabt_svc+0x40/0x60) [<c02a8490>] (__csum_ipv6_magic+0x8/0xc8)  fix using probe_kernel_address() stead of __get_user().  arch/arm/mm/alignment.c |   11 ++++------- 

Comments

Popular posts from this blog

user interface - Python attempting to create a simple gui, getting "AttributeError: 'MainMenu' object has no attribute 'intro_screen'" -

jquery - Common JavaScript snippet to share files on Google Drive, Dropbox, Box.net or SkyDrive -

Android Gson.fromJson error -