[445713.507663] Pid: , comm: -IFileSender Tainted: G    B      ENX 3.0.-0.47.-default # ZTE Grantley/S1008
[445713.507671] RIP: :[<ffffffff810fb2cb>] [<ffffffff810fb2cb>] find_get_pages_contig+0x5b/0x110
[445713.507678] RSP: :ffff883edfc2fab8 EFLAGS:
[445713.507679] RAX: ffff881f68ef68d0 RBX: RCX:
[445713.507681] RDX: RSI: ffffea000a9164e8 RDI: ffffea000a9164e0
[445713.507682] RBP: R08: R09: ffff883edfc2fa78
[445713.507683] R10: R11: 000000000000003f R12: ffffffff8146ffee
[445713.507684] R13: 000000000006cc46 R14: 00000000000007fe R15: ffffe8e001baa620
[445713.507686] FS: 00007f06f82a9700() GS:ffff88207fda0000() knlGS:
[445713.507688] CS: DS: ES: CR0:
[445713.507689] CR2: 00007fd39233d810 CR3: 0000003ec0289000 CR4: 00000000001407e0
[445713.507690] DR0: DR1: DR2:
[445713.507691] DR3: DR6: 00000000ffff0ff0 DR7:
[445713.507693] Process -IFileSender (pid: , threadinfo ffff883edfc2e000, task ffff883edfc2c480)
[445713.507694] Stack:
[445713.507700] 000000059715f240 ffff881f6a1bd2e8 0000000000003ffb
[445713.507704] ffff881dab7a5180 0000000000004c04
[445713.507706] ffff883edfc2fdf8 ffffffff811898f1 ffff881d69cf4c40 ffff881dab7a5180
[445713.507709] Call Trace:
[445713.507718] [<ffffffff811898f1>] __generic_file_splice_read+0x111/0x4c0
[445713.507722] [<ffffffff81189ceb>] generic_file_splice_read+0x4b/0x90
[445713.507767] [<ffffffffa05fec5a>] xfs_file_splice_read+0x14a/0x200 [xfs]
[445713.507832] [<ffffffff81188c6c>] splice_direct_to_actor+0xcc/0x1d0
[445713.507837] [<ffffffffa070a9ab>] do_sendfile+0x1db/0x270 [witdriver]
[445713.507844] [<ffffffffa0716b3a>] my_sendfile+0x2da/0x530 [witdriver]
[445713.507863] [<ffffffff8146f5f2>] system_call_fastpath+0x16/0x1b
[445713.507870] [<00007f07326683c9>] 0x7f07326683c8

获取页面超时,反汇编响应的代码,确定了是在进行page计数增加。

        if (!page_cache_get_speculative(page))
goto repeat;

根据代码逻辑,page的计数不对,本来page的计数为0是一个瞬间状态,结果却一直在循环。

查看crash之前的打印,找到对应的日志为:

kernel: [111747.127259] BUG: Bad page state in process -IFileSender  pfn:2375c8e
kernel: [111747.127259] BUG: Bad page state in process -IFileSender pfn:2375c8e
kernel: [111747.127263] page:ffffea007c1c3f10 count: mapcount: mapping:ffff882b63e766e0 index:0x3ffc
kernel: [111747.127263] page:ffffea007c1c3f10 count: mapcount: mapping:ffff882b63e766e0 index:0x3ffc
kernel: [111747.127265] page flags: 0x60000000080010(uptodate|mappedtodisk)
kernel: [111747.127265] page flags: 0x60000000080010(uptodate|mappedtodisk)
kernel: [111747.127269] Pid: , comm: -IFileSender Tainted: G ENX 3.0.-0.47.-default #
kernel: [111747.127269] Pid: , comm: -IFileSender Tainted: G ENX 3.0.-0.47.-default #
kernel: [111747.127271] Call Trace:
kernel: [111747.127271] Call Trace:
kernel: [111747.127284] [<ffffffff81004b95>] dump_trace+0x75/0x300
kernel: [111747.127284] [<ffffffff81004b95>] dump_trace+0x75/0x300
kernel: [111747.127290] [<ffffffff81464663>] dump_stack+0x69/0x6f
kernel: [111747.127290] [<ffffffff81464663>] dump_stack+0x69/0x6f
kernel: [111747.127296] [<ffffffff81100da1>] bad_page+0xb1/0x120
kernel: [111747.127296] [<ffffffff81100da1>] bad_page+0xb1/0x120
kernel: [111747.127300] [<ffffffff81101306>] free_pages_prepare+0xe6/0x110
kernel: [111747.127300] [<ffffffff81101306>] free_pages_prepare+0xe6/0x110
kernel: [111747.127304] [<ffffffff81104d69>] free_hot_cold_page+0x49/0x1f0
kernel: [111747.127304] [<ffffffff81104d69>] free_hot_cold_page+0x49/0x1f0
kernel: [111747.127311] [<ffffffffa0621224>] wit_free_shinfo_pages+0x34/0x50 [witdriver]
kernel: [111747.127311] [<ffffffffa0621224>] wit_free_shinfo_pages+0x34/0x50 [witdriver]
kernel: [111747.127331] [<ffffffffa0631306>] my_writev+0x2b6/0x6e0 [witdriver]
kernel: [111747.127331] [<ffffffffa0631306>] my_writev+0x2b6/0x6e0 [witdriver]
kernel: [111747.127341] [<ffffffff8146f5f2>] system_call_fastpath+0x16/0x1b
kernel: [111747.127341] [<ffffffff8146f5f2>] system_call_fastpath+0x16/0x1b
kernel: [111747.127361] [<00007f2018ce33c9>] 0x7f2018ce33c8
kernel: [111747.127361] [<00007f2018ce33c9>] 0x7f2018ce33c8

从这个打印,知道了我们当时流程释放页的时候,page的计数为0了,此时的mapping指针还在,说明了不该释放的页给释放了。

这种计数问题本来很头疼,偶然间看到page的index 为:

kernel: [111747.127263] page:ffffea007c1c3f10 count: mapcount: mapping:ffff882b63e766e0 index:0x3ffc------------这个index

查看了其他类似的打印发现这个index都靠近0x4000,而这个0x4000是我们一种业务文件的固定大小。

再查找对应的业务日志,发现当时sendfile调用失败,然后使用writev方式发送文件,而writev的时候,又出现了调用方传送的参数不对的情况,导致我们内核模块在释放内存的时候,

将发送失败那几页page释放多执行了一次。从而使得page计数被减成0了。

void put_page(struct page *page)
{
if (unlikely(PageCompound(page)))
put_compound_page(page);
else if (put_page_testzero(page))//原子计数减,然后判断是否为0,为0则继续释放
__put_single_page(page);
}

这个page因为还在被inode的radix树管理,所以那边读文件找page的时候,发现计数为0,则循环等待,否则加1,这样的话,导致了一个死循环,因为这个计数本来不应该长时间为0,是被

我们释放计数错了才导致为0的。

void free_hot_cold_page(struct page *page, int cold)
{
struct zone *zone = page_zone(page);
struct per_cpu_pages *pcp;
unsigned long flags;
int migratetype;
int wasMlocked = __TestClearPageMlocked(page); #ifdef CONFIG_XEN
WARN_ON(PageForeign(page) && wasMlocked);
#endif
if (!free_pages_prepare(page, ))
return;

最终由于mapping指针不为NULL而在bad_page 的流程中打印警告。

不过这种page会不会used after free呢?不会的,因为page的计数虽然为0,但是并没有放到管理单元中去,假设以后再也不访问这个page,则只会泄露。

这种循环,会因为定时器中断而中断,最终系统hung住:

 kernel: [217186.608729]  [<ffffffff8102735a>] arch_trigger_all_cpu_backtrace+0x5a/0xa0
kernel: [217186.608729] [<ffffffff8102735a>] arch_trigger_all_cpu_backtrace+0x5a/0xa0---------------等回调,
kernel: [217186.608734] [<ffffffff810d0021>] check_cpu_stall+0xe1/0x140
kernel: [217186.608734] [<ffffffff810d0021>] check_cpu_stall+0xe1/0x140
kernel: [217186.608738] [<ffffffff810d00a9>] __rcu_pending+0x29/0x180
kernel: [217186.608738] [<ffffffff810d00a9>] __rcu_pending+0x29/0x180
kernel: [217186.608742] [<ffffffff810d025f>] rcu_check_callbacks+0x5f/0x110
kernel: [217186.608742] [<ffffffff810d025f>] rcu_check_callbacks+0x5f/0x110
kernel: [217186.608748] [<ffffffff81071dff>] update_process_times+0x3f/0x80
kernel: [217186.608748] [<ffffffff81071dff>] update_process_times+0x3f/0x80--------------------------定时中断,更新进程时间等
kernel: [217186.608752] [<ffffffff8109615b>] tick_sched_timer+0x5b/0xc0
kernel: [217186.608752] [<ffffffff8109615b>] tick_sched_timer+0x5b/0xc0
kernel: [217186.608757] [<ffffffff81088a4e>] __run_hrtimer+0xbe/0x1a0
kernel: [217186.608757] [<ffffffff81088a4e>] __run_hrtimer+0xbe/0x1a0
kernel: [217186.608762] [<ffffffff81088d6d>] hrtimer_interrupt+0xed/0x2a0
kernel: [217186.608762] [<ffffffff81088d6d>] hrtimer_interrupt+0xed/0x2a0
kernel: [217186.608767] [<ffffffff81026da3>] smp_apic_timer_interrupt+0x63/0xa0
kernel: [217186.608767] [<ffffffff81026da3>] smp_apic_timer_interrupt+0x63/0xa0
kernel: [217186.608771] [<ffffffff8146fff3>] apic_timer_interrupt+0x13/0x20
kernel: [217186.608771] [<ffffffff8146fff3>] apic_timer_interrupt+0x13/0x20--------------被中断
kernel: [217186.608777] [<ffffffff810fb2c3>] find_get_pages_contig+0x53/0x110
kernel: [217186.608777] [<ffffffff810fb2c3>] find_get_pages_contig+0x53/0x110
kernel: [217186.608782] [<ffffffff811898f1>] __generic_file_splice_read+0x111/0x4c0
kernel: [217186.608782] [<ffffffff811898f1>] __generic_file_splice_read+0x111/0x4c0
kernel: [217186.608786] [<ffffffff81189ceb>] generic_file_splice_read+0x4b/0x90
kernel: [217186.608786] [<ffffffff81189ceb>] generic_file_splice_read+0x4b/0x90
kernel: [217186.608805] [<ffffffffa0be6c5a>] xfs_file_splice_read+0x14a/0x200 [xfs]
kernel: [217186.608805] [<ffffffffa0be6c5a>] xfs_file_splice_read+0x14a/0x200 [xfs]
kernel: [217186.608868] [<ffffffff81188c6c>] splice_direct_to_actor+0xcc/0x1d0
kernel: [217186.608868] [<ffffffff81188c6c>] splice_direct_to_actor+0xcc/0x1d0
kernel: [217186.608874] [<ffffffffa0620a8b>] do_sendfile+0x1db/0x270 [witdriver]
kernel: [217186.608874] [<ffffffffa0620a8b>] do_sendfile+0x1db/0x270 [witdriver]
kernel: [217186.608881] [<ffffffffa0630df0>] my_sendfile+0x2e0/0x540 [witdriver]
kernel: [217186.608881] [<ffffffffa0630df0>] my_sendfile+0x2e0/0x540 [witdriver]
kernel: [217186.608892] [<ffffffff8146f5f2>] system_call_fastpath+0x16/0x1b
kernel: [217186.608892] [<ffffffff8146f5f2>] system_call_fastpath+0x16/0x1b
kernel: [217186.608898] [<00007f2018ce33c9>] 0x7f2018ce33c8
kernel: [217186.608898] [<00007f2018ce33c9>] 0x7f2018ce33c8

linux 内核假死循环导致的问题的更多相关文章

  1. linux内核过高导致vm打开出错修复脚本

    #!/bin/bashVMWARE_VERSION=workstation-15.1.0TMP_FOLDER=/tmp/patch-vmwarerm -fdr $TMP_FOLDERmkdir -p ...

  2. mysql 5.7.15 vs mysql 5.6.31性能测试以及不同linux内核性能比较

    最近,将部分开发和测试环境的mysql升级到5.7之后,今天抽时间测试了下5.6和5.7 PK查询的性能,使用mysqlslap进行测试,测试结果发现在低配下,percona 5.6.31大约比5.7 ...

  3. Linux内核分析:页回收导致的cpu load瞬间飙高的问题分析与思考--------------蘑菇街技术博客

    http://mogu.io/156-156 摘要 本文一是为了讨论在Linux系统出现问题时我们能够借助哪些工具去协助分析,二是讨论出现问题时大致的可能点以及思路,三是希望能给应用层开发团队介绍一些 ...

  4. Linux内核升级导致无法启动,Kernel panic - not syncing Unable to mount root fs on unknown block(0,0)

    问题原因:内核的某次升级,导致系统无法启动. 首先进入recovery模式:引导界面选择-->Ubuntu高级-->出现的选项中选择能够启动的recovery模式(几个内核版本分别试一下) ...

  5. 一个linux内核编译时遇到的perl语法导致的编译问题解决

    在编译linux内核时,遇到了一个比较诡异的问题.具体log如下: Can't locate strict.pm in @INC (you may need to install the strict ...

  6. 升级Linux内核导致vmware无法使用(vmnet模块无法编译)解决方式

    近期将ubuntu升级到了14.04,出现了vmware无法启动的情况. 详细表现为:每次启动的时候都会弹出一个VMWare Kernel Module Updater的对话框,要求依据当前内核版本号 ...

  7. 【漏洞预警】Intel爆CPU设计问题,导致win和Linux内核重设计(附测试poc)

    目前研究人员正抓紧检查 Linux 内核的安全问题,与此同时,微软也预计将在本月补丁日公开介绍 Windows 操作系统的相关变更. 而 Linux 和 Windows 系统的这些更新势必会对 Int ...

  8. Linux内核同步

    Linux内核剖析 之 内核同步 主要内容 1.内核请求何时以交错(interleave)的方式执行以及交错程度如何. 2.内核所实现的基本同步机制. 3.通常情况下如何使用内核提供的同步机制. 内核 ...

  9. 浅析Linux内核同步机制

    非常早之前就接触过同步这个概念了,可是一直都非常模糊.没有深入地学习了解过,最近有时间了,就花时间研习了一下<linux内核标准教程>和<深入linux设备驱动程序内核机制>这 ...

随机推荐

  1. java jdk版本切换

    首先看链接: 1. 这个链接清晰,但不一定能成功,但也不一定:https://blog.csdn.net/spt_dream/article/details/70673836 2. 其次这个链接比较完 ...

  2. [UE4]在UI中获取玩家角色实例

  3. [UE4]蓝图的颜色

    一.蓝色:调用的函数或事件 二.绿色:纯函数 三.紫色:函数定义 四.灰色:宏 五.白色:执行线 六.事件的定义 另外还有数据类型的颜色: 执行线是白色,数据线颜色跟数据量类型一致.

  4. 网站简介-为什么网站的ICO图标更新后,ie浏览器没有更新过来?

    为什么网站的ICO图标更新后,ie浏览器没有更新过来? 如何更新本地ico图标? 收藏夹里的网址访问后网站ico小图标怎么不会更新,还是没图标的. 如果制作了一个新的favicon.ico图标,并且已 ...

  5. 第三章: web界面操作

    3.1 zabbix的web安装 3.1.1 使用浏览器访问 http://10.0.0.61/zabbix/setup.php 在检测信息时,可查看具体的报错信息进行不同的解决 选择mysql数据库 ...

  6. 初始Golang

    Golang初识 字节跳动也就是我们常说的今日头条 1.今日头条基于Go语言构建千亿级微服务的实践 今日头条当前后端服务超过80%的流量是跑在Go构建的服务上 微服务数量超过100个 高峰QPS超过7 ...

  7. Find the peace with yourself

    The purpose of being mature is to find the real calm and peace with yourself. Or you can say the tur ...

  8. 通过OTA的方式在局域网分发iOS应用

    公司的一个项目有Android和iOS的app,Android的下载和安装都很方便,不过iOS有些麻烦,因为项目本身有些限制,主要有以下一些障碍:1.iOS的版本不是通过Appstore分发.2.出于 ...

  9. System.Drawing.Graphics.FromImage(Image image)引发内存不足

    原因:图片位深度导致的,c# gui 应该无法将32位jpg格式的图片load到内存中 通过对比可成功处理的图片 和 不能处理的图片,发现 CMYK(印刷格式)的图片是无法处理的,具体需要深入 .ne ...

  10. 《Linux性能及调优指南》第二章:监控和基准工具2.1-2.2

    翻译:飞哥 (http://hi.baidu.com/imlidapeng) 版权所有,尊重他人劳动成果,转载时请注明作者和原始出处及本声明. 原文名称:<Linux Performance a ...