Home | History | Annotate | Download | only in linux
      1 /*
      2  * include/linux/sync.h
      3  *
      4  * Copyright (C) 2012 Google, Inc.
      5  *
      6  * This program is distributed in the hope that it will be useful,
      7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      9  * GNU General Public License for more details.
     10  *
     11  */
     12 
     13 #ifndef _LINUX_SYNC_H
     14 #define _LINUX_SYNC_H
     15 
     16 #include <linux/types.h>
     17 #ifdef __KERNEL__
     18 
     19 #include <linux/kref.h>
     20 #include <linux/ktime.h>
     21 #include <linux/list.h>
     22 #include <linux/spinlock.h>
     23 #include <linux/wait.h>
     24 
     25 struct sync_timeline;
     26 struct sync_pt;
     27 struct sync_fence;
     28 
     29 /**
     30  * struct sync_timeline_ops - sync object implementation ops
     31  * @driver_name:	name of the implentation
     32  * @dup:		duplicate a sync_pt
     33  * @has_signaled:	returns:
     34  *			  1 if pt has signaled
     35  *			  0 if pt has not signaled
     36  *			 <0 on error
     37  * @compare:		returns:
     38  *			  1 if b will signal before a
     39  *			  0 if a and b will signal at the same time
     40  *			 -1 if a will signabl before b
     41  * @free_pt:		called before sync_pt is freed
     42  * @release_obj:	called before sync_timeline is freed
     43  * @print_obj:		print aditional debug information about sync_timeline.
     44  *			  should not print a newline
     45  * @print_pt:		print aditional debug information about sync_pt.
     46  *			  should not print a newline
     47  * @fill_driver_data:	write implmentation specific driver data to data.
     48  *			  should return an error if there is not enough room
     49  *			  as specified by size.  This information is returned
     50  *			  to userspace by SYNC_IOC_FENCE_INFO.
     51  */
     52 struct sync_timeline_ops {
     53 	const char *driver_name;
     54 
     55 	/* required */
     56 	struct sync_pt *(*dup)(struct sync_pt *pt);
     57 
     58 	/* required */
     59 	int (*has_signaled)(struct sync_pt *pt);
     60 
     61 	/* required */
     62 	int (*compare)(struct sync_pt *a, struct sync_pt *b);
     63 
     64 	/* optional */
     65 	void (*free_pt)(struct sync_pt *sync_pt);
     66 
     67 	/* optional */
     68 	void (*release_obj)(struct sync_timeline *sync_timeline);
     69 
     70 	/* optional */
     71 	void (*print_obj)(struct seq_file *s,
     72 			  struct sync_timeline *sync_timeline);
     73 
     74 	/* optional */
     75 	void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
     76 
     77 	/* optional */
     78 	int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
     79 };
     80 
     81 /**
     82  * struct sync_timeline - sync object
     83  * @kref:		reference count on fence.
     84  * @ops:		ops that define the implementaiton of the sync_timeline
     85  * @name:		name of the sync_timeline. Useful for debugging
     86  * @destoryed:		set when sync_timeline is destroyed
     87  * @child_list_head:	list of children sync_pts for this sync_timeline
     88  * @child_list_lock:	lock protecting @child_list_head, destroyed, and
     89  *			  sync_pt.status
     90  * @active_list_head:	list of active (unsignaled/errored) sync_pts
     91  * @sync_timeline_list:	membership in global sync_timeline_list
     92  */
     93 struct sync_timeline {
     94 	struct kref		kref;
     95 	const struct sync_timeline_ops	*ops;
     96 	char			name[32];
     97 
     98 	/* protected by child_list_lock */
     99 	bool			destroyed;
    100 
    101 	struct list_head	child_list_head;
    102 	spinlock_t		child_list_lock;
    103 
    104 	struct list_head	active_list_head;
    105 	spinlock_t		active_list_lock;
    106 
    107 	struct list_head	sync_timeline_list;
    108 };
    109 
    110 /**
    111  * struct sync_pt - sync point
    112  * @parent:		sync_timeline to which this sync_pt belongs
    113  * @child_list:		membership in sync_timeline.child_list_head
    114  * @active_list:	membership in sync_timeline.active_list_head
    115  * @signaled_list:	membership in temorary signaled_list on stack
    116  * @fence:		sync_fence to which the sync_pt belongs
    117  * @pt_list:		membership in sync_fence.pt_list_head
    118  * @status:		1: signaled, 0:active, <0: error
    119  * @timestamp:		time which sync_pt status transitioned from active to
    120  *			  singaled or error.
    121  */
    122 struct sync_pt {
    123 	struct sync_timeline		*parent;
    124 	struct list_head	child_list;
    125 
    126 	struct list_head	active_list;
    127 	struct list_head	signaled_list;
    128 
    129 	struct sync_fence	*fence;
    130 	struct list_head	pt_list;
    131 
    132 	/* protected by parent->active_list_lock */
    133 	int			status;
    134 
    135 	ktime_t			timestamp;
    136 };
    137 
    138 /**
    139  * struct sync_fence - sync fence
    140  * @file:		file representing this fence
    141  * @kref:		referenace count on fence.
    142  * @name:		name of sync_fence.  Useful for debugging
    143  * @pt_list_head:	list of sync_pts in ths fence.  immutable once fence
    144  *			  is created
    145  * @waiter_list_head:	list of asynchronous waiters on this fence
    146  * @waiter_list_lock:	lock protecting @waiter_list_head and @status
    147  * @status:		1: signaled, 0:active, <0: error
    148  *
    149  * @wq:			wait queue for fence signaling
    150  * @sync_fence_list:	membership in global fence list
    151  */
    152 struct sync_fence {
    153 	struct file		*file;
    154 	struct kref		kref;
    155 	char			name[32];
    156 
    157 	/* this list is immutable once the fence is created */
    158 	struct list_head	pt_list_head;
    159 
    160 	struct list_head	waiter_list_head;
    161 	spinlock_t		waiter_list_lock; /* also protects status */
    162 	int			status;
    163 
    164 	wait_queue_head_t	wq;
    165 
    166 	struct list_head	sync_fence_list;
    167 };
    168 
    169 struct sync_fence_waiter;
    170 typedef void (*sync_callback_t)(struct sync_fence *fence,
    171 				struct sync_fence_waiter *waiter);
    172 
    173 /**
    174  * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
    175  * @waiter_list:	membership in sync_fence.waiter_list_head
    176  * @callback:		function pointer to call when fence signals
    177  * @callback_data:	pointer to pass to @callback
    178  */
    179 struct sync_fence_waiter {
    180 	struct list_head	waiter_list;
    181 
    182 	sync_callback_t		callback;
    183 };
    184 
    185 static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
    186 					  sync_callback_t callback)
    187 {
    188 	waiter->callback = callback;
    189 }
    190 
    191 /*
    192  * API for sync_timeline implementers
    193  */
    194 
    195 /**
    196  * sync_timeline_create() - creates a sync object
    197  * @ops:	specifies the implemention ops for the object
    198  * @size:	size to allocate for this obj
    199  * @name:	sync_timeline name
    200  *
    201  * Creates a new sync_timeline which will use the implemetation specified by
    202  * @ops.  @size bytes will be allocated allowing for implemntation specific
    203  * data to be kept after the generic sync_timeline stuct.
    204  */
    205 struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
    206 					   int size, const char *name);
    207 
    208 /**
    209  * sync_timeline_destory() - destorys a sync object
    210  * @obj:	sync_timeline to destroy
    211  *
    212  * A sync implemntation should call this when the @obj is going away
    213  * (i.e. module unload.)  @obj won't actually be freed until all its childern
    214  * sync_pts are freed.
    215  */
    216 void sync_timeline_destroy(struct sync_timeline *obj);
    217 
    218 /**
    219  * sync_timeline_signal() - signal a status change on a sync_timeline
    220  * @obj:	sync_timeline to signal
    221  *
    222  * A sync implemntation should call this any time one of it's sync_pts
    223  * has signaled or has an error condition.
    224  */
    225 void sync_timeline_signal(struct sync_timeline *obj);
    226 
    227 /**
    228  * sync_pt_create() - creates a sync pt
    229  * @parent:	sync_pt's parent sync_timeline
    230  * @size:	size to allocate for this pt
    231  *
    232  * Creates a new sync_pt as a chiled of @parent.  @size bytes will be
    233  * allocated allowing for implemntation specific data to be kept after
    234  * the generic sync_timeline struct.
    235  */
    236 struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
    237 
    238 /**
    239  * sync_pt_free() - frees a sync pt
    240  * @pt:		sync_pt to free
    241  *
    242  * This should only be called on sync_pts which have been created but
    243  * not added to a fence.
    244  */
    245 void sync_pt_free(struct sync_pt *pt);
    246 
    247 /**
    248  * sync_fence_create() - creates a sync fence
    249  * @name:	name of fence to create
    250  * @pt:		sync_pt to add to the fence
    251  *
    252  * Creates a fence containg @pt.  Once this is called, the fence takes
    253  * ownership of @pt.
    254  */
    255 struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
    256 
    257 /*
    258  * API for sync_fence consumers
    259  */
    260 
    261 /**
    262  * sync_fence_merge() - merge two fences
    263  * @name:	name of new fence
    264  * @a:		fence a
    265  * @b:		fence b
    266  *
    267  * Creates a new fence which contains copies of all the sync_pts in both
    268  * @a and @b.  @a and @b remain valid, independent fences.
    269  */
    270 struct sync_fence *sync_fence_merge(const char *name,
    271 				    struct sync_fence *a, struct sync_fence *b);
    272 
    273 /**
    274  * sync_fence_fdget() - get a fence from an fd
    275  * @fd:		fd referencing a fence
    276  *
    277  * Ensures @fd references a valid fence, increments the refcount of the backing
    278  * file, and returns the fence.
    279  */
    280 struct sync_fence *sync_fence_fdget(int fd);
    281 
    282 /**
    283  * sync_fence_put() - puts a refernnce of a sync fence
    284  * @fence:	fence to put
    285  *
    286  * Puts a reference on @fence.  If this is the last reference, the fence and
    287  * all it's sync_pts will be freed
    288  */
    289 void sync_fence_put(struct sync_fence *fence);
    290 
    291 /**
    292  * sync_fence_install() - installs a fence into a file descriptor
    293  * @fence:	fence to instal
    294  * @fd:		file descriptor in which to install the fence
    295  *
    296  * Installs @fence into @fd.  @fd's should be acquired through get_unused_fd().
    297  */
    298 void sync_fence_install(struct sync_fence *fence, int fd);
    299 
    300 /**
    301  * sync_fence_wait_async() - registers and async wait on the fence
    302  * @fence:		fence to wait on
    303  * @waiter:		waiter callback struck
    304  *
    305  * Returns 1 if @fence has already signaled.
    306  *
    307  * Registers a callback to be called when @fence signals or has an error.
    308  * @waiter should be initialized with sync_fence_waiter_init().
    309  */
    310 int sync_fence_wait_async(struct sync_fence *fence,
    311 			  struct sync_fence_waiter *waiter);
    312 
    313 /**
    314  * sync_fence_cancel_async() - cancels an async wait
    315  * @fence:		fence to wait on
    316  * @waiter:		waiter callback struck
    317  *
    318  * returns 0 if waiter was removed from fence's async waiter list.
    319  * returns -ENOENT if waiter was not found on fence's async waiter list.
    320  *
    321  * Cancels a previously registered async wait.  Will fail gracefully if
    322  * @waiter was never registered or if @fence has already signaled @waiter.
    323  */
    324 int sync_fence_cancel_async(struct sync_fence *fence,
    325 			    struct sync_fence_waiter *waiter);
    326 
    327 /**
    328  * sync_fence_wait() - wait on fence
    329  * @fence:	fence to wait on
    330  * @tiemout:	timeout in ms
    331  *
    332  * Wait for @fence to be signaled or have an error.  Waits indefinitely
    333  * if @timeout < 0
    334  */
    335 int sync_fence_wait(struct sync_fence *fence, long timeout);
    336 
    337 #endif /* __KERNEL__ */
    338 
    339 /**
    340  * struct sync_merge_data - data passed to merge ioctl
    341  * @fd2:	file descriptor of second fence
    342  * @name:	name of new fence
    343  * @fence:	returns the fd of the new fence to userspace
    344  */
    345 struct sync_merge_data {
    346 	__s32	fd2; /* fd of second fence */
    347 	char	name[32]; /* name of new fence */
    348 	__s32	fence; /* fd on newly created fence */
    349 };
    350 
    351 /**
    352  * struct sync_pt_info - detailed sync_pt information
    353  * @len:		length of sync_pt_info including any driver_data
    354  * @obj_name:		name of parent sync_timeline
    355  * @driver_name:	name of driver implmenting the parent
    356  * @status:		status of the sync_pt 0:active 1:signaled <0:error
    357  * @timestamp_ns:	timestamp of status change in nanoseconds
    358  * @driver_data:	any driver dependant data
    359  */
    360 struct sync_pt_info {
    361 	__u32	len;
    362 	char	obj_name[32];
    363 	char	driver_name[32];
    364 	__s32	status;
    365 	__u64	timestamp_ns;
    366 
    367 	__u8	driver_data[0];
    368 };
    369 
    370 /**
    371  * struct sync_fence_info_data - data returned from fence info ioctl
    372  * @len:	ioctl caller writes the size of the buffer its passing in.
    373  *		ioctl returns length of sync_fence_data reutnred to userspace
    374  *		including pt_info.
    375  * @name:	name of fence
    376  * @status:	status of fence. 1: signaled 0:active <0:error
    377  * @pt_info:	a sync_pt_info struct for every sync_pt in the fence
    378  */
    379 struct sync_fence_info_data {
    380 	__u32	len;
    381 	char	name[32];
    382 	__s32	status;
    383 
    384 	__u8	pt_info[0];
    385 };
    386 
    387 #define SYNC_IOC_MAGIC		'>'
    388 
    389 /**
    390  * DOC: SYNC_IOC_WAIT - wait for a fence to signal
    391  *
    392  * pass timeout in milliseconds.  Waits indefinitely timeout < 0.
    393  */
    394 #define SYNC_IOC_WAIT		_IOW(SYNC_IOC_MAGIC, 0, __s32)
    395 
    396 /**
    397  * DOC: SYNC_IOC_MERGE - merge two fences
    398  *
    399  * Takes a struct sync_merge_data.  Creates a new fence containing copies of
    400  * the sync_pts in both the calling fd and sync_merge_data.fd2.  Returns the
    401  * new fence's fd in sync_merge_data.fence
    402  */
    403 #define SYNC_IOC_MERGE		_IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
    404 
    405 /**
    406  * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
    407  *
    408  * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
    409  * Caller should write the size of the buffer into len.  On return, len is
    410  * updated to reflect the total size of the sync_fence_info_data including
    411  * pt_info.
    412  *
    413  * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
    414  * To itterate over the sync_pt_infos, use the sync_pt_info.len field.
    415  */
    416 #define SYNC_IOC_FENCE_INFO	_IOWR(SYNC_IOC_MAGIC, 2,\
    417 	struct sync_fence_info_data)
    418 
    419 #endif /* _LINUX_SYNC_H */
    420