同步文件 API 指南¶
- 作者:
Gustavo Padovan <gustavo at padovan dot org>
本文档旨在指导设备驱动程序编写者了解 sync_file API 是什么,以及驱动程序如何支持它。 Sync 文件是 fences(struct dma_fence
) 的载体,需要在驱动程序之间或跨进程边界进行同步。
sync_file API 旨在用于向/从用户空间发送和接收 fence 信息。 它使用户空间能够进行显式 fencing,即生产者驱动程序(如 GPU 或 V4L 驱动程序)不是将 fence 附加到缓冲区,而是通过 sync_file 将与缓冲区相关的 fence 发送到用户空间。
然后可以将 sync_file 发送到消费者(例如 DRM 驱动程序),在 fence 发出信号之前,它不会将缓冲区用于任何事情,即,发出 fence 的驱动程序不再使用/处理缓冲区,因此它发出信号表明该缓冲区已准备好使用。 对于消费者 -> 生产者周期部分,情况正好相反。
Sync 文件允许用户空间了解驱动程序之间缓冲区共享的同步。
Sync 文件最初是在 Android 内核中添加的,但当前的 Linux 桌面可以从中受益匪浅。
in-fences 和 out-fences¶
Sync 文件可以发送到用户空间或从用户空间发送。 当 sync_file 从驱动程序发送到用户空间时,我们称其包含的 fences 为“out-fences”。 它们与驱动程序正在处理或将要处理的缓冲区相关,因此驱动程序创建一个 out-fence 以便能够通过 dma_fence_signal()
通知何时完成使用(或处理)该缓冲区。 Out-fences 是驱动程序创建的 fences。
另一方面,如果驱动程序通过来自用户空间的 sync_file 接收 fence,我们称这些 fence 为“in-fences”。 接收 in-fences 意味着我们需要等待 fence 发出信号,然后才能使用与 in-fences 相关的任何缓冲区。
创建 Sync 文件¶
当驱动程序需要将 out-fence 发送到用户空间时,它会创建一个 sync_file。
接口
struct sync_file *sync_file_create(struct dma_fence *fence);
调用者传递 out-fence 并返回 sync_file。 这只是第一步,接下来需要在 sync_file->file 上安装一个 fd。 所以它获得一个 fd
fd = get_unused_fd_flags(O_CLOEXEC);
并将其安装在 sync_file->file 上
fd_install(fd, sync_file->file);
现在可以将 sync_file fd 发送到用户空间。
如果创建过程失败,或者由于任何其他原因需要释放 sync_file,则应使用 fput(sync_file->file)。
从用户空间接收 Sync 文件¶
当用户空间需要将 in-fence 发送到驱动程序时,它会将 Sync 文件的文件描述符传递给内核。 然后,内核可以从中检索 fences。
接口
struct dma_fence *sync_file_get_fence(int fd);
返回的引用归调用者所有,之后必须使用 dma_fence_put()
处理掉。 如果发生错误,则返回 NULL。
参考文献
struct sync_file
在 include/linux/sync_file.h 中上面提到的所有接口都在 include/linux/sync_file.h 中定义