Back to home page

LXR

 
 

    


0001                               Sync File API Guide
0002                               ~~~~~~~~~~~~~~~~~~~
0003 
0004                                 Gustavo Padovan
0005                           <gustavo at padovan dot org>
0006 
0007 This document serves as a guide for device drivers writers on what the
0008 sync_file API is, and how drivers can support it. Sync file is the carrier of
0009 the fences(struct dma_fence) that are needed to synchronize between drivers or
0010 across process boundaries.
0011 
0012 The sync_file API is meant to be used to send and receive fence information
0013 to/from userspace. It enables userspace to do explicit fencing, where instead
0014 of attaching a fence to the buffer a producer driver (such as a GPU or V4L
0015 driver) sends the fence related to the buffer to userspace via a sync_file.
0016 
0017 The sync_file then can be sent to the consumer (DRM driver for example), that
0018 will not use the buffer for anything before the fence(s) signals, i.e., the
0019 driver that issued the fence is not using/processing the buffer anymore, so it
0020 signals that the buffer is ready to use. And vice-versa for the consumer ->
0021 producer part of the cycle.
0022 
0023 Sync files allows userspace awareness on buffer sharing synchronization between
0024 drivers.
0025 
0026 Sync file was originally added in the Android kernel but current Linux Desktop
0027 can benefit a lot from it.
0028 
0029 in-fences and out-fences
0030 ------------------------
0031 
0032 Sync files can go either to or from userspace. When a sync_file is sent from
0033 the driver to userspace we call the fences it contains 'out-fences'. They are
0034 related to a buffer that the driver is processing or is going to process, so
0035 the driver creates an out-fence to be able to notify, through
0036 dma_fence_signal(), when it has finished using (or processing) that buffer.
0037 Out-fences are fences that the driver creates.
0038 
0039 On the other hand if the driver receives fence(s) through a sync_file from
0040 userspace we call these fence(s) 'in-fences'. Receiveing in-fences means that
0041 we need to wait for the fence(s) to signal before using any buffer related to
0042 the in-fences.
0043 
0044 Creating Sync Files
0045 -------------------
0046 
0047 When a driver needs to send an out-fence userspace it creates a sync_file.
0048 
0049 Interface:
0050         struct sync_file *sync_file_create(struct dma_fence *fence);
0051 
0052 The caller pass the out-fence and gets back the sync_file. That is just the
0053 first step, next it needs to install an fd on sync_file->file. So it gets an
0054 fd:
0055 
0056         fd = get_unused_fd_flags(O_CLOEXEC);
0057 
0058 and installs it on sync_file->file:
0059 
0060         fd_install(fd, sync_file->file);
0061 
0062 The sync_file fd now can be sent to userspace.
0063 
0064 If the creation process fail, or the sync_file needs to be released by any
0065 other reason fput(sync_file->file) should be used.
0066 
0067 Receiving Sync Files from Userspace
0068 -----------------------------------
0069 
0070 When userspace needs to send an in-fence to the driver it passes file descriptor
0071 of the Sync File to the kernel. The kernel can then retrieve the fences
0072 from it.
0073 
0074 Interface:
0075         struct dma_fence *sync_file_get_fence(int fd);
0076 
0077 
0078 The returned reference is owned by the caller and must be disposed of
0079 afterwards using dma_fence_put(). In case of error, a NULL is returned instead.
0080 
0081 References:
0082 [1] struct sync_file in include/linux/sync_file.h
0083 [2] All interfaces mentioned above defined in include/linux/sync_file.h