
一、背景与引入
在 Linux 内核中,内存管理并不只局限于伙伴系统(buddy allocator)和 slab/slub 分配器。在许多设备驱动 、SoC 子系统以及 共享内存 场景 中,开发者往往需要管理一块地址固定、大小有限、分配规则特殊的内存区域,例如:
-
设备 MMIO / SRAM / TCM
-
多 OS / 多核共享内存
-
DMA buffer、固件通信缓冲区
-
预留内存(reserved-memory)
这类内存既不适合直接交给 buddy system,也不适合 slab 管理对象生命周期。为此,Linux 内核提供了一个相对独立、通用而轻量的组件 ------ genpool(Generic Memory Pool)。
本文将从设计动机、核心数据结构、分配算法以及典型使用场景几个方面,对 Linux genpool 进行系统性介绍。
二、什么是 genpool
genpool(Generic Pool) 是 Linux 内核中的一种通用 内存 池管理机制 ,用于在一段连续的物理或虚拟地址区间上,按固定最小粒度(granularity)进行动态分配和释放。
其核心目标可以概括为三点:
-
管理非伙伴系统的 内存 区域
-
提供确定性强、开销低的分配接口
-
适用于驱动和平台代码的早期或特殊 内存 管理
genpool 的实现位于内核源码:
lib/genalloc.c include/linux/genalloc.h

三、genpool 的典型使用场景
在内核中,genpool 被广泛用于以下场景:
-
SoC 驱动:管理片上 SRAM / TCM
-
设备固件通信:Host--Device 共享内存
-
DMA 子系统:特定地址范围的 buffer 分配
-
reserved-memory:设备树中预留内存的管理
-
多 OS / 多核系统:共享 non-cache memory
这些场景具有一个共同特征:
内存区域的起始地址和大小在系统设计阶段已知,但运行时需要进行灵活分配。

有很多和bitmap相关的算法

四、genpool 的核心设计思想
4.1 固定粒度(granularity)
创建 genpool 时,需要指定一个 最小分配粒度(通常是 2 的幂,例如 32B / 64B / 4KB):
struct gen_pool *gen_pool_create(int min_alloc_order, int nid);
-
min_alloc_order:最小分配单位 = 2^order 字节 -
genpool 内部所有管理都基于该粒度
这使得 genpool 在嵌入式 和实时场景中具有非常稳定的分配行为。
4.2 基于位图(bitmap)的空间管理
genpool 内部并不维护复杂的红黑树或链表,而是采用:
-
bitmap 描述 内存 块使用情况
-
每一 bit 对应一个最小粒度单元
这种设计带来的好处包括:
-
空间开销小
-
实现简单、易于验证
-
非常适合硬件资源管理
4.3 chunk 抽象
genpool 并不要求所有内存一次性加入,而是引入了 chunk 的概念。

每个 chunk 对应一段连续地址空间:
-
start_addr ~ end_addr -
配套一份 bitmap
一个 genpool 可以由多个 chunk 组成,这使其在平台初始化阶段具有更高的灵活性。
五、genpool 的分配与释放机制
5.1 添加内存到 genpool

该接口用于将一段内存区域注册到 genpool 中,通常发生在:
-
平台初始化
-
驱动 probe 阶段


bits是尾部的变长数组,已经都一起分配并且清零了
5.2 内存分配

分配流程简要概括为:
-
将 size 向上对齐到最小粒度
-
遍历 pool 中的各个 chunk
-
在 bitmap 中查找连续空闲 bit 区间
-
标记 bit 为已使用
-
返回对应地址
genpool 不保证最佳适配(best-fit),而是更偏向简单、快速、可预测的策略。
可以选择最快或者最佳适应的算法


bitmap_set_ll是在读锁下面的操作,竞争,如果没有设置完所有的bit,就清除自己设置的bit,因为流程都是从前到后的顺序设置的,这个开读锁再竞争的操作真的骚
5.3 内存释放

释放时:
-
根据地址定位 chunk
-
将对应 bitmap bit 清零
genpool 不维护对象元数据,因此调用者必须保证:
释放地址和大小必须与分配时一致。

六、并发与同步模型
-
genpool 本身不强制绑定特定锁模型
-
内部使用 spinlock 保护关键路径:只有加chunk链表要上spinlock
-
适用于 IRQ / 原子上下文(部分接口)
这使 genpool 能够安全地被驱动和底层平台代码调用。
七、与其他内存管理机制的对比
|--------------|--------|-----------|
| 机制 | 适用场景 | 特点 |
| buddy system | 通用物理内存 | 面向页、全局管理 |
| slab/slub | 内核对象 | 生命周期明确 |
| memblock | 启动早期 | 只分配不释放 |
| genpool | 固定地址内存 | 粒度固定、实现简单 |
genpool 处在一个非常明确的位置:
它不是通用 内存 分配器,而是资源管理工具。
八、genpool 在系统设计中的价值
从系统架构角度看,genpool 具备以下优势:
-
将"内存资源管理"从业务逻辑中剥离
-
适合作为多 OS / 多核共享内存的底层组件
-
便于进行调试和可视化(bitmap)
-
实现稳定,长期维护
在复杂 SoC 和异构系统中,genpool 往往是比自研 bitmap allocator 更稳妥的选择。