Kernel 在页面错误处理程序中启用中断或使用抢占式调度时,ARM内核OOP

Kernel 在页面错误处理程序中启用中断或使用抢占式调度时,ARM内核OOP,kernel,arm,tlb,page-fault,preemptive,Kernel,Arm,Tlb,Page Fault,Preemptive,能否在页面错误处理程序中启用中断?是否存在ARM内核与抢占式调度的争用 我在UDP中得到了一个ARM内核oops,接收带有CONFIG_PREEMPT的代码,或者在故障处理程序中启用了中断 问题类似于。但在我的例子中,当我向系统发送110%的loadudp数据包(系统丢弃大约10%的数据包)时,内核oop只需几分钟。只有在某些busybox shell脚本正在运行时才会发生这种情况,而不是只有UDP接收程序正在运行时才会发生这种情况。我跟踪了数据地址,它看起来总是很好,缓冲区在释放之前就被分配和

能否在页面错误处理程序中启用中断?是否存在ARM内核与抢占式调度的争用

我在UDP中得到了一个ARM内核oops,接收带有CONFIG_PREEMPT的代码,或者在故障处理程序中启用了中断

问题类似于。但在我的例子中,当我向系统发送110%的loadudp数据包(系统丢弃大约10%的数据包)时,内核oop只需几分钟。只有在某些busybox shell脚本正在运行时才会发生这种情况,而不是只有UDP接收程序正在运行时才会发生这种情况。我跟踪了数据地址,它看起来总是很好,缓冲区在释放之前就被分配和使用了

有两种方法可以避免这种情况:

[1] 当将调度从preempt(CONFIG_preempt)更改为preempt_自愿时,问题就消失了。这是内核2.6.39上ARM的已知问题吗?使用preempt调度,我在很长一段时间后也看到了jffs2中的问题,但使用preempt\u时没有

有那么一会儿,我怀疑是以太网DMA充分利用了总线,从而阻止了CPU加载其TLB条目,从而导致了页面错误。我这样推断是因为busybox脚本需要出现在图片中,当脚本生成时,它会创建地址空间并加载许多TLB条目,从而导致总线过载。如果抢占是一种解决方案,DMA阻塞总线可以被排除吗

我正在运行的测试是基于phy3250的系统上的LTIB内核2.6.39.4 lpclinux

[2] 更多的测试表明,页面错误处理程序是由以太网中断嵌套的。当在内核页面错误处理程序_dabt_svc中禁用中断,但在用户页面错误处理程序_dabt_user中保持启用时,问题就消失了。如果不是,嵌套级别将上升到4,它将oops。所以问题是:在页面错误处理程序中启用中断是否正确

[2]的测试代码如下所示。将添加或修改带@@@1的行。然后在do_DataAbort()中捕获嵌套级别

并将变量也添加到文件中:

file arch/arm/kernel/entry-armv.S:
@@@@save nesting level:
    .data            @@@@
    .align           @@@@
armv_dabtsvc_count:  @@@@
    .long   0   @ count svc entry    @@@@
我正试图把这些联系起来。内核专家能看到所有的测试是否都有意义吗?在页面错误处理程序中禁用中断是有效的解决方案吗

编辑:页面错误处理程序中的oops不是第一个失败。正在进行的对齐处理程序中存在“do_bad_区域”。随后,未能修复未对齐的访问导致页面错误。是的,正如下面有人评论的那样,修复未对齐的访问非常麻烦。这些未对齐的访问来自ip_输入、ip_片段和udp堆栈。一旦我解决了堆栈中的所有问题,问题就消失了


再次编辑:问题在于对齐处理程序中的两个操作:它获取指令,并获取指令引用的数据。oops由数据访问报告,但原因是由于第一页错误导致获取指令失败。由于fetch指令位于内核空间,因此页面始终有效,这表明存在硅错误。如果更改代码以再次获取,它将成功,这证实它更有可能是一个硅错误。中断进入图片,因为它带来了过多的TLB刷新。简而言之,TLB加载是自动的,因此在内核空间中获取指令不会失败。但还是失败了

我想这就是答案(不完整,有待测试):

过早启用中断时出现问题。当在do_alignment()中启用中断时,假定在原子上下文中使用uu get_user()。如果中断启用延迟到该点之后,则一切正常

请查看两个内核提交。第一次是在2011年6月25日,推迟了中断启用。第二次是在2013年2月25日,它将uuu get_user()的用法更改为probling_kernel_address()

第一次提交:

3.x内核删除了低级处理程序uu dabt_svc和uu dabt_user等中的中断启用。提交消息:

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 the parent context had interrupts enabled
    in the abort handler assembly code, and move this into the breakpoint/
    page/alignment fault handlers instead.

    This gets rid of some special-casing for the breakpoint fault handlers
    from the low level abort handler path.

    Acked-by: Will 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
这确认了中断不需要在故障处理程序中过早启用

第二次提交:

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 that IPv6 triggers this warning:

    BUG: scheduling while atomic: swapper/0/0/0x40000100
    [<c001b1c4>] (unwind_backtrace+0x0/0xf0) from [<c0503c5c>] (__schedule_bug+0x48/0x5c)
    [<c0503c5c>] (__schedule_bug+0x48/0x5c) from [<c0508608>] (__schedule+0x700/0x740)
    [<c0508608>] (__schedule+0x700/0x740) from [<c007007c>] (__cond_resched+0x24/0x34)
    [<c007007c>] (__cond_resched+0x24/0x34) from [<c05086dc>] (_cond_resched+0x3c/0x44)
    [<c05086dc>] (_cond_resched+0x3c/0x44) from [<c0021f6c>] (do_alignment+0x178/0x78c)
    [<c0021f6c>] (do_alignment+0x178/0x78c) from [<c00083e0>] (do_DataAbort+0x34/0x98)
    [<c00083e0>] (do_DataAbort+0x34/0x98) from [<c0509a60>] (__dabt_svc+0x40/0x60)
    Exception stack(0xc0763d70 to 0xc0763db8)
    [<c0509a60>] (__dabt_svc+0x40/0x60) from [<c02a8490>] (__csum_ipv6_magic+0x8/0xc8)

Fix this by using probe_kernel_address() stead of __get_user().
 arch/arm/mm/alignment.c |   11 ++++-------
提交b255188f90e2bade1bd11a986dd1ca4861869f4d
作者:拉塞尔·金
日期:星期一2013年2月25日16:10:42+0000
ARM:修复对齐处理代码中原子警告时的调度
Paolo Pisati报告说IPv6触发了此警告:
错误:原子时调度:swapper/0/0/0x40000100
[](从[]展开回溯+0x0/0xf0)(\uuuuu计划\uu错误+0x48/0x5c)
[](uuu schedule_ubug+0x48/0x5c)来自[](uu schedule+0x700/0x740)
[](uu计划+0x700/0x740)从[](uu cond_uresched+0x24/0x34)
[](第二次重新扫描+0x24/0x34)来自[](第二次重新扫描+0x3c/0x44)
[](第二次重新扫描+0x3c/0x44)从[](执行对齐+0x178/0x78c)
[](do_校准+0x178/0x78c)从[](do_数据中止+0x34/0x98)
[](数据中止+0x34/0x98)来自[](数据中止+0x40/0x60)
异常堆栈(0xc0763d70到0xc0763db8)
[](uu dabt_svc+0x40/0x60)来自[](uu csum\u ipv6\u magic+0x8/0xc8)
通过使用probe_kernel_address()而不是u get_user()来修复此问题。
拱/臂/毫米/对准。c | 11++++-------

我想这就是答案(不完整,有待测试):

过早启用中断时出现问题。当在do_alignment()中启用中断时,假定在原子上下文中使用uu get_user()。如果中断启用延迟到该点之后,则一切正常

请查看两个内核提交。第一次是在2011年6月25日,推迟了中断启用。第二次是在2013年2月25日,它将uuu get_user()的用法更改为probling_kernel_address()

第一次提交:

3.x内核删除了低级处理程序uu dabt_svc和uu dabt_user等中的中断启用。提交消息:

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 the parent context had interrupts enabled
    in the abort handler assembly code, and move this into the breakpoint/
    page/alignment fault handlers instead.

    This gets rid of some special-casing for the breakpoint fault handlers
    from the low level abort handler path.

    Acked-by: Will 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
这确认了中断不需要在故障处理程序中过早启用

第二次提交:

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 that IPv6 triggers this warning:

    BUG: scheduling while atomic: swapper/0/0/0x40000100
    [<c001b1c4>] (unwind_backtrace+0x0/0xf0) from [<c0503c5c>] (__schedule_bug+0x48/0x5c)
    [<c0503c5c>] (__schedule_bug+0x48/0x5c) from [<c0508608>] (__schedule+0x700/0x740)
    [<c0508608>] (__schedule+0x700/0x740) from [<c007007c>] (__cond_resched+0x24/0x34)
    [<c007007c>] (__cond_resched+0x24/0x34) from [<c05086dc>] (_cond_resched+0x3c/0x44)
    [<c05086dc>] (_cond_resched+0x3c/0x44) from [<c0021f6c>] (do_alignment+0x178/0x78c)
    [<c0021f6c>] (do_alignment+0x178/0x78c) from [<c00083e0>] (do_DataAbort+0x34/0x98)
    [<c00083e0>] (do_DataAbort+0x34/0x98) from [<c0509a60>] (__dabt_svc+0x40/0x60)
    Exception stack(0xc0763d70 to 0xc0763db8)
    [<c0509a60>] (__dabt_svc+0x40/0x60) from [<c02a8490>] (__csum_ipv6_magic+0x8/0xc8)

Fix this by using probe_kernel_address() stead of __get_user().
 arch/arm/mm/alignment.c |   11 ++++-------
提交b255188f90e2bade1bd11a986dd1ca4861869f4d
金