定义
“Synchronization between consumers and producers who are from different hardware components to use a buffer atomically”
应用背景
在复杂的DMA管线如图形管线(多媒体,摄像头,GPU以及显示设备),一个buffer的消费者需要知道生产者什么时候完成生产(即创建一个Buffer,并往里面放置消费者所需要的数据)。同样地,生产者也需要知道消费者什么时候使用它创建的Buffer,以便它可以重新使用这个Buffer。而且,一个Buffer可能被多个不同的消费者使用不同的时间。另外,一个消费者可能需要互斥地消费多个Buffer,等等,有一个问题应运而生,就是如何保证多个消费者之间同步使用Buffer,以及生产者与消费者协调使用Buffer。因为Buffer是一个共享资源,且任何消费者或生产者对Buffer的使用都是排他性的(因为它们属于不同的硬件单元或模块),大体看来,需要解决如下两个问题:
1. 消费者与生产者之间对Buffer的同步访问。
2. 消费者之间对Buffer的同步访问。
方案提出
在Android中,引入了Sync框架,它添加了一组API,可以允许生产者和消费者之间以一种通用的方式解决上面提到的同步访问问题,平台需要实现这些Driver定义的同步原语以支持这个Sync框架。
Android Sync框架的目标是:
1. 提供一个通用的API用于表达同步依赖关系。
2. 允许驱动在不同的硬件模块中实现同步。
3. 提供了一套用户空间的API,使得Compositor(等硬件模块)可以管理这些依赖。
4. 提供丰富的测量数据,可以调试图形管线变慢和停止的问题。
驱动代码位于drivers/staging/android/sync.c,主要定义了如下三个数据类型:
• sync_timeline
sync_timeline是一种抽象的单调递增的计数器。通常情况下,每个驱动或硬件模块上下文只有一个sync_timeline。一般需要提供硬件模块特有的Sync驱动或使用通用的sw_sync实现,它是基于CPU的一种实现方式。实现上,是通过这些底层的驱动来创建sync_timeline的。一个硬件模块如果要提供Sync支持,则必须实现创建sync_timeline逻辑的驱动。
• sync_pt
sync_pt是一个抽象的值,标记在sync_timeline上。sync_pt只能属于唯一的sync_timeline。它有三种状态:活跃,信号和错误。开始时,处于活跃状态,当sync_timeline的计数值超过了sync_pt的值,就会触发状态转换为信号状态或错误状态。
• sync_fence
sync_fence是驱动间协调同步使用Buffer的主要原语。它包含一系列的sync_pt,这些sync_pt可能来自于不同的sync_timeline。另外,sync_fence上的sync_pt一旦确定,是不可更改的。可以同步或异步等待sync_fence对象状态的改变。两个sync_fence对象也可以合并生成第三个Fence对象,它包含了合并前的两个sync_fence对象的所有sync_pt的拷贝。sync_fence与文件描述符关联,用户空间可以通过它来协调显示管线等硬件单元之间的依赖性关系,即访问Buffer的先后顺序。
If you pass a fence fd to the framework, we will close it(If you want to keep using it, you must dup it, Sf merge fence if need transfer it)
如何使用
一个实现Sync支持的驱动,应该拥有如下一个工作提交函数:
1. 接受一个sync_fence参数,指定什么时候开始工作。
2. 当sync_fence处于信号态后,异步地将对应的工作放入队列中去运行。
3. 返回一个sync_fence对象,包含工作何时结束的信息。
4. 当工作结束后,会将关联的sync_fence对象变成信号态。
接口声明实例:
|
Driver API without fence support /* * assumes buf is ready to be displayed. * blocks until the buffer is on screen. */ void display_buffer(struct dma_buf *buf); |
Driver API with fence support /* * will display buf when fence is signaled. * returns immediately with a fence that will signal * when buf is no longer displayed. */ struct sync_fence* display_buffer(struct dma_buf *buf, struct sync_fence *fence); |
Android Sync框架的软件Stack如下图所示:
Android使用类Fence封装了sync用户接口,所以Android框架层中一般通用Fence类来使用Android Sync框架
Sync驱动
Sync驱动包含两部分:
- fence的通用操作,已经实现
- 各个sync 驱动相关的代码,由各个硬件Vendor实现,其中,基于CPU的sync驱动已经提供
主要数据结构
struct sync_timeline_ops
sync对象需要实现的一些操作
struct sync_timeline
代表一个sync对象的描述
它包含许多struct sync_pt
struct sync_pt
同步点
有三种状态
signaled(status > 0)
active(status = 0)
error(status < 0)
它位于一个sync_timeline以及sync_fence中
struct sync_fence
struct sync_fence_waiter
在一个fence上异步等待的waiter的相关信息
主要API
API focomponentsr sync_time implementers
sync_timeline_create()
创建一个sync对象
sync_timeline_destory()
销毁一个sync对象
sync_timeline_signal()
signal a status change on a sync_timeline
sync_pt_create()
创建一个同步点
sync_pt_free()
释放一个同步点
此函数仅能在该同步点未加入到一个fence前调用
sync_fence_create()
创建一个sync fence
API for sync_fence consumers
sync_fence_merge()
合并两个fence
当两个sync_pt位于同一个timeline时,需要将他们合并成一个sync_pt,
并以触发时间最晚些的那个sync_pt那个为准
sync_fence_fdget()
根据一个fd获取对应的fence对象
sync_fence_put()
减少一次对sync fence的引用
sync_fence_install()
安装fence到一个文件描述符中
sync_fence_waiter_init()
sync_fence_wait_async()
注册和异步等待某个fence对象
sync_fence_cancel_async()
取消一个异步等待
sync_fence_wait()
等待一个fence状态变为signaled 或error
主要有三种IOCTL命令
SYNC_IOC_WAIT
SYNC_IOC_MERGE
SYNC_IOC_FENCE_INFO
fill_driver_data
实现一个Sync-aware的驱动
1.定义自己的timeline, pt数据结构
如Mali 驱动定义的:
struct mali_sync_timeline
{
struct sync_timeline timeline;
atomic_t counter;
atomic_t signalled;
};
struct mali_sync_pt
{
struct sync_pt pt;
u32 order;
s32 error;
};sw sync定义的:
struct sw_sync_timeline {
struct sync_timeline obj;
u32 value;
};
struct sw_sync_pt {
struct sync_pt pt;
u32 value;
};2.提供创建struct sync_timeline, struct sync_pt的接口,
3.实现struct sync_timeline_ops定义的一些回调函数
如sw_sync驱动实现了如下函数,它是创建sync_timeline所必需的:
static struct sync_timeline_ops sw_sync_timeline_ops = {
.driver_name = "sw_sync",
.dup = sw_sync_pt_dup,
.has_signaled = sw_sync_pt_has_signaled,
.compare = sw_sync_pt_compare,
.fill_driver_data = sw_sync_fill_driver_data,
.timeline_value_str = sw_sync_timeline_value_str,
.pt_value_str = sw_sync_pt_value_str,
};4.提供创建fence的接口
根据自身的设计,可能会提供如下两个IOCTL命令,注意区分上面提供的几个通用的IOCTL命令,以提供用户空间创建Fence的接口:
创建Fence的命令:
如sw_sync中定义义了如下命令:
SW_SYNC_IOC_CREATE_FENCE
另外,sw_sync还有一个改变sync_timeline当前值的命令(每个驱动也都会提供类似的操作,根据自身的逻辑,实现方法不尽相同):
SW_SYNC_IOC_INC, 每当这个值变化时,会检查当前的值与位于sync_timeline中的syn_pt的值是否相等,以此来判断状态是否变为信号态。

Android Sync Framework提供了一组API,解决在图形管线等复杂DMA环境中,消费者与生产者以及消费者之间对缓冲区的同步访问问题。通过sync_timeline、sync_pt和sync_fence等数据类型,实现跨硬件模块的同步。驱动开发者需要实现特定的同步原语,而Android框架层则使用Fence类进行交互。该框架旨在确保缓冲区在不同硬件组件间的原子性使用,并提供性能监控数据。
3438

被折叠的 条评论
为什么被折叠?



