^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ===================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) Sync File API Guide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ===================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) :Author: Gustavo Padovan <gustavo at padovan dot org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) This document serves as a guide for device drivers writers on what the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) sync_file API is, and how drivers can support it. Sync file is the carrier of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) the fences(struct dma_fence) that are needed to synchronize between drivers or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) across process boundaries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) The sync_file API is meant to be used to send and receive fence information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) to/from userspace. It enables userspace to do explicit fencing, where instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) of attaching a fence to the buffer a producer driver (such as a GPU or V4L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) driver) sends the fence related to the buffer to userspace via a sync_file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) The sync_file then can be sent to the consumer (DRM driver for example), that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) will not use the buffer for anything before the fence(s) signals, i.e., the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) driver that issued the fence is not using/processing the buffer anymore, so it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) signals that the buffer is ready to use. And vice-versa for the consumer ->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) producer part of the cycle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) Sync files allows userspace awareness on buffer sharing synchronization between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) Sync file was originally added in the Android kernel but current Linux Desktop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) can benefit a lot from it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) in-fences and out-fences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) ------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) Sync files can go either to or from userspace. When a sync_file is sent from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) the driver to userspace we call the fences it contains 'out-fences'. They are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) related to a buffer that the driver is processing or is going to process, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) the driver creates an out-fence to be able to notify, through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) dma_fence_signal(), when it has finished using (or processing) that buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) Out-fences are fences that the driver creates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) On the other hand if the driver receives fence(s) through a sync_file from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) userspace we call these fence(s) 'in-fences'. Receiving in-fences means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) we need to wait for the fence(s) to signal before using any buffer related to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) the in-fences.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) Creating Sync Files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) -------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) When a driver needs to send an out-fence userspace it creates a sync_file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) Interface::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct sync_file *sync_file_create(struct dma_fence *fence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) The caller pass the out-fence and gets back the sync_file. That is just the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) first step, next it needs to install an fd on sync_file->file. So it gets an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) fd::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) fd = get_unused_fd_flags(O_CLOEXEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) and installs it on sync_file->file::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) fd_install(fd, sync_file->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) The sync_file fd now can be sent to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) If the creation process fail, or the sync_file needs to be released by any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) other reason fput(sync_file->file) should be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) Receiving Sync Files from Userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) -----------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) When userspace needs to send an in-fence to the driver it passes file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) of the Sync File to the kernel. The kernel can then retrieve the fences
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) from it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) Interface::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct dma_fence *sync_file_get_fence(int fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) The returned reference is owned by the caller and must be disposed of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) afterwards using dma_fence_put(). In case of error, a NULL is returned instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) References:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 1. struct sync_file in include/linux/sync_file.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 2. All interfaces mentioned above defined in include/linux/sync_file.h