ARM Linux 内核 panic 之cache 一致性 ——Cortex-A9多核cache和TLB一致性广播

Cortex-A9的多喝CPU可以接收和执行一致性广播操作,当其使能并处于SMP模式时。本文以内核的panic为例,在给出内核panic后的真正原因后,讨论Cortex-A9多核的cache和TLB的一致性广播,实际使用中应该怎么设置。

1 多核启动android失败

内核版本:3.0.15           CPU:Freescale Imx6Q(Cortex-A9四核)

芯片特点:支持ARM TrustZone

操作步骤:主核CPU0以Secure模式启动后,切换到NS模式,然后启动内核。内核启动其它的三个CPU,它们也会切换到NS模式,最后启动Android系统。

但是启动失败了,后来发现内核只是panic,并没有彻底死机。为了确认panic后的状态,在内核的 arch/arm/kernel/smp.c文件,do_local_timer函数中,打印CPU的ID和时钟节拍,发现panic后,这个中断患有,信息还可以打印出来。

原始日志如下:

[   24.707074] request_suspend_state: wakeup (3->0) at 24564020006 (1970-01-02 00:14:26.233322336 UTC)

[   24.719704] in panic, line:75     cpu:3

[   24.726012] Kernel panic - not syncing: Attempted to kill init!

[   24.732338] [<c004c65c>] (unwind_backtrace+0x0/0xfc) from [<c05633a0>] (panic+0x88/0x1b4)

[   24.740586] [<c05633a0>] (panic+0x88/0x1b4) from [<c0076c60>] (do_exit+0x664/0x710)

[   24.748278] [<c0076c60>] (do_exit+0x664/0x710) from [<c0076d48>] (do_group_exit+0x3c/0xbc)

[   24.756581] [<c0076d48>] (do_group_exit+0x3c/0xbc) from [<c0082918>] (get_signal_to_deliver+0x1f8/0x430)

[   24.766107] [<c0082918>] (get_signal_to_deliver+0x1f8/0x430) from [<c0048fec>] (do_signal+0x94/0x534)

[   24.775440] [<c0048fec>] (do_signal+0x94/0x534) from [<c00494c4>] (do_notify_resume+0x38/0x44)

[   24.784162] [<c00494c4>] (do_notify_resume+0x38/0x44) from [<c0046698>] (work_pending+0x24/0x28)

[   24.792971] CPU1: stopping

[   24.795700] [<c004c65c>] (unwind_backtrace+0x0/0xfc) from [<c00402d4>] (do_IPI+0x188/0x1bc)

[   24.804064] [<c00402d4>] (do_IPI+0x188/0x1bc) from [<c004608c>] (__irq_svc+0x4c/0xe8)

[   24.811895] Exception stack(0xd7551d78 to 0xd7551dc0)

[   24.816948] 1d60:                                                       4657775f 00000001

[   24.825130] 1d80: 00000101 00000101 cbf48cc0 d6c4a758 40464000 cbecaee0 4657775f d6c0d190

[   24.833313] 1da0: c07dde00 0004a466 c0771c80 d7551dc0 c00de290 c0050688 60000113 ffffffff

[   24.841505] [<c004608c>] (__irq_svc+0x4c/0xe8) from [<c0050688>] (__sync_icache_dcache+0x14/0xa0)

[   24.850385] [<c0050688>] (__sync_icache_dcache+0x14/0xa0) from [<d6c0d000>] (0xd6c0d000)

[   24.858482] CPU0: stopping

[   24.861209] [<c004c65c>] (unwind_backtrace+0x0/0xfc) from [<c00402d4>] (do_IPI+0x188/0x1bc)

[   24.869573] [<c00402d4>] (do_IPI+0x188/0x1bc) from [<c004608c>] (__irq_svc+0x4c/0xe8)

[   24.877405] Exception stack(0xd752bec8 to 0xd752bf10)

[   24.882460] bec0:                   d7610180 00100073 00000000 00000000 d7610180 00000000

[   24.890642] bee0: 4ae957df d76cf208 cbaed9ec 40083000 d6739000 40082fff 00000001 d752bf10

[   24.898821] bf00: c00e5d80 c00e5d80 60000013 ffffffff

[   24.903884] [<c004608c>] (__irq_svc+0x4c/0xe8) from [<c00e5d80>] (mprotect_fixup+0x318/0x410)

[   24.912417] [<c00e5d80>] (mprotect_fixup+0x318/0x410) from [<c00e5f94>] (sys_mprotect+0x11c/0x1c0)

[   24.921385] [<c00e5f94>] (sys_mprotect+0x11c/0x1c0) from [<c0046640>] (ret_fast_syscall+0x0/0x30)

[   24.930264] CPU2: stopping

[   24.932988] [<c004c65c>] (unwind_backtrace+0x0/0xfc) from [<c00402d4>] (do_IPI+0x188/0x1bc)

[   24.941349] [<c00402d4>] (do_IPI+0x188/0x1bc) from [<c0046328>] (__irq_usr+0x48/0xe0)

[   24.949181] Exception stack(0xd75e9fb0 to 0xd75e9ff8)

[   24.954236] 9fa0:                                     405923ec 401d9688 01010101 07000000

[   24.962418] 9fc0: 78635f5f 5f5f0076 4058ecb4 4058e344 40590bd4 401d9686 401d9686 40238a60

[   24.970598] 9fe0: 00005f5f becb84a8 b0003c5b b0001774 60000010 ffffffff

[   25.073049] in do_local_timer, line:453  cpu:3

[   26.073044] in do_local_timer, line:453    cpu:3

跟踪内核发现,这个panic的执行流程是这样的。

work_pending -> do_notify_resume -> do_signal -> get_signal_to_deliver -> do_group_exit ->

do_exit -> exit_notify -> forget_original_parent -> find_new_reaper -> panic("Attempted to kill init!");

涉及到线程、进程的退出,以及线程父子之间的关系,暂时无法分析出来。

怎么会走到kill init这一步,考虑到是多核环境下出现的,则尝试改为单核启动系统,然后再手动启动其它CPU,见下节描述。

2 手动启动其它的CPU

单核启动Android不死机,此时手动用命令启动其它CPU。

echo 1 > /sys/devices/system/cpu/cpu1/online

这样CPU1就可以起来,一段时间后,内核又panic了,日志如下。

[   88.604151] XXXXXXXXXX  in panic, line:75        cpu:0

[   88.610321] Kernel panic - not syncing: Attempted to kill init!

[   88.619172] [<c004c65c>] (unwind_backtrace+0x0/0xfc) from [<c05633a0>] (panic+0x88/0x1b4)

[   88.627741] [<c05633a0>] (panic+0x88/0x1b4) from [<c0076c60>] (do_exit+0x664/0x710)

[   88.635424] [<c0076c60>] (do_exit+0x664/0x710) from [<c0076d48>] (do_group_exit+0x3c/0xbc)

[   88.643713] [<c0076d48>] (do_group_exit+0x3c/0xbc) from [<c0082918>] (get_signal_to_deliver+0x1f8/0x430)

root@android:/ # [   88.653215] [<c0082918>] (get_signal_to_deliver+0x1f8/0x430) from [<c0048fec>] (do_signal+0x94/0x534)

[   88.663905] [<c0048fec>] (do_signal+0x94/0x534) from [<c00494c4>] (do_notify_resume+0x38/0x44)

[   88.672545] [<c00494c4>] (do_notify_resume+0x38/0x44) from [<c0046698>] (work_pending+0x24/0x28)

[   88.681352] CPU1: stopping

[   88.684082] [<c004c65c>] (unwind_backtrace+0x0/0xfc) from [<c00402d4>] (do_IPI+0x188/0x1bc)

[   88.692449] [<c00402d4>] (do_IPI+0x188/0x1bc) from [<c004608c>] (__irq_svc+0x4c/0xe8)

[   88.700281] Exception stack(0xd2cf1f90 to 0xd2cf1fd8)

[   88.705337] 1f80:                                     00000020 c0771aa4 d2cf1fd8 00000000

[   88.713520] 1fa0: d2cf0000 c07d0624 c0567c74 c077a0f4 1000406a 412fc09a 00000000 00000000

[   88.721702] 1fc0: 00000001 d2cf1fd8 c0053aec c00471dc 60000013 ffffffff

[   88.728328] [<c004608c>] (__irq_svc+0x4c/0xe8) from [<c00471dc>] (default_idle+0x24/0x28)

[   88.736514] [<c00471dc>] (default_idle+0x24/0x28) from [<c00475b4>] (cpu_idle+0xbc/0xfc)

[   88.744612] [<c00475b4>] (cpu_idle+0xbc/0xfc) from [<10560094>] (0x10560094)

[   89.321214] in do_local_timer, line:453    cpu:0

[   90.291213] in do_local_timer, line:453    cpu:0

[   91.291213] in do_local_timer, line:453    cpu:0

panic的信息跟上一节是一样的,都是按照那样的流程,最后走入了kill init那一步。

3 为何多核SMP会panic

既然能够定位到是多核导致的,只能将多核相关的寄存器仔细查看了。

3.1 NS访问控制寄存器

NSACR寄存器的描述如下图所示。这个寄存器在S模式是可以读写的,NS模式则为只读。

它的NS_SMP位可以决定NS模式下,能否修改辅助控制寄存器的SMP位。

3.2 辅助控制寄存器

辅助控制寄存器如下所述,相关的是。

一致性模式,SMP或者AMP;

广播cache、分支预测、TLB的一致性操作。

S模式下可以读写;

NS下只读,若NSACR.NS_SMP是0;若这个位变成1,则NS下可以读写,这种情况下,其它位都是写忽略的,除了SMP位

根据这个寄存器的描述,就是不管是否设置了它的FW位,它都可以从同簇的其它CPU那里,发送或者接收对内部共享的写回、写分配的一致性请求。

言外之意:我的理解是,若是设置了SMP bit,则必须设置FW bit

基于这个推测,结合上面这个寄存器的描述,CPU这样设置。

在S模式,首先设置NSACR的NS_SMP位是1,然后设置辅助控制寄存器的SMP、FW位也是1,这样切换到NS模式后,也能修改辅助控制寄存器的SMP位,而它的FW位也是1。

经过这样设置,多核启动Android成功了,系统没有再出现panic。

4 后续问题怎么解决

上面的问题,是在定位到是多核导致后,经过修改寄存器,然后解决的。

至于怎么根据panic的Kill init信息去跟踪,然后推导出是cache一致性没有处理好,最后内核奔溃的,没有好的思路。

就是出现 Kernel panic - not syncing: Attempted to kill init!

这个问题还是没有找到根本的解决思路。

ARM Linux 内核 panic 之cache 一致性 ——Cortex-A9多核cache和TLB一致性广播的更多相关文章

  1. ARM Linux 内核 panic 之cache 一致性 ——cci-400 cache一致互联

    ARM Linux 内核 panic 之cache 一致性 ——cci-400 cache一致互联 CCI-400 集合了互联和一致性功能,有 2 个 ACE slave 接口和 3 个 ACE-Li ...

  2. ARM Linux内核Input输入子系统浅解

    --以触摸屏驱动为例 第一章.了解linux input子系统         Linux输入设备总类繁杂,常见的包括有按键.键盘.触摸屏.鼠标.摇杆等等,他们本身就是字符设备,而linux内核将这些 ...

  3. ARM linux内核启动时几个关键地址【转】

    转自:http://www.cnblogs.com/armlinux/archive/2011/11/06/2396787.html 1.       内核启动地址1.1.   名词解释ZTEXTAD ...

  4. ubuntu 交叉编译arm linux 内核小例子

    下载arm-linux-gcc 4.2.3http://code.google.com/p/princess-alist/downloads/detail?name=arm-linux-gcc-4.3 ...

  5. (repost)在ARM Linux内核中增加一个新的系统调用

    实验平台内核版本为4.0-rc1,增加一仅仅打印Hello World的syscall,最后我们在用户空间swi验证 实验平台内核版本为4.0-rc1,增加的系统调用仅仅是简单打印一个Hello Wo ...

  6. ARM Linux内核源码剖析索引

    start_kernel -->asm-offset.h 生成 -->proc_info_list   -->machine_desc -->__vet_atags --> ...

  7. Linux内核启动流程分析(一)【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-3380535.html 很久以前分析的,一直在电脑的一个角落,今天发现贴出来和大家分享下.由于是word直接 ...

  8. linux 内核启动流程

    Linux内核启动流程详细分析: http://www.linuxidc.com/Linux/2014-10/108034.htm ARM Linux内核启动过程: http://blog.csdn. ...

  9. ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现

    ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现 承接 http://www.wowotech.net/pm_subsystem/suspend_and_re ...

随机推荐

  1. 前端(三):JavaScript基础

    JavaScript是一种属于网络的脚本语言,常用来为网页添加各式各样的动态功能,是一种动态类型.弱类型.基于原型的语言.它包括三个部分:ECMAScript.BOM和DOM.ECMAScript描述 ...

  2. PHP三维优先级运算

    昨天去某大型公司面试,做了一套面试题,整套面试题的基础要求比较高,对于js的使用有一定的要求.在本次面试中碰到PHP三维运算优先级的问题,先看题: <?php $b=20; $c=40; $a= ...

  3. AS开发实战第二章学习笔记——其他

    第二章学习笔记(1.19-1.22)像素Android支持的像素单位主要有px(像素).in(英寸).mm(毫米).pt(磅,1/72英寸).dp(与设备无关的显示单位).dip(就是dp).sp(用 ...

  4. 求解2的N次幂的问题(多种方法)

    #include <iostream> using namespace std; //计算2的N次幂 //一般方法,时间复杂度为2^n __int64 pow2(int n) { __in ...

  5. Nancy使用Razor视图引擎时,提示对C:\Windows\temp 没有权限访问的问题

    Nancy下使用Razor视图需要添加DLL文件引用,通过Nuget安装: 发布网站,在IIS上建立站点后,提示错误:对C:\Windows\temp\XXXX 的访问被拒绝(在VS里F5调试的时候没 ...

  6. Redis源码学习1-sds.c

    https://github.com/huangz1990/redis-3.0-annotated/blob/unstable/src/sds.c#L120 /* SDSLib, A C dynami ...

  7. vscode:解决操作git总让输入用户名及密码问题

    只要是使用git操作,不管是同步,拉去,克隆,vscode总让我们输入用户名及密码,是一件很繁琐的事情 我们打开终端,会看到cmd定位在我们仓库位置,我们只要添加:git config --globa ...

  8. June 30th 2017 Week 26th Friday

    Love me little and love me long. 不求情意浓,但愿情意久. Some people say beautiful young people are the creatur ...

  9. Geekforgeek week1

    1. is palindrome solution 1: check to reverse the digit, if they are the same number https://www.gee ...

  10. spring集成ehcache本地缓存

    1.maven依赖 <!-- ehcache 相关依赖 --> <dependency> <groupId>net.sf.ehcache</groupId&g ...