ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux PowerPC Firmware-Assisted Dump(FADump)完全指南:原理、配置与 sysfs 接口解析

Linux PowerPC Firmware-Assisted Dump(FADump)完全指南:原理、配置与 sysfs 接口解析 Linux PowerPC Firmware-Assisted DumpFADump完全指南原理、配置与 sysfs 接口解析【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linuxFADumpFirmware-Assisted Dump是 Linux PowerPC 平台上由系统固件Power Hypervisor 或 OPAL协助完成的崩溃转储机制其核心目标是在系统彻底复位、硬件状态完全重置的前提下捕获崩溃现场并最大限度缩短系统恢复上线的时间。本文以内核文档 Documentation/arch/powerpc/firmware-assisted-dump.rst 为主线结合 arch/powerpc/kernel/fadump.c 与 arch/powerpc/include/asm/fadump-internal.h 的源码实现完整讲解 FADump 的工作流程、内存预留模型、平台支持范围、启用方法及全部 sysfs/debugfs 控制接口帮助你在一台 POWER 机器上从零配置并理解每一次崩溃转储背后的固件协作细节。FADump 是什么目标与设计初衷FADump 旨在解决传统转储方案的两个核心痛点一是系统崩溃后必须尽快回到生产状态二是转储过程必须发生在完全复位、硬件干净一致的系统中。其核心思路是第一内核first kernel在启动时将需要保存的内存区域注册给 Power 固件当系统崩溃时固件负责把注册的低端内存boot memory复制到预留给转储的区域同时保存硬件 PTE随后固件复位 PCI 及其他硬件状态但不清空 RAM并按正常流程引导 bootloader新引导的内核capture kernel从设备树中识别出存在上一轮崩溃数据随即把 boot memory 以上的所有内存全部预留确保自己不会触碰转储区用户态工具通过/proc/vmcore读取 ELF 格式的内存转储内容保存完成后回写1到释放节点将预留内存归还系统。FADump 在设计上是对原有 phyp assisted dump 的替代与演进其关键差异体现在与 kdump 一样FADump 以ELF 格式通过/proc/vmcore导出内存转储因此可以直接复用整套 kdump 用户态基础设施抓取与过滤工具完全一致无需为新机制重写工具链。与 phyp dump 不同用户态工具读取/proc/vmcore时无需参照任何 sysfs 接口路径更简单。与 phyp dump 不同用户可以通过一次操作echo 1 /sys/kernel/fadump_release_mem释放全部为转储预留的内存。通过内核启动参数启用后FADump 可以通过/sys/kernel/fadump_registered接口启停能很方便地与 kdump 服务的 start/stop init 脚本集成。相比 kdump 的两大核心优势文档明确给出了 FADump 相对 kdump 及其他策略的强项硬件状态干净一致与 kdump 不同FADump 下系统已经过完全复位并加载了全新内核PCI 与 I/O 设备均被重新初始化处于干净、一致的状态避免因崩溃残留的硬件状态导致转储工具无法工作。无需第二次重启即可恢复生产转储数据一旦被复制出去存放转储的内存立即归还给运行中的内核使用。与 kdump 相比FADump不需要第二次重启来使系统恢复到生产配置显著缩短业务中断窗口。这些优势只有通过与 Power 固件的协调配合才能实现。也正因如此FADump 本质上是“固件主导内存搬运 内核复用 kdump 工具链”的分工模型固件负责物理内存的保护与拷贝内核负责 ELF 化的呈现与释放。FADump 完整工作流程整个 FADump 生命周期可分解为以下步骤第一内核注册第一内核在操作系统初始化期间将需要保留的内存段dump 区注册给 Power 固件并在早期启动阶段完成预留。崩溃发生时固件搬运系统崩溃后Power 固件把已注册的低端内存区域boot memory从源地址复制到目的地址同时保存硬件 PTE。固件复位并引导低端内存保存完成后固件复位 PCI 及其他硬件状态但不清除 RAM随后像正常启动一样引导 bootloader。第二内核识别崩溃数据新引导的内核会注意到设备树中出现新节点——pSeries 平台的rtas/ibm,kernel-dump或 OPAL 平台的ibm,opal/dump/mpipl-boot表明存在上一轮的崩溃数据。在早期启动阶段内核会把 boot memory 大小以上的所有内存全部预留实际上以受限内存大小启动确保这个内核即第二内核 / capture kernel不会触碰任何转储内存区域。用户态读取转储用户态工具读取/proc/vmcore获取 ELF 格式的崩溃内核内存转储可将其复制到磁盘、网络、NAS、SAN、iSCSI 等任意目标。释放预留内存保存完成后用户态工具向/sys/kernel/fadump_release_mem写入1释放预留内存供系统常规使用保留下一次 FADump 注册所需的部分除外# echo 1 /sys/kernel/fadump_release_mem什么是 boot memory文档中对 “boot memory” 的定义是内核以受限内存启动时能够成功引导所需的那块低端内存的大小。默认情况下boot memory 取以下两者中的较大者系统 RAM 的 5%256MB。用户也可以通过内核启动参数crashkernel覆盖默认计算值用于默认 boot memory 不足以让第二内核成功引导的场景。crashkernel参数的完整语法请参考 Documentation/admin-guide/kdump/kdump.rst。需要特别注意的是如果crashkernel中提供了 offset偏移量该偏移量会被忽略因为 FADump 使用预定义的偏移来为崩溃时的 boot memory 转储预留内存。从源码看这一逻辑在 fadump.c 的fadump_calculate_reserve_size()中实现优先解析crashkernel指定的 size若未指定则取memblock_phys_mem_size() / 20即 5%并按 256MB 对齐向下取整同时通过MAX_BOOT_MEM_RATIO值为 4即上限 25%对用户指定值做上限约束见 fadump-internal.h最后取bootmem_min平台相关的最小值与计算值的较大者。文档中还提到fadump_reserve_mem参数已废弃应改用crashkernel这一废弃警告在源码中同样存在fadump.c。内存预留模型CPU 状态、HPTE、boot memory 与元数据FADump 在第一次内核启动时需要预留的内存包括保存 CPU 状态cpu_state_data_size、HPTE 区域hpte_region_size、boot memory 转储区以及 FADump 头struct fadump_crash_info_header在支持 metadata标签的平台如 OPAL上还包括内核元数据区。这些信息统一记录在 fadump-internal.h 定义的struct fw_dump配置结构中。内存预留的总大小由 fadump.c 的get_fadump_area_size()计算cpu_state_data_size hpte_region_size经页对齐后加上boot_memory_size、sizeof(struct fadump_crash_info_header)以及平台元数据大小。第一内核阶段的内存布局Fig. 1Low memory Top of memory 0 boot memory size |------ Reserved dump area -----| | | | | Permanent Reservation | | V V | | V ----------------/ /------------------------------------- | | |///|////| DUMP | HDR |////| | ----------------/ /------------------------------------- | ^ ^ ^ ^ ^ | | | | | | \ CPU HPTE / | | -------------------------------- | | Boot memory content gets transferred | | to reserved area by firmware at the | | time of crash. | | FADump Header | (meta area) |图 1 展示了无崩溃数据时的内存布局仅在高于 boot memory 大小的偏移处预留了 CPU 状态、HPTE 区域、boot memory 转储区DUMP与 FADump 头HDR/元数据区。这个区域不会被释放它将永久保留作为将来崩溃发生时 boot memory 内容与 CPU 状态、HPTE 区域的接收容器。从源码结构看struct fw_dump中的boot_mem_addr[]/boot_mem_sz[]最多FADUMP_MAX_MEM_REGS 128 个区域见 fadump-internal.h记录了 boot memory 的多个物理段boot_mem_top记录其顶部边界fadump_get_boot_mem_regions()fadump.c遍历 memblock 内存范围把 boot memory 切分为若干区域并记录还会顺带累计内存空洞boot_mem_top的计算包含空洞大小。固件对单次拷贝的大小有限制max_copy_size因此add_boot_mem_regions()fadump.c会把超限范围拆分为多个子区域。第二内核阶段的内存布局Fig. 2Low memory Top of memory 0 boot memory size | | |------------ Crash preserved area ------------| V V |--- Reserved dump area ---| | --------------/ /---------------------------------- | |ELF| | |///|////| DUMP | HDR |/////| | --------------/ /---------------------------------- | | | | | | ----- ------------------------------ --------------- \ | | \ | | \ | | \ | ---------------------------- \ | / \ | / \ | / /proc/vmcore图 2 展示了崩溃发生后的内存布局第二内核使用从 0 到 boot memory size 的内存运行elfcorehdr图中ELF在第二内核中创建崩溃保留区Crash preserved area涵盖从 boot memory 顶部到内存顶端的全部内容其中转储区DUMP与 HDR 之间的物理内存会在/proc/vmcore中按 PT_LOAD 段呈现。图注补充了两个重要细节标记为///的区域CPU、HPTE 与 Metadata并非总是存在。例如 OPAL 平台没有 CPU 与 HPTE 区域而 pSeries 平台目前不支持 Metadata 区域。ELF表示 elfcorehdr它是在崩溃后的第二内核中创建的。struct fadump_crash_info_headerfadump-internal.h是崩溃信息头包含魔数FADMPSIG旧内核为FADMPINF、版本号FADUMP_HEADER_VERSION 1、崩溃 CPU、vmcoreinfo 地址与大小、pt_regs寄存器现场与 CPU mask。源码注释特别说明新增字段应追加在结构体末尾非基本类型成员需附带 size 成员每次修改都要递增版本号以便新内核正确处理旧内核产生的转储fadump-internal.h。在第二内核中fadump_reserve_mem()fadump.c检测到dump_active后会调用fadump_reserve_crash_area()把 boot memory 以上的全部内存预留同时若配置了 HugeTLB还会设置hugetlb_disabled true——源码注释解释capture kernel 并不关心大页在 FADump 激活时处理大页反而徒增麻烦fadump.c。基于 CMA 的智能预留让预留内存“物尽其用”由于这块预留内存只在系统崩溃后才被使用把它整块从生产内核中封锁出去并不划算。因此实现中采用 Linux 内核的Contiguous Memory AllocatorCMA来完成预留前提是内核配置了 CMA以 CMA 方式预留时该内存可供应用程序使用但内核被阻止使用它。这样 FADump 仍然能捕获全部内核内存以及绝大部分用户空间内存唯一的例外是当时恰好落在 CMA 区域内的用户页面。对应源码位于 fadump.c 的fadump_cma_init()它从 FADump 预留区中取出与 boot memory 大小相当、按CMA_MIN_ALIGNMENT_BYTES对齐的部分交给cma_init_reserved_mem()初始化为名为fadump_cma的 CMA 区域即使 CMA 初始化失败内存预留仍然存在FADump 照常工作仅退回为纯预留模式。这也解释了fadumpnocma启动参数的意义——见下文。平台支持范围与固件要求文档明确限定了 FADump 的硬件与固件前提平台最低要求pSeriesPowerVMPOWER6 及以上系统PowerNVOPALPOWER9 及以上且固件版本为OP940 或更新其中 OPAL 固件在支持 FADump 的 PowerNV 平台上会导出ibm,opal/dump设备树节点。源码中early_init_dt_scan_fw_dump()fadump.c在设备树深度为 1 时按节点名分发rtas节点交给rtas_fadump_dt_scan()ibm,opal节点交给opal_fadump_dt_scan()分别对应 pSeries 与 PowerNV 两种固件实现路径struct fadump_opsfadump-internal.h中的一组平台回调函数fadump_register、fadump_process、fadump_trigger、fadump_region_show等正是为这两种平台抽象出来的操作接口。OPAL 平台的额外机制petitboot 内核与 CONFIG_PRESERVE_FA_DUMP在 OPALPowerNV机器上系统崩溃后会先引导一个中间内核intermittent kernel即 petitboot 内核然后才引导 capture kernel。这个中间内核只需最精简的内核/用户态支持来处理崩溃数据但它必须保留之前崩溃内核的内存供后续的 capture kernel 引导时处理。因此这种内核必须启用内核配置选项CONFIG_PRESERVE_FA_DUMP以确保崩溃数据被保留下来供后续处理。对应内核配置位于 arch/powerpc/Kconfigconfig PRESERVE_FA_DUMP bool Preserve Firmware-assisted dump depends on PPC64 PPC_POWERNV !FA_DUMP help On a kernel with FA_DUMP disabled, this option helps to preserve crash data from a previously crashed kernel. Useful when the next memory preserving kernel boot would process this crash data. Petitboot kernel is the typical usecase for this option.CONFIG_OPAL_CORE导出 OPAL 内存用于 GDB 调试在 OPALPowerNV机器上如果内核以CONFIG_OPAL_COREy构建崩溃时 OPAL 的内存也会被导出为/sys/firmware/opal/mpipl/core文件。这个 procfs 文件在使用 GDB 调试 OPAL 崩溃时非常有用。用于导出该文件的 kernel 内存可以通过向/sys/firmware/opal/mpipl/release_core节点写入1来释放# echo 1 /sys/firmware/opal/mpipl/release_core对应 Kconfig 定义为arch/powerpc/Kconfigconfig OPAL_CORE bool Export OPAL memory as /sys/firmware/opal/core depends on PPC64 PPC_POWERNV help This option uses the MPIPL support in firmware to provide an ELF core of OPAL memory after a crash. The ELF core is exported as /sys/firmware/opal/core file which is helpful in debugging OPAL crashes using GDB.为 FADump 内核追加额外启动参数FADump 支持向 fadumpcapture内核传递额外的内核参数。该特性的设计初衷是禁用 fadump 内核不需要的内核功能从而在收集转储时降低其内存占用。添加额外参数无需显式重启服务即可生效# echo nr_cpus16 /sys/kernel/fadump/bootargs_append查询当前追加的 FADump 参数# cat /sys/kernel/fadump/bootargs_append注意对于 HASH MMU 的 FADump只有在RMA 大小大于 768MB时才支持额外内核参数如果 RMA 小于 768MB内核不会导出/sys/kernel/fadump/bootargs_append这个 sysfs 节点。从源码看该节点由bootargs_append_show()/bootargs_append_store()fadump.c实现写入时校验 FADump 已启用且未处于 dump_active 状态并对命令行长度的上限COMMAND_LINE_SIZE做了保护这些参数被存放在一个专用的 param_area 中capture kernel 启动时由fadump_append_bootargs()fadump.c读取并拼接到 boot_command_line 末尾若拼接超出命令行大小则截断并告警。此外sysfs 节点/sys/kernel/fadump/hotplug_ready返回 1向用户空间表明内存热插拔事件发生时 fadump 无需重新注册fadump.c。如何启用 FADump启用 FADump 分三步设置内核配置CONFIG_FA_DUMPy并重新编译内核。该选项定义在 arch/powerpc/Kconfig依赖CRASH_DUMP PPC64 (PPC_RTAS || PPC_POWERNV)其帮助文本明确说明它是“不依赖 kexec、由固件协助引导 capture kernel 并保留内存内容”的机制定位为 kdump 的替代品除非是 petitboot 之类的特殊内核一般建议选 “y”。以fadumpon内核命令行选项启动 Linux 内核。默认情况下FADump 预留内存会被初始化为 CMA 区域也可以改用fadumpnocma启动内核阻止 FADump 使用 CMA。可选通过crashkernel内核命令行参数指定为 boot memory 转储预留的内存大小。三个 NOTE 需要特别留意fadump_reserve_mem参数已废弃请改用crashkernel来指定 boot memory 转储预留大小。回退机制如果 firmware-assisted dump 预留内存失败且内核命令行设置了crashkernel则自动回退到现有 kdump 机制。nocma 的取舍如果用户想捕获全部用户空间内存并且可以接受预留内存无法供生产系统使用则可以使用fadumpnocma参数回退到旧行为。fadump参数的解析在early_fadump_param()fadump.c中完成支持on、off、nocma三种取值其中nocma会同时置位fadump_enabled与nocma标志fadump_reserve_mem的解析则位于early_fadump_reserve_mem()fadump.c源码中同样标注了 TODO尽快移除对该参数的引用、全面转向crashkernel。sysfs 与 debugfs 接口全解析FADump 使用sysfs 文件系统存放控制文件使用debugfs 文件系统展示预留内存区域。内核 sysfs 控制文件/sys/kernel/fadump_enabled用于显示 FADump 状态0 FADump 已禁用1 FADump 已启用该接口可供 kdump init 脚本识别内核是否启用了 FADump 并据此行动。/sys/kernel/fadump_registered用于显示 FADump 注册状态同时用于控制启动/停止FADump 注册0 FADump 未注册1 FADump 已注册可随时处理系统崩溃注册与注销方式# echo 1 /sys/kernel/fadump_registered # 注册 # echo 0 /sys/kernel/fadump_registered # 注销并停止一旦注销系统崩溃将不再被处理vmcore 也不会被捕获。该接口可以很容易地与 kdump 服务的 start/stop 集成。/sys/kernel/fadump/mem_reserved显示 FADump 为保存崩溃转储而预留的内存大小源码mem_reserved_show()直接输出fw_dump.reserve_dump_area_size见 fadump.c。/sys/kernel/fadump_release_mem该文件仅在第二内核中 FADump 处于活动状态时可用用于释放为保存崩溃转储而持有的预留内存区域# echo 1 /sys/kernel/fadump_release_mem执行后/sys/kernel/debug/powerpc/fadump_region文件的内容会随之更新反映新的内存预留。现有用户态工具kdump 基础设施可以很容易地增强为使用该接口释放预留内存从而无需第二次重启。/sys/firmware/opal/mpipl/release_core仅存在于OPAL 平台且 FADump 在 capture kernel 中处于活动状态时。用于释放内核导出/sys/firmware/opal/mpipl/core文件所占用的内存# echo 1 /sys/firmware/opal/mpipl/release_core注意旧的/sys/kernel/fadump_release_opalcoresysfs 节点已迁移到/sys/firmware/opal/mpipl/release_core。已废弃的 sysfs 节点及替代以下 FADump sysfs 文件已废弃请使用对应的新路径已废弃替代/sys/kernel/fadump_enabled/sys/kernel/fadump/enabled/sys/kernel/fadump_registered/sys/kernel/fadump/registered/sys/kernel/fadump_release_mem/sys/kernel/fadump/release_mem从源码看内核在创建新 kobject 目录的同时通过sysfs_create_link()为旧路径创建了符号链接以保持兼容fadump.c。powerpc debugfs 文件假设 debugfs 挂载在/sys/kernel/debug目录挂载方法参考 Documentation/filesystems/debugfs.rst/sys/kernel/debug/powerpc/fadump_region该文件在 FADump 启用时显示预留的内存区域否则为空。输出格式为region: [start-end] reserved-size bytes, Dumped: dump-size其中内核 DUMP 区域boot memory 转储的格式为DUMP: Src: src-addr, Dest: dest-addr, Size: size, Dumped: # bytes第一内核注册 FADump 时的示例输出# cat /sys/kernel/debug/powerpc/fadump_region CPU : [0x0000006ffb0000-0x0000006fff001f] 0x40020 bytes, Dumped: 0x0 HPTE: [0x0000006fff0020-0x0000006fff101f] 0x1000 bytes, Dumped: 0x0 DUMP: [0x0000006fff1020-0x0000007fff101f] 0x10000000 bytes, Dumped: 0x0第二内核中 FADump 处于活动状态时的示例输出注意 Dumped 值变为实际转储量并多出崩溃保留区的整段内存# cat /sys/kernel/debug/powerpc/fadump_region CPU : [0x0000006ffb0000-0x0000006fff001f] 0x40020 bytes, Dumped: 0x40020 HPTE: [0x0000006fff0020-0x0000006fff101f] 0x1000 bytes, Dumped: 0x1000 DUMP: [0x0000006fff1020-0x0000007fff101f] 0x10000000 bytes, Dumped: 0x10000000 : [0x00000010000000-0x0000006ffaffff] 0x5ffb0000 bytes, Dumped: 0x5ffb0000该输出由fadump_region_show()fadump.c调用平台回调fadump_region_show生成并注册到 debugfs权限 0444。转储的抓取与工具链复用当前转储的落地仍需用户介入触发转储数据将从/proc/vmcore复制到新文件中数据本身为ELF 格式。正因如此现有的 kdump 基础设施kdump 脚本只需少量修改即可用于保存转储各大发行版上的 kdump 脚本已经过修改在使用 FADump 作为转储机制时能够无缝工作保存转储无需用户介入。分析转储的工具也与 kdump 完全相同。这也对应了crash_fadump()fadump.c的崩溃路径实现第一个进入崩溃路径的 CPU 通过cmpxchg(crashing_cpu, -1, this_cpu)竞争成为“主崩溃 CPU”其余 CPU 在cpus_in_fadump计数中等待若经由 system reset 进入主 CPU 会最多等待CRASH_TIMEOUT500ms让其他 CPU 就位主 CPU 随后把崩溃现场pt_regs、CPU mask、vmcoreinfo写入fadump_crash_info_header最终调用平台回调fadump_trigger()触发固件完成内存保存。已知限制与 TODO内核文档在 TODO 一节中明确列出当前已知的改进方向需要找到更优的方法来确定“以内核受限内存引导时成功引导所需的确切 boot memory 大小”。当前默认取 5% RAM 与 256MB 中的较大者这一估算逻辑在源码fadump_calculate_reserve_size()中同样留有 TODO 注释fadump.c。这意味着如果你在生产环境中遇到第二内核因 boot memory 不足而引导失败的情况应主动通过crashkernel调大预留值而不是依赖默认估算。小结FADump 通过“固件搬运内存 内核复用 kdump 工具链”的协作模型为 PowerPC 平台提供了一条比传统 kdump 更稳健、恢复更快的崩溃转储路径系统崩溃后硬件被完全复位到干净状态转储以 ELF 格式经/proc/vmcore导出保存完成后一次性释放预留内存全程无需第二次重启。无论是 pSeriesPOWER6还是 PowerNVPOWER9 OP940 固件平台都可以通过CONFIG_FA_DUMPy加fadumpon启动参数快速启用并通过本文梳理的 sysfs/debugfs 接口完成注册、状态查询、参数追加与内存释放的日常运维。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表