一、代码分析
1. 代码分析
drm_mm.c 的分析
- 概述:这是一个通用的简单内存范围分配器(range allocator),专为 DRM(Direct Rendering Manager)子系统设计,用于管理 GPU 或图形驱动中的内存区域分配。它不进行实际内存分配,而是跟踪和管理范围(ranges),支持预分配块的保留、颜色调整(用于缓存域等限制)、对齐限制和范围限制。内部使用间隔树(interval tree)和红黑树(rb-tree)来优化查找和插入操作。算法简单,适合 GPU 的特殊需求,但不追求极致性能(如碎片化优化)。它支持自底向上(bottom-up)和自顶向下(top-down)的分配策略,以及扫描模式用于驱逐(evict)对象以腾出空间。
- 关键数据结构:
- drm_mm:分配器主结构,包含间隔树、孔洞栈(hole stack)和红黑树,用于跟踪节点和空闲孔洞。
- drm_mm_node:表示分配的节点,包含起始地址、大小、颜色等。
- 特性:
- 支持预保留节点(reserve node),用于接管固件配置。
- 支持扫描模式(scan mode),用于 LRU(Least Recently Used)驱逐,以腾出连续空间。
- 调试功能:内存泄漏跟踪和打印分配状态。
- 非线程安全:驱动程序需自行加锁。
- 潜在问题:碎片化可能导致性能问题,但适合 GPU 的线性分配需求。
drm_vma_manager.c 的分析
- 概述:这是一个 VMA(Virtual Memory Area)偏移管理器,用于将驱动程序特定的内存区域映射到用户空间的线性地址空间。它提供偏移量(offsets),允许用户空间通过 mmap 系统调用访问 DRM 设备内存。它确保区域不重叠、大小合适,并避免与内核 mm-core 冲突。内部使用 drm_mm 作为后端进行实际范围分配,但添加了访问控制(allow/revoke)和快速查找(rb-tree)。它不用于 VMEM(视频内存)对象放置,仅用于用户空间线性 VM 映射。
- 关键数据结构:
- drm_vma_offset_manager:管理器结构,包含 drm_mm 作为地址空间后端,以及读写锁。
- drm_vma_offset_node:节点结构,嵌入 drm_mm_node,并添加访问控制的 rb-tree(用于文件标签)。
- drm_vma_offset_file:表示允许访问的文件标签(tag),用于权限管理。
- 特性:
- 支持页面对齐的偏移分配。
- 访问控制:通过 allow/revoke 管理文件上下文的访问权限,防止未授权 mmap。
- 查找优化:使用 rb-tree 加速偏移查找。
- 与 mm-core 兼容:确保 VM 是线性的,避免多管理器冲突。
- 潜在问题:节点分配/销毁由调用者负责;必须严格匹配 allow 和 revoke 以避免内存泄漏。
两个代码之间的联系
- 依赖关系:drm_vma_manager.c 强烈依赖 drm_mm.c,将其作为后端使用。具体来说:
- drm_vma_offset_manager 内部的 vm_addr_space_mm 是 drm_mm 的实例,用于实际管理偏移范围。
- drm_vma_offset_manager_init 调用 drm_mm_init 初始化后端。
- drm_vma_offset_manager_destroy 调用 drm_mm_takedown 清理后端。
- drm_vma_offset_add 调用 drm_mm_insert_node 插入节点