• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
sync_fence_waiter_init(struct sync_fence_waiter * waiter,sync_callback_t callback)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