这个问题困扰了我很久,平均3天死机一次,现象为:鼠标键盘不能操作,Caps灯狅闪
以下报告为本地agent调查之后生成:
内核崩溃调查报告:IEE 子系统在 slab/巨页路径触发 double fault
| 项目 | 内容 |
|---|---|
| 报告日期 | 2026-09-24 |
| 严重级别 | 严重(Kernel Panic / 系统崩溃自动重启) |
| 受影响内核 | 6.6.0-24-generic #0ok1-KYLINOS(CONFIG_IEE=y) |
| 崩溃组件 | arch/x86/kernel/iee/(麒麟定制内核子系统 IEE) |
| 是否已定位崩溃路径 | 是(iee_set_token_page_valid → do_split_huge_pmd → allocate_slab) |
| 是否与 GPU/显卡相关 | 否(推翻前期假设) |
| 是否为硬件故障 | 现有证据指向软件缺陷;硬件未证实有问题 |
1. 概述
本机在运行中会随机卡死约 10 秒后自动重启。通过 ramoops/pstore 捕获到一次真实 panic 现场,完整调用链落在麒麟定制内核子系统 IEE(arch/x86/kernel/iee/)上:
dpkg 进程 fork/clone
→ dup_task_struct → slab 分配
→ iee_set_token_page_valid
→ do_split_huge_pmd ← WARNING(arch/x86/kernel/iee/iee-func.c:77)
→ iee_rw_gate ← PANIC: double fault(RSP=0,内核栈损坏)
崩溃发生在 dpkg 安装软件、产生大量 fork/clone 期间;路径涉及 slab 分配器与 透明巨页(THP)分裂(IEE 内部操作 IEE_OP_SPLIT_HUGE_PMD)。
结论:这是一处软件缺陷,而非显卡/显存问题。 前期围绕 Intel i915(Iris Xe)"GPU hang → hard lockup"的排查方向应予修正。
2. 环境信息
| 项目 | 值 |
|---|---|
| 机型 | HUAWEI BoDE-WXX9 / M1010(华为笔记本,QUANTA 代工) |
| BIOS | 1.20(2023-07-05) |
| CPU | 11th Gen Intel Core i7-1195G7 @ 2.90GHz(Tiger Lake,8 线程) |
| 集成显卡 | Intel Iris Xe Graphics(PCI 8086:9a49) |
| 内存 | ~15.8 GiB,无 ECC |
| 存储 | NVMe SSD(1987:5013,PCI 0000:01:00.0) |
| 操作系统 | openKylin / KYLINOS(Kylin V10 系) |
| 内核 | 6.6.0-24-generic #0ok1-KYLINOS SMP PREEMPT_DYNAMIC,构建于 Mon Jun 22 14:28:34 UTC 2026,编译器 gcc (Openkylin 12.3.0-1ok3) 12.3.0 |
| 内核配置(关键) | CONFIG_IEE=y、CONFIG_TRANSPARENT_HUGEPAGE=y、CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y、CONFIG_SLUB=y、CONFIG_HARDENED_USERCOPY=y |
| 取证机制 | ramoops(固件 Reserved 区 0x70e00000,2MB)+ pstore |
3. 问题现象
- 随机死机:界面定格、无 panic 文本上屏,约 10 秒后自动重启(与
panic=10行为一致)。 - 部分事件进入固件自检/冷复位,导致内存被清空、ramoops 丢失现场。
- 本次捕获到热重启(panic → 10 秒后重启)的完整现场。
- 崩溃前 uptime 约 81653 秒,其中约 21 小时为 s2idle 休眠(见 §7)。
- 崩溃时正在执行
dpkg(安装/升级软件),存在大量 fork/clone。
4. 取证过程与证据
4.1 证据文件
| 文件 | 说明 | SHA-256 |
|---|---|---|
/var/lib/systemd/pstore/dmesg-ramoops-0 |
头部 Oops#1 Part1(1150 行) |
944490f631ee5688f1cde4a71dc9b50a39bfd73df16d524f92c0ceed135d0a99 |
/var/lib/systemd/pstore/dmesg-ramoops-1 |
头部 Panic#2 Part1(1164 行) |
6c700602e9167e090df9728922ec071bbe35fcb75ea6471a2527d331e345b70b |
两份文件是同一次崩溃:pstore 在 WARN 时写 “Oops” 记录、panic 时写 “Panic” 记录,内容除末尾收尾行外完全相同。即本次只捕获到一次 panic。
4.2 崩溃调用链(自内向外,调用者在下)
WARNING: ... at arch/x86/kernel/iee/iee-func.c:77
do_split_huge_pmd+0x21d/0x2d0
↑ iee_set_token_page_valid+0x30d/0x370
↑ allocate_slab+0x41e/0x5d0
↑ ? get_any_partial+0x11b/0x190
↑ ___slab_alloc+0x603/0xb00
↑ kmem_cache_alloc_node_noprof+0x2dd/0x3a0
↑ dup_task_struct+0x48/0x1d0
↑ copy_process+0x1e4/0x1680
↑ kernel_clone+0xc3/0x460
↑ __do_sys_clone+0x66/0x90
↑ do_syscall_64+0x7d/0x1e0
↑ entry_SYSCALL_64_after_hwframe+0x76/0xe0
WARN 上下文:
CPU: 1 PID: 42357 Comm: dpkg
Tainted: G U W
RIP: 0010:do_split_huge_pmd+0x21d/0x2d0
RAX: 80000000000001e1 RBX: ffff88847f8e3060 RDI: ffffea0005060000 (struct page)
RSI: ffff88821ef81000 RBP: ffff88821ef81000 CR2: 000000001e7a2418
CR4: 0000000000672ee0
WARN 之后立即:
traps: PANIC: double fault, error_code: 0x0
CPU: 7 PID: 42385 Comm: dpkg
RIP: 0010:iee_rw_gate+0x37/0x70
RSP: 0018:0000000000000000 ← 内核栈指针为 0(栈已损坏)
CR2: fffffffffffffff8 ← 访问 -8 偏移
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: disabled
4.3 时间线
| 内核时间 | 事件 |
|---|---|
| ~0.068s | IEE 初始化异常(见 §5.3) |
| 383s | PM: suspend entry (s2idle) 进入休眠 |
| 76486s | ACPI: EC: interrupt unblocked 唤醒(休眠约 21.1 小时) |
| 76539–76555s | kylin-vpn 反复 general protection fault(用户态) |
| 76619s 起 | PCIe AER Corrected 错误(NVMe 链路) |
| 80283–80470s | stack_test / v3 程序反复 segfault(用户态) |
| 81653s | IEE WARN → double fault → kernel panic |
5. IEE 子系统分析
5.1 IEE 是什么
IEE 是麒麟定制内核功能,源码位于 arch/x86/kernel/iee/,编译进内核(CONFIG_IEE=y,非模块)。从符号与操作码看,它围绕页表级访问控制 / 内存隔离 / 令牌(token)机制构建,深度挂钩内存管理与 slab 分配:
- 源文件:
iee.c、iee-func.c、page-slab.c、stack-slab.c - 关键函数(部分,共 104 个 IEE 符号):
init_iee_offset、iee_rw_gate、iee_rwx_gate、iee_read_token_stack、iee_read_tmp_page、iee_read_freeptr、set_iee_page、unset_iee_page、iee_set_logical_mem_ro、set_iee_page_valid/invalid、iee_set_token_page_valid/invalid、set_iee_stack_page、get_iee_stack、free_iee_stack、iee_free_task_struct_slab、iee_free_slab、kernel_physical_mapping_init_for_iee、init_memory_mapping_for_iee、iee_get_oo_objects - 操作码枚举:
IEE_OP_INIT_TOKEN、IEE_OP_INVALIDATE_TOKEN、IEE_OP_SET_TOKEN、IEE_OP_UNSET_TOKEN、IEE_OP_VALIDATE_TOKEN、IEE_OP_SET_TOKEN_PGD、IEE_OP_SPLIT_HUGE_PMD、IEE_OP_READ_*、IEE_OP_MEMCPY/MEMSET、IEE_OP_SET_FREEPTR、IEE_OP_TEST_CLEAR_BIT
其中 IEE_OP_SPLIT_HUGE_PMD 与崩溃点 do_split_huge_pmd 直接对应,说明 IEE 会在其令牌/页管理流程中主动分裂巨页 PMD。
5.2 与崩溃的关系
- 崩溃路径为
allocate_slab → iee_set_token_page_valid → do_split_huge_pmd,即 IEE 在为 slab 页建立/校验令牌时,走到了巨页 PMD 分裂逻辑。 - 该路径上的
WARNING(iee-func.c:77)触发后,紧接着iee_rw_gate发生 double fault,且RSP=0,表明 IEE 的门(gate)机制在异常后破坏了内核栈。
5.3 IEE 初始化异常(每次开机均出现)
<3>[0.067] IBT selftest: Failed!
<3>[0.068] IEE SI disabled because SMAP or SMEP is not available
<3>[0.068] IEE: testing iee_exec_entry si_test...
<3>[0.068] IEE: testing iee_exec_entry si_test... ← 重复两次
5.4 关于 SMEP/SMAP 的重要观察
/proc/cpuinfo明确报告 CPU 支持smap、smep。- 但崩溃现场 CR4 =
0x0000000000672ee0:其中 bit20(SMEP)= 0,bit21(SMAP)= 1,即内核运行在 SMEP 已关闭的状态。 - IEE 启动时也报告 “SMAP or SMEP is not available”,并据此禁用了
IEE SI。
推断(待厂商确认):内核/或 IEE 自身以 SMEP 关闭的方式运行(例如 IEE 的 rwx_gate/可执行门机制可能与 SMEP 冲突,或探测时机早于 SMEP 启用),导致 IEE SI 在半残状态下运行——但其 slab/巨页钩子仍在生效,形成不一致状态,这很可能就是崩溃的土壤。
6. 根因分析
已确证:
- 崩溃是内核 panic(double fault),非用户态、非 GPU。
- 崩溃调用栈完整,根节点在 IEE 的
iee_set_token_page_valid/do_split_huge_pmd。 - 触发者是
fork/clone(dup_task_struct走 slab 分配),由 dpkg 的大规模进程创建放大。 - 崩溃路径与 IEE 的
IEE_OP_SPLIT_HUGE_PMD(巨页分裂)强相关。
推断(根因假设):
- IEE 在
IEE SI被禁用(SMEP 不可用 / 探测异常)的状态下,仍执行令牌页校验与巨页分裂;两者状态不一致,在do_split_huge_pmd内触发WARN,随后iee_rw_gate门机制在异常处理中使内核栈失效(RSP=0),升级为 double fault → panic。 - THP 默认
always使巨页广泛存在,提供了该路径的触发条件。
佐证:
- 新版内核
6.6.0.ok25.0的 IEE 符号集合与ok24完全一致(44 项),两版 vmlinuz 体积仅差 252 字节 → 新版未修复该 IEE 逻辑,升级内核不能解决。
7. 关于"运行 22 小时"的更正
日志显示 383s 进入 s2idle 休眠、76486s 才唤醒,约 21 小时为休眠,唤醒后仅约 86 分钟即崩溃。崩溃与"长时间运行导致的老化/过热"无必然关系,而是休眠唤醒后的 slab/fork 负载触发了 IEE 缺陷。
8. 影响面
- 任意触发 slab 分配 + 巨页分裂的负载(尤其大量进程创建,如
dpkg、编译、容器 churn)都可能触发。 - 系统会无预警 panic 重启,可能丢失未保存数据;冷复位事件还会清空 ramoops 现场,增加排查难度。
- 崩溃后 EFI/FAT 分区出现"未正常卸载"告警,长期可能累积损坏。
- 属于可用性问题(DoS),且在 SMEP 关闭状态下运行存在安全隐患。
9. 建议
9.1 用户侧缓解(立即可用)
- 禁用透明巨页(THP):内核参数
transparent_hugepage=never,并在/etc/grub.d持久化、update-grub。目的:使巨页不产生,从根源绕开IEE_OP_SPLIT_HUGE_PMD路径。(详见本机死机调查.md§11) - 保留 ramoops/kdump 取证通道,改后持续观察是否仍崩溃。
- 持续观察 NVMe PCIe AER 可纠正错误;择机对 EFI/FAT 分区
fsck。
9.2 厂商侧修复建议(麒麟/openKylin)
- 修复 IEE 在
IEE SI disabled(SMEP 不可用)状态下仍执行 token page 校验/巨页分裂的逻辑不一致问题。 - 审查
iee-func.c:77处WARN之后iee_rw_gate导致内核栈损坏(RSP=0)的异常处理路径。 - 提供运行时/启动参数关闭 IEE 的开关(当前
CONFIG_IEE=y且无任何开关,用户无法规避)。 - 核查为何内核在 CPU 支持 SMEP 的情况下以 SMEP 关闭运行,及
IEE SI disabled的判定是否与被自身关闭 SMEP 互相矛盾。 - 评估
6.6.0.ok25.0:目前已确认其 IEE 代码与ok24无差异,未包含本问题修复。
10. 附录
10.1 关键日志原文(崩溃段)
<4>[81653.756177] ------------[ cut here ]------------
<4>[81653.756180] WARNING: CPU: 1 PID: 42357 at arch/x86/kernel/iee/iee-func.c:77 do_split_huge_pmd+0x21d/0x2d0
<4>[81653.756280] CPU: 1 PID: 42357 Comm: dpkg Tainted: G U W 6.6.0-24-generic #0ok1-KYLINOS
<4>[81653.756284] RIP: 0010:do_split_huge_pmd+0x21d/0x2d0
<4>[81653.756288] RAX: 80000000000001e1 RBX: ffff88847f8e3060 RCX: 0000000141800000
<4>[81653.756289] RDX: 0000000000000040 RSI: ffff88821ef81000 RDI: ffffea0005060000
<4>[81653.756295] CR2: 000000001e7a2418 CR3: 00000002cdbb4003 CR4: 0000000000672ee0
<4>[81653.756302] iee_set_token_page_valid+0x30d/0x370
<4>[81653.756306] allocate_slab+0x41e/0x5d0
<4>[81653.756312] ___slab_alloc+0x603/0xb00
<4>[81653.756323] kmem_cache_alloc_node_noprof+0x2dd/0x3a0
<4>[81653.756326] dup_task_struct+0x48/0x1d0
<4>[81653.756329] copy_process+0x1e4/0x1680
<4>[81653.756332] kernel_clone+0xc3/0x460
<4>[81653.756336] __do_sys_clone+0x66/0x90
<0>[81653.756786] traps: PANIC: double fault, error_code: 0x0
<4>[81653.756788] double fault: 0000 [#1] PREEMPT SMP NOPTI
<4>[81653.756790] CPU: 7 PID: 42385 Comm: dpkg Tainted: G U W
<4>[81653.756792] RIP: 0010:iee_rw_gate+0x37/0x70
<4>[81653.756795] RSP: 0018:0000000000000000 EFLAGS: 00010082
<4>[81653.756800] CR2: fffffffffffffff8 CR3: 000000025fa50001 CR4: 0000000000672ee0
<0>[81653.759105] Kernel panic - not syncing: Fatal exception in interrupt
<0>[81653.759125] Kernel Offset: disabled
10.2 IEE 初始化日志
<3>[0.067519] IBT selftest: Failed!
<3>[0.068486] IEE SI disabled because SMAP or SMEP is not available
<3>[0.068486] IEE: testing iee_exec_entry si_test...
<3>[0.068486] IEE: testing iee_exec_entry si_test...
10.3 IEE 符号表(节选,/boot/System.map-6.6.0-24-generic)
ffffffff8103ef50 T init_iee_offset
ffffffff81099370 T iee_rw_gate
ffffffff810993f0 T iee_read_token_stack
ffffffff81099450 T iee_read_tmp_page
ffffffff810994b0 T iee_read_freeptr
ffffffff81099510 T iee_rwx_gate_inner
ffffffff810995b0 T iee_rwx_gate
ffffffff810998d0 T set_iee_page
ffffffff81099a90 T unset_iee_page
ffffffff81099c00 T iee_set_logical_mem_ro
ffffffff81099d70 T set_iee_page_valid
ffffffff81099d90 T set_iee_page_invalid
ffffffff81099db0 T iee_set_token_page_valid ← 崩溃调用链
ffffffff8109a130 T iee_set_token_page_invalid
ffffffff8109a4e0 T set_iee_stack_page
ffffffff8109a500 T unset_iee_stack_page
ffffffff8109a520 T get_iee_stack
ffffffff8109a5c0 T free_iee_stack
ffffffff8109a610 T iee_free_task_struct_slab
ffffffff8109a740 T iee_free_slab
ffffffff8109f270 T kernel_physical_mapping_init_for_iee
ffffffff8140a4e0 T iee_get_oo_objects
ffffffff81ff9590 T init_memory_mapping_for_iee
10.4 相关配置文件
/etc/default/grub第 11 行(当前内核命令行)/etc/modules-load.d/ramoops.conf(加载 ramoops)- 取证存档:
/var/lib/systemd/pstore/dmesg-ramoops-{0,1}
10.5 术语
- IEE:麒麟定制内核子系统(
arch/x86/kernel/iee/),本报告分析对象;内部缩写含义以厂商定义为准。 - THP:Transparent Huge Pages,透明巨页。
- PMD:Page Middle Directory,页中间目录(巨页分裂的对象)。
- ramoops/pstore:将内核日志直写保留内存、跨重启留存的取证机制。
- SMEP/SMAP:Supervisor Mode Execution/Access Prevention,内核执行/访问用户页的硬件保护。
11. 补充说明
11.1 可复现性与影响范围(是否单机问题)
-
不是单机硬件问题。 崩溃代码
arch/x86/kernel/iee/编译进内核(CONFIG_IEE=y),与硬件无关;任何安装同一麒麟内核(6.6.0-24-generic #0ok1-KYLINOS)的设备运行的都是同一份有缺陷代码。 -
触发路径通用:
fork/clone → slab 分配 → IEE 令牌页校验 → 巨页分裂(IEE_OP_SPLIT_HUGE_PMD)。任何 Linux 都在做 fork/slab,因此同类内核设备普遍存在隐患。 -
是否实际崩溃取决于以下条件(概率性):
条件 本机情况 内核含 IEE 是( CONFIG_IEE=y)THP 开启 是( TRANSPARENT_HUGEPAGE_ALWAYS=y,内核默认)IEE 处于半残但生效状态 是( IEE SI disabled但仍运行 slab/巨页钩子)负载/时序命中 dpkg 装包时命中(休眠唤醒后 ~86 分钟) -
因此表现为偶发死机:可能数小时或数天一次,也可能长期未碰到。
-
待确认:内核运行于 SMEP 关闭状态(见 §5.4)是"该内核普遍如此"还是"本机型/固件特有"。若普遍,则风险面更广;建议在其它同版本设备上对比(命令见 §11.5)。
-
建议在报 bug 时明确声明:位于内核 IEE 代码、理论影响所有同版本内核设备、非单机硬件问题、且 ok25 未修复。
11.2 禁用 THP 的影响与权衡
缓解手段 transparent_hugepage=never 的副作用(功能/数据安全无影响,完全可逆):
| 方面 | 影响 |
|---|---|
| 内存密集负载性能 | 可能略降(数据库/VM/大型程序,几个百分点~约 10%);日常桌面/浏览器/办公基本无感 |
| 内存占用 | 可能更省(THP 按 2MB 粒度、易内部碎片) |
| 延迟/抖动 | 通常更好(去掉 khugepaged 合并与 defrag 造成的停顿) |
| HugeTLB | 不受影响(另一套机制;本机 HugePages_Total=0) |
| 可逆性 | 完全可逆(改回 always/madvise 或删除参数) |
- 多数发行版默认
madvise,本内核编译为always;改为never是更保守的一步。 - 折中方案
madvise:保留按需巨页,但不一定足以规避本崩溃(只要有程序申请巨页,IEE_OP_SPLIT_HUGE_PMD仍可能触发),故取证阶段建议先用never。
11.3 排查中已确认/排除的因素
| 因素 | 结论 | 依据 |
|---|---|---|
| i915 / GPU / 显存 | 已排除(前期方向走偏) | 崩溃栈与 GPU 无关;kern.log 无 GPU HANG/rcs0 reset |
| 硬件内存 | 未证实有问题 | 崩溃为软件缺陷;本机无 ECC,但仍未见内存错误证据 |
| IEE 可否运行时关闭 | 否 | CONFIG_IEE=y、无启动参数、无 sysfs/proc 开关 |
| 升级 ok25 内核 | 不能解决 | IEE 符号集合与 ok24 完全相同(44 项)、vmlinuz 仅差 252 字节 |
| efi_pstore 变砖风险 | 无 | 内置且 pstore_disable=Y,backend=ramoops,efivarfs 无 dmesg-efi-* |
| kdump/crashkernel | 已暂停,ramoops 为主取证通道 | 见 死机调查.md §9.6 |
显卡相关内核参数(i915.enable_*) |
保留未动(一次只改一个变量) | GPU 假设虽已推翻,但暂不改动 |
11.4 复现与验证建议
给用户(复现验证):
- 重启后确认 THP 已关闭:
cat /sys/kernel/mm/transparent_hugepage/enabled→[never]。 - 制造 fork/slab 压力(如
apt安装/升级一批包,或重复运行大栈复现程序),观察是否仍崩。 - 若再崩,检查
/var/lib/systemd/pstore/,确认是否仍落在iee_set_token_page_valid/do_split_huge_pmd。
给厂商(定位):
- 审阅
arch/x86/kernel/iee/iee-func.c:77处WARN及其后iee_rw_gate的异常处理。 - 审阅
iee_set_token_page_valid在IEE SI disabled状态下为何仍执行IEE_OP_SPLIT_HUGE_PMD。 - 核查内核为何在 CPU 支持 SMEP 时以 SMEP 关闭运行,及其与
IEE SI disabled的因果关系。 - 在带
CONFIG_IEE=y的内核上以 THP 开启 + 高 fork 压力复现。
11.5 相关命令速查
# 环境核对
uname -r
zcat /proc/config.gz 2>/dev/null | grep -E 'CONFIG_IEE|TRANSPARENT_HUGEPAGE'
dmesg | grep -iE 'IEE SI disabled|si_test|IBT selftest'
# 当前 THP 状态
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
# 取证
ls -la /var/lib/systemd/pstore/
sudo sha256sum /var/lib/systemd/pstore/dmesg-ramoops-*
grep -nE 'WARNING|do_split_huge_pmd|iee_|panic|double fault' /var/lib/systemd/pstore/dmesg-ramoops-0
# 其它设备对比(判断是否共性)
# 看 IEE 与 THP 是否与本机一致
11.6 排查时间线纪要
- 早期:误判为 Intel i915 “GPU hang → hard lockup”,围绕 i915 加参数(
i915.enable_psr/dc/guc)。 - 2026-09-23:建立 ramoops 取证;efi_pstore 实测不可用并禁用;kdump 尝试后回退。
- 2026-09-24:捕获真实 panic 现场 → 定位 IEE;核对配置与符号,确认 ok25 未修复;确认 SMEP 关闭与
IEE SI disabled;实施transparent_hugepage=never;产出本报告。
*报告完。证据文件哈希见 §4.1,原始日志见 §10,补充说明见 §11。