一、架构设计

在Linux DRM(Direct Rendering Manager)图形子系统中, dma_resv 机制是确保多个进程或硬件引擎安全、高效地共享图形缓冲区(buffer)的核心。它主要通过 ww_mutex ( wound-wait 互斥锁)和 dma_fence (DMA围栏)来协同工作。下图概括了其关键的工作流程:

在这里插入图片描述

二、数据结构及关键代码实现

  1. 数据结构

dma_resv 结构体(定义在 linux/dma-resv.h 中)的简化视图如下:

struct dma_resv {
struct ww_mutex lock; // 保护内部数据的互斥锁,采用 wound-wait 算法
struct dma_fence __rcu *fence_excl; // 独占(写)操作的围栏
struct dma_resv_list __rcu *fence_shared; // 共享(读)操作的围栏列表
};

它的两个核心组件分工如下:

ww_mutex lock :这是保护缓冲区访问权限的“大门锁”。它的特殊之处在于实现了 wound-wait 死锁避免算法。当多个进程(或事务)需要同时锁定一组缓冲区,但请求锁的顺序可能形成循环等待时(例如进程A锁了缓冲区1想锁缓冲区2,进程B锁了缓冲区2想锁缓冲区1), ww_mutex 会根据事务的“年龄”(启动顺序)决定回滚(wound)较年轻的事务,让其释放已获得的锁,从而打破死锁局面,让较年长的事务先完成。

dma_fence :这是表示异步操作(如GPU命令执行)完成状态的信号机制。一个 dma_fence 有两种基本状态:signaled(操作已完成)和 unsignaled(操作进行中)。它允许一个任务(如显示合成器)等待另一个任务(如GPU渲染器)的完成,而不需要忙等待。 dma_resv 会管理两类 fence:

独占fence:通常代表写操作。一个缓冲区在同一时间只能有一个独占围栏,确保写的排他性。

共享fence:通常代表读操作。一个缓冲区可以同时有多个共享围栏,允许多个消费者并发读取。

2.wait fence完成

等待fence完成: dma_fence_wait_timeout() 是同步等待的核心函数。

signed long dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)

{

// ... 参数检查 ...

trace_dma_fence_wait_start(fence);

ret = fence->ops->wait(fence, intr, timeout); // 调用具体实现的wait操作

trace_dma_fence_wait_end(fence);

return ret;

}

它最终会调用fence特定实现的wait方法,使进程进入睡眠,直到fence被signal或超时。

3.signal fence

标记fence完成: dma_fence_signal() 是触发完成通知的函数。

int dma_fence_signal(struct dma_fence *fence)

{

// ... 检查并设置SIGNALED_BIT ...

trace_dma_fence_signaled(fence);

if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {

    // ... 遍历并执行所有回调函数 ...

}

return 0;

}

它设置状态位,并安全地执行所有注册的回调函数。

  1. critical buffer lock

锁定多个缓冲区: drm_gem_lock_reservations() 是避免死锁的关键。
其实现是 ww_mutex 的典型应用。在获取锁的过程中如果发生冲突,会根据事务的先后顺序(年龄)来解决:较年轻的事务(后发起者)会回退(释放已获得的锁)并等待,让较年长的事务(先发起者)先完成,从而避免死锁。

三、软件使用流程

以GPU渲染一帧图像到缓冲区,然后显示器再从中读取显示为例:

准备阶段:GPU驱动程序准备提交渲染命令。它首先调用 drm_gem_lock_reservations() 锁定所有相关缓冲区的 dma_resv->lock (使用 ww_mutex ),确保当前能独占地设置这些缓冲区的状态。

添加fence:成功上锁后,GPU驱动程序为本次渲染操作创建一个新的 dma_fence ,并将其作为exclusive fence添加到目标帧缓冲区的 dma_resv 中。这标志着“即将有一个写操作要发生”。然后解锁。


完整文章请关注微信公众号:颇锐克科技共享


更多AI,GPU,Linux,Android,芯片行业技术分享请关注微信公众号:颇锐克科技共享。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐