![[Android稳定性] 第014篇 [问题篇] slab内存泄露](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_014_212cd63c15ff50b0071aed7fbda8d059.jpg)
[Android稳定性] 第014篇 [问题篇] slab内存泄露
**问题描述**: 系统出现Slab内存占用过高,初步分析发现`kmalloc-128`存在内存泄漏问题。日志分析显示`pd_dbg_info`函数申请内存次数远大于释放次数,怀疑存在内存泄漏。 **问题分析**: * **日志分析**: 通过分析`meminfo`和`slabinfo`日志,发现`kmalloc-128`内存占用持续增加,初步判断存在内存泄漏。 * **Slabtrace日志**: `pd_dbg_info`函数申请内存次数达到3761872,而释放函数`print_out_dwork_fn`只释放了224862次,存在大量内存未释放。 * **根本原因**: `pd_dbg_info`函数申请内存后,通过`print_out_dwork_fn`工作队列函数释放内存。由于`print_out_dwork_fn`会统计printed次数,超过`dbg_log_limit`后启动延迟队列,导致内存释放延迟,最终造成内存泄漏。 **解决方案**: * **调整`dbg_log_limit`**: 根据实际情况调整`dbg_log_limit`值,避免延迟队列启动,及时释放内存。 * **优化工作队列**: 优化`print_out_dwork_fn`工作队列,提高内存释放效率。 * **内存泄漏检测**: 使用内存泄漏检测工具,例如Valgrind,对代码进行检测和修复。 **总结**: 该问题是由于`pd_dbg_info`函数申请内存后,延迟释放导致的内存泄漏。通过调整`dbg_log_limit`、优化工作队列和进行内存泄漏检测,可以有效解决该问题。
![[linux内存管理] 第014篇 /proc/zoneinfo的详细解析](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_linux_memory_management_014.png)
[linux内存管理] 第014篇 /proc/zoneinfo的详细解析
你好,根据您提供的文档内容,我总结如下: 内存管理是Linux内核中一个复杂的模块,涉及多种数据结构和逻辑。为了帮助开发者了解内存使用情况,内核在核心数据结构中提供了计数统计。初始化时,会进行一系列操作,包括设置架构、构建zonelist、初始化页分配器和内存管理模块等。 `/proc/zoneinfo` 是一个虚拟文件节点,用于展示内存管理区的详细统计信息。通过 `zoneinfo_show` 函数,可以遍历每个内存管理区,并打印相关信息。 `zoneinfo_show_print` 函数负责打印每个内存管理区的详细信息,包括: 1. 当前节点的内存统计信息,例如匿名页面、文件页面、脏页面、写回页面等数量。 2. 当前内存管理区的总信息,例如空闲页面数、最低/高/高水位线、覆盖的页面数、实际存在的页面数、受内核管理的页面数、CMA预留页面数等。 3. 当前内存管理区的详细页面信息,例如空闲页面数、非活跃/活跃的匿名/文件页面数、无法回收的页面数、待写回的页面数、mlock锁定的页面数、页表页面数、中转页面数、压缩页数、CMA空闲页面数等。 4. 当前内存管理区的pageset信息,即每个CPU内存分配器信息,包括可用的页面数、高水位线、批量分配大小等。 5. 其他信息,例如节点是否不可回收、节点的起始页帧号等。 这些信息可以帮助开发者了解内存使用情况,并进行相应的优化和调整。
![[Android稳定性] 第013篇 [问题篇] page allocation failure: order:0内存分配失败的异常报错](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_013.png)
[Android稳定性] 第013篇 [问题篇] page allocation failure: order:0内存分配失败的异常报错
在工厂老化测试过程中,设备出现卡视频现象,但USB接口可以识别到ADB口。通过分析日志发现,设备频繁出现"page allocation failure"错误,且均为"order:0",表明在分配一页大小的内存时失败。然而,系统配置中存在空闲的4KB内存,且内存分配标志为"GFP_NOWAIT|__GFP_NORETRY",表示希望进行一个非阻塞的内存分配,而空闲的UMEH页面恰好符合这些条件。这表明内核在内存充足的情况下无法分配内存,原因可能在于erofs文件系统在执行解压缩时使用GFP_NOWAIT标签进行内存申请,减少分配page的压力,但可能存在系统内存水位线不满足要求的情况。
![[Android稳定性] 第012篇 [原理篇] blackbox的原理介绍](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_012.png)
[Android稳定性] 第012篇 [原理篇] blackbox的原理介绍
Blackbox 是一种用于解决日志分析和自动化解析痛点的系统。它将大部分系统日志集中在黑匣子分区,并通过流式日志增加日志可读性。黑匣子分为三个区域:流水日志区、异常日志区和控制区,每个区域有不同的日志老化删除节奏。通过黑匣子,可以提高RAS自动化分析能力,并辅助问题分析。验证方法包括重启设备、触发系统崩溃、拉取黑匣子分区并使用工具解析,以及检查相关日志文件是否生成。
![[Android稳定性] 第011篇 [原理篇] minidump的原理介绍补充](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_011.png)
[Android稳定性] 第011篇 [原理篇] minidump的原理介绍补充
这篇文章主要介绍了Android系统中的minidump机制,这是一种用于保存系统崩溃信息的技术。文章首先解释了minidump的概念,即各个子系统在内存映射表中注册,当系统崩溃时,boot subsystem会加密并保存注册过的内存信息到RAM EMMC分区。 接着,文章详细描述了minidump的流程图和代码流程,包括HLOS侧和NON-HLOS侧的流程。在HLOS侧,文章重点介绍了defconfig配置、相关代码以及msm_minidump_add_region函数。在NON-HLOS侧,文章重点介绍了add_minidump_regions函数和boot_ram_dump_to_raw_parition函数。 文章还介绍了小米项目在minidump中增加的regions,包括md_kmsg、md_pmsg和tz_log,并解释了它们的设计原理。最后,文章介绍了如何验证minidump,包括设置minidump到emmc、触发dump以及从设备中拉取minidump。 此外,文章还介绍了minidump.gz的解析方法,包括解压minidump.gz和拆分minidump。
![[Android稳定性] 第010篇 [问题篇] 数组越界导致的内核panic](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_010.png)
[Android稳定性] 第010篇 [问题篇] 数组越界导致的内核panic
**摘要总结:** 服务器打包的daily版本在刷机后出现900E口死机问题。通过分析dmesg日志,发现程序在`fts_set_cur_value`函数处异常终止。进一步使用trace32工具恢复现场,确认是由于`touch_mode`数组越界导致的内存访问错误。该数组最大值被定义为15,但实际使用时传入了100,导致严重异常。
![[linux内存管理] 第013篇 zone的初始化](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_linux_memory_management_013.png)
[linux内存管理] 第013篇 zone的初始化
**摘要**: 本文深入剖析了 Linux 内核中物理内存管理的关键函数 `zone_sizes_init` 和 `free_area_init`,揭示了内存区域(zone)初始化的详细过程。 **主要内容**: 1. **zone_sizes_init** 函数: * 计算每种类型 zone 的最大页帧号(PFN)。 * 调用 `free_area_init` 函数进行后续初始化。 2. **free_area_init** 函数: * 记录区域边界并计算起始 PFN。 * 遍历所有区域,设置边界并初始化 `zone` 结构。 * 计算 `ZONE_MOVABLE` 的边界。 * 打印区域信息。 * 初始化每个 NUMA 节点,包括分配 `mem_map` 空间和设置伙伴系统数据结构。 * 初始化 `struct page` 结构。 3. **free_area_init_node** 函数: * 获取节点信息并计算页帧范围。 * 设置节点 ID、起始 PFN 和节点状态。 * 计算节点的总页数和可用页数。 * 分配 `mem_map` 空间。 * 初始化节点的核心管理结构,包括 `zone` 的范围和伙伴系统数据结构。 4. **zone_init_internals** 函数: * 设置 `zone` 的 `managed_pages` 和 `name`。 * 初始化 `zone` 的锁和 PGP 数据结构。 5. **init_currently_empty_zone** 函数: * 初始化 `zone` 的 `free_area` 数据结构,包括空闲列表和空闲页数。 **关键点**: * `zone_sizes_init` 函数计算区域边界,为后续初始化做准备。 * `free_area_init` 函数是内存区域初始化的核心,负责划分区域、初始化节点和设置伙伴系统。 * `free_area_init_node` 函数负责初始化每个 NUMA 节点的内存管理结构。 * `zone_init_internals` 函数初始化 `zone` 的核心管理结构。 * `init_currently_empty_zone` 函数初始化 `zone` 的 `free_area` 数据结构。 **总结**: Linux 内核通过 `zone_sizes_init` 和 `free_area_init` 等函数,实现了对物理内存的精细化管理,确保了内存分配的高效性和安全性。
![[Android稳定性] 第009篇 [问题篇] 数组越界导致的内核panic](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_009.png)
[Android稳定性] 第009篇 [问题篇] 数组越界导致的内核panic
**问题现象**: 部分机器插着 USB 后出现死机。 **问题分析**: 通过 `dmesg` 和 `trace32` 分析,发现死机原因是 `power_operation_mode_show` 函数中 `typec_port` 结构体的 `pwr_opmode` 成员值错误(为负数),导致数组越界。 **解决方案**: 更新 charger 模块,修复对 `pwr_opmode` 的误判,确保其值为正数,避免数组越界。 **总结**: 本次问题是由 `typec_port` 结构体的 `pwr_opmode` 成员值错误导致,通过分析定位问题,并更新 charger 模块修复了问题。
![[Android稳定性] 第008篇 [原理篇] 动态设置kernel cmdline](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/image_34a046feced97161f77c77dbd27075d9.png)
[Android稳定性] 第008篇 [原理篇] 动态设置kernel cmdline
本文介绍了一种在fastboot模式下动态修改内核参数的方法,无需重新打包。首先,通过扩展fastboot oem指令,接收输入的内核参数并写入到devinfo分区中。然后,在更新kernel cmdline时,将保存的内核参数添加到cmdline中。实验测试显示,该方案可以成功修改内核参数,并永久生效。代码更新后,支持设置、追加和清除模式,方便用户根据需求进行操作。
![[Android稳定性] 第007篇 [问题篇] 中断风暴导致panic](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_007.png)
[Android稳定性] 第007篇 [问题篇] 中断风暴导致panic
问题摘要:系统日志显示irq 193存在异常,其action为0,表明中断未被注册,导致中断被送至`handle_bad_irq`处理。经查询,该中断对应gpio 93,且在设备树中该gpio被用于wusb3801的中断和复位功能。去除相关配置后,系统恢复正常。
![[Android稳定性] 第006篇 [问题篇] hungtask causing panic-死锁](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_006.png)
[Android稳定性] 第006篇 [问题篇] hungtask causing panic-死锁
本文讨论了一个系统问题现象,通过分析日志文件发现一个进程因等待锁而被阻塞120秒。通过使用`tace32`工具跟踪调用栈,发现存在一个三方的死锁情况,涉及进程`2848_9`、`crtc_commit:160`、`vendor.qti.came`和`kworker/u16:7`。文章详细展示了锁的持有者和调用栈信息,但未提供具体的解决方法。
![[Android稳定性] 第003篇 [原理篇] mtdoops的原理介绍](https://hexoimg.oss-cn-shanghai.aliyuncs.com/blog/24/12/cover_android_stability_003.png)
[Android稳定性] 第003篇 [原理篇] mtdoops的原理介绍
**mtdoops简介与原理总结** mtdoops是一种将系统崩溃时的日志信息保存到MTD(Memory Technology Device)设备中的机制,用于在系统panic时捕获关键信息。它利用MTD子系统,将崩溃日志转存到非易失存储器中,便于后续问题分析。mtdoops与其他捕获panic的方式(如ramoops和kdump)相比,具有特定优势,但需依赖MTD设备和相关配置。 **核心内容摘要:** - mtdoops通过在内核中注册捕获panic或oops,将日志信息保存到MTD设备。 - 需要在内核defconfig中启用相关配置,并在设备树中预留存储空间。 - 通过cmdline动态更新,确保在系统启动时正确配置mtdoops。 - 功能验证包括开机初始化log检查、cmdline确认及重启测试抓取log。 - offline_log机制可触发mtdoops日志抓取,便于问题诊断。