SuperAPI AI 工具集

kernel-memory-management

编程与开发

查看项目

更新于 10-15 15:12

技能介绍

用途

该技能用于引导智能体处理 Linux 内核内存分配相关任务,覆盖物理页分配器(buddy)、SLUB kmalloc 缓存、vmalloc 虚拟映射、内存区(DMA/Normal)以及驱动程序中的安全分配模式,是对 kernel/kernel-internals 技能的扩展。

适用时机

  • 在 kmalloc、vmalloc、get_free_pages 之间做选择
  • 调试内核 OOM 或 slab 损坏
  • 处理 DMA 缓冲区分配需求
  • 理解 /proc/meminfo 与 slab 统计

工作流程

1. 分配器决策树

需要物理连续内存用于 DMA?
├── 是 → dma_alloc_coherent() 或 CMA pool
└── 否
    ├── 大小 ≤ ~128K(依赖架构)→ kmalloc / kzalloc
    ├── 较大或允许非连续 → vmalloc / vzalloc
    └── 整页 → alloc_pages() / __get_free_pages()

2. kmalloc 与 SLUB

SLUB 是默认的通用 kmalloc 后端;旧版 SLAB 分配器已在 Linux 6.12 中移除。

void *buf = kmalloc(size, GFP_KERNEL);
if (!buf)
    return -ENOMEM;
/* ... */
kfree(buf);

GFP 标志:

GFP 标志 上下文
GFP_KERNEL 进程上下文,可能睡眠
GFP_ATOMIC IRQ / 持有自旋锁——使用更小的池
GFP_DMA DMA 区(旧式 32 位设备)

可通过 /proc/slabinfo 和 cat /sys/kernel/slab/*/object_size 检查。

3. vmalloc

void *v = vmalloc(size);  /* 虚拟连续,物理分散 */
vfree(v);

适用于不需要物理连续页的大缓冲区。若用于 DMA,须先使用 dma_map_*。

4. 伙伴页分配器

struct page *page = alloc_pages(GFP_KERNEL, order);
void *addr = page_address(page);
__free_pages(page, order);

order n 分配 2^n 个页。内存区选择:ZONE_DMA、ZONE_NORMAL、ZONE_MOVABLE(参见 include/linux/mmzone.h)。

5. NUMA 基础

在 NUMA 系统上,kmalloc 优先本地节点;HPC 路径可使用 alloc_pages_node() 或 mbind 策略,另见 skills/allocators/numa-programming。

6. 调试

cat /proc/meminfo
cat /proc/slabinfo
dmesg | grep -i oom

内核配置:CONFIG_SLUB_DEBUG、CONFIG_KASAN(用于 use-after-free 检测)。

7. 智能体用法

/kernel-memory-management 在进程上下文中为 2 MiB 驱动环形缓冲区选择分配器

常见问题

症状 原因 修复
kmalloc 大块失败 超出 kmalloc 上限 改用 vmalloc 或页分配
DMA 缓冲区错误 用 vmalloc 做硬件 DMA 使用 dma_alloc_coherent
OOM killer 缓存无界增长 限制池;使用 shrinker
Slab 损坏 use-after-free KASAN;检查 kfree 配对
IRQ 中使用 GFP_KERNEL 原子上下文调用可睡眠分配器 改用 GFP_ATOMIC

相关技能

  • skills/kernel/kernel-internals——page cache、OOM killer
  • skills/kernel/device-drivers——dma_alloc_coherent
  • skills/allocators/custom-allocators——用户态分配器设计
  • skills/allocators/numa-programming——NUMA 感知分配
  • skills/runtimes/sanitizers——KASAN 重叠