[Android稳定性] 第050篇 [问题篇] slab内存泄露造成设备黑屏 2月前查看 评论
[Android稳定性] 第050篇 [问题篇] slab内存泄露造成设备黑屏

本文描述了在测试手机经过长期智能充电后,出现卡顿和黑屏的问题现象。复现步骤包括设置手机时间和电池温度,并使用QC3.0充电器进行充电。预期结果是系统界面流畅,但实际结果是系统界面卡死和黑屏。通过分析内存信息和slab信息,发现内存不足和slab内存泄露问题。通过slabtrace分析,确定问题根源在于charger模块中的一些函数调用导致了内存泄露。解决方案是在申请内存前,先判断是否已经申请过,以避免重复申请。

[linux内存管理] 第026篇 从内核源码看 slab 内存池的创建初始化流程 2月前查看 评论
[linux内存管理] 第026篇 从内核源码看 slab 内存池的创建初始化流程

本文详细介绍了Linux内核中slab内存池的创建过程,从源码层面解释了slab cache的架构设计和实现。文章首先介绍了slab cache的创建接口函数kmem_cache_create,并解释了其参数与slab cache结构体属性的对应关系。接着,文章深入分析了slab cache创建的详细流程,包括获取锁、参数校验、查找可复用的slab cache、计算slab对象的内存布局、初始化slab cache的重要属性、创建本地cpu缓存和NUMA节点缓存等步骤。此外,文章还介绍了slab allocator体系的初始化过程,解释了如何解决先有鸡还是先有蛋的问题,并详细说明了slab对象的内存布局和计算slab所需物理内存页个数的逻辑。最后,文章总结了slab cache的创建流程和架构,并展望了后续对slab内存池内存分配的深入探讨。

[linux内存管理] 第025篇 细节拉满,80 张图带你一步一步推演 slab 内存池的设计与实现 2月前查看 评论
[linux内存管理] 第025篇 细节拉满,80 张图带你一步一步推演 slab 内存池的设计与实现

本文介绍了 Linux 内核中的 slab 内存池,用于高效地分配和释放小内存块。作者首先回顾了 Linux 内存分配的宏观流程,然后引出 slab 内存池的产生背景和优势。slab 内存池将频繁使用的小内存块池化,避免了频繁的内存分配和释放带来的性能开销。文章详细介绍了 slab 对象池的内存布局,包括对齐、red zone、freepointer 和状态信息等。接着,文章分析了 slab 的总体架构设计,包括 kmem_cache、kmem_cache_cpu 和 kmem_cache_node 等数据结构。最后,文章详细介绍了 slab 内存分配和释放的原理,包括从本地 cpu 缓存、partial 列表、NUMA 节点缓存和伙伴系统中分配和释放内存的场景。

[linux内存管理] 第024篇 slab内存分配器概述 2月前查看 评论
[linux内存管理] 第024篇 slab内存分配器概述

填充操作中的数据结构 在内存管理中,填充操作涉及到多个核心数据结构,其中包括: 1. **struct kmem_cache**:代表一种“对象类型”的缓存池。内核启动时或动态创建时,会为常见的内核对象(如 `task_struct`、`fs_struct`、`inode`)各自建立一个 `kmem_cache`,用它来管理该类型对象的分配与回收。 2. **struct array_cache**:本地缓存池,每个CPU一个。当本地缓存池为空时,需要从共享缓存池或者slans_partial/slabs_free中,获取batchcount个对象到本地缓存池。 3. **slab_flags_t flags**:对象分配掩码,用于控制对象的分配行为。 4. **unsigned int num**:一个slab最多可以有多少个对象。 5. **unsigned int gfporder**:一个slab占用多个2的order次方物理页面。 6. **size_t colour**:一个slab分配器有多少个不同的高速缓存行,用于着色。 7. **unsigned int colour_off**:一个着色区长度,和L1高速缓存行大小相同。 8. **void (*ctor)(void *obj)**:构造函数,用于初始化新分配的对象。 9. **const char *name**:slab描述符名字。 10. **struct list_head list**:链表节点,用于把slab描述符添加到全局链表slab_caches中。 11. **int refcount**:本描述符引用计数。 12. **int object_size**:对象实际大小。 13. **int align**:对齐长度。 14. **unsigned long num_active**:当前正被使用(allocated but not freed)的对象总数。 15. **unsigned long num_allocations**:累计分配(kmem_cache_alloc)次数。 16. **unsigned long high_mark**:历史最高的 num_active 值(峰值并发使用量)。 17. **unsigned long grown**:slab “增长”次数:从 partial/slabs_empty 中取空 slab 或新建 slab 的总次数。 18. **unsigned long reaped**:slab “收割”次数:将完全空闲的 slab 返还给伙伴系统的总次数。 19. **unsigned long errors**:运行时遇到的错误次数(如分配失败、参数校验失败等)。 20. **unsigned long max_freeable**:在任意时刻,整 cache 中可一次性返还给伙伴系统的最大页数。 21. **unsigned long node_allocs**:NUMA 环境下,从本节点分配 slab 对象的次数。 22. **unsigned long node_frees**:NUMA 环境下,向本节点返还 slab 对象的次数。 23. **unsigned long node_overflow**:NUMA 本地缓存溢出的次数(本地 node cache 空间不足需借用或返还)。 24. **atomic_t allochit**:分配时直接命中 per-CPU cache 的次数(无需访问 partial/full)。 25. **atomic_t allocmiss**:分配时未命中 per-CPU cache,需要去 partial/full 或新建 slab 的次数。 26. **atomic_t freehit**:释放时直接回填 per-CPU cache 的次数。 27. **atomic_t freemiss**:释放时未能回填 per-CPU cache,需要 flush 回 partial/full 的次数。 28. **int obj_offset**:对象在 slab 内的偏移(bytes),仅在调试模式下有效。 29. **struct kasan_cache kasan_info**:KASAN相关的缓存信息。 30. **unsigned int *random_seq**:用于随机化 freelist 的序列。 31. **unsigned int useroffset**:用户对象偏移量。 这些数据结构共同构成了填充操作的核心,它们协同工作,实现了高效、低碎片的内存管理。

[Android稳定性] 第025篇 [问题篇] KASAN slab-out-of-bounds内存越界问题 6月前查看 评论
[Android稳定性] 第025篇 [问题篇] KASAN slab-out-of-bounds内存越界问题

本文分析了在运行kasan版本corgi: 4967550时出现的死机问题,问题概率为4/7。通过分析dmesg日志,确定问题类型为slab-out-of-bounds,问题函数为usbpd_mi_vdm_received_cb,越界地址为ffffff808d6c0a60。通过trace32工具恢复现场,定位到死机原因为for循环中的数组越界访问。最终,通过修改循环次数为rx_msg->data_len/sizeof(u32),成功解决问题。

[Android稳定性] 第023篇 [问题篇] printk非空的非法指针参数导致的spinlock死锁引起Non Secure WDT 6月前查看 评论
[Android稳定性] 第023篇 [问题篇] printk非空的非法指针参数导致的spinlock死锁引起Non Secure WDT

**摘要**: 本文分析了Linux内核中因`Non secure wdt`导致的死机问题。通过分析ramdump,发现所有CPU都在等待一个spin lock,且锁的持有者是`kworker/u17:12`。进一步分析发现,该进程在获取锁后出现了data abort,并在异常处理流程中再次尝试获取锁,导致死锁。根本原因是`nvt_update_firmware`函数中使用了未初始化的指针作为`printk`的参数,导致打印异常。解决方案是将`kmalloc`改为`kzalloc`,以确保内存被清零。实验验证了当`printk`的参数为非法指针时,会导致死锁。

[Android稳定性] 第014篇 [问题篇] slab内存泄露 8月前查看 评论
[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`、优化工作队列和进行内存泄漏检测,可以有效解决该问题。