sync: add debugfs support
[linux-2.6.git] / include / linux / sync.h
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/ktime.h>
20 #include <linux/list.h>
21 #include <linux/spinlock.h>
22 #include <linux/wait.h>
23
24 struct sync_timeline;
25 struct sync_pt;
26 struct sync_fence;
27
28 /**
29  * struct sync_timeline_ops - sync object implementation ops
30  * @driver_name:        name of the implentation
31  * @dup:                duplicate a sync_pt
32  * @has_signaled:       returns:
33  *                        1 if pt has signaled
34  *                        0 if pt has not signaled
35  *                       <0 on error
36  * @compare:            returns:
37  *                        1 if b will signal before a
38  *                        0 if a and b will signal at the same time
39  *                       -1 if a will signabl before b
40  * @free_pt:            called before sync_pt is freed
41  * @release_obj:        called before sync_timeline is freed
42  * @print_obj:          print aditional debug information about sync_timeline.
43  *                        should not print a newline
44  * @print_pt:           print aditional debug information about sync_pt.
45  *                        should not print a newline
46  */
47 struct sync_timeline_ops {
48         const char *driver_name;
49
50         /* required */
51         struct sync_pt *(*dup)(struct sync_pt *pt);
52
53         /* required */
54         int (*has_signaled)(struct sync_pt *pt);
55
56         /* required */
57         int (*compare)(struct sync_pt *a, struct sync_pt *b);
58
59         /* optional */
60         void (*free_pt)(struct sync_pt *sync_pt);
61
62         /* optional */
63         void (*release_obj)(struct sync_timeline *sync_timeline);
64
65         /* optional */
66         void (*print_obj)(struct seq_file *s,
67                           struct sync_timeline *sync_timeline);
68
69         /* optional */
70         void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
71 };
72
73 /**
74  * struct sync_timeline - sync object
75  * @ops:                ops that define the implementaiton of the sync_timeline
76  * @name:               name of the sync_timeline. Useful for debugging
77  * @destoryed:          set when sync_timeline is destroyed
78  * @child_list_head:    list of children sync_pts for this sync_timeline
79  * @child_list_lock:    lock protecting @child_list_head, destroyed, and
80  *                        sync_pt.status
81  * @active_list_head:   list of active (unsignaled/errored) sync_pts
82  * @sync_timeline_list: membership in global sync_timeline_list
83  */
84 struct sync_timeline {
85         const struct sync_timeline_ops  *ops;
86         char                    name[32];
87
88         /* protected by child_list_lock */
89         bool                    destroyed;
90
91         struct list_head        child_list_head;
92         spinlock_t              child_list_lock;
93
94         struct list_head        active_list_head;
95         spinlock_t              active_list_lock;
96
97         struct list_head        sync_timeline_list;
98 };
99
100 /**
101  * struct sync_pt - sync point
102  * @parent:             sync_timeline to which this sync_pt belongs
103  * @child_list:         membership in sync_timeline.child_list_head
104  * @active_list:        membership in sync_timeline.active_list_head
105  * @fence:              sync_fence to which the sync_pt belongs
106  * @pt_list:            membership in sync_fence.pt_list_head
107  * @status:             1: signaled, 0:active, <0: error
108  * @timestamp:          time which sync_pt status transitioned from active to
109  *                        singaled or error.
110  */
111 struct sync_pt {
112         struct sync_timeline            *parent;
113         struct list_head        child_list;
114
115         struct list_head        active_list;
116
117         struct sync_fence       *fence;
118         struct list_head        pt_list;
119
120         /* protected by parent->active_list_lock */
121         int                     status;
122
123         ktime_t                 timestamp;
124 };
125
126 /**
127  * struct sync_fence - sync fence
128  * @file:               file representing this fence
129  * @name:               name of sync_fence.  Useful for debugging
130  * @pt_list_head:       list of sync_pts in ths fence.  immutable once fence
131  *                        is created
132  * @waiter_list_head:   list of asynchronous waiters on this fence
133  * @waiter_list_lock:   lock protecting @waiter_list_head and @status
134  * @status:             1: signaled, 0:active, <0: error
135  *
136  * @wq:                 wait queue for fence signaling
137  * @sync_fence_list:    membership in global fence list
138  */
139 struct sync_fence {
140         struct file             *file;
141         char                    name[32];
142
143         /* this list is immutable once the fence is created */
144         struct list_head        pt_list_head;
145
146         struct list_head        waiter_list_head;
147         spinlock_t              waiter_list_lock; /* also protects status */
148         int                     status;
149
150         wait_queue_head_t       wq;
151
152         struct list_head        sync_fence_list;
153 };
154
155 /**
156  * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
157  * @waiter_list:        membership in sync_fence.waiter_list_head
158  * @callback:           function pointer to call when fence signals
159  * @callback_data:      pointer to pass to @callback
160  */
161 struct sync_fence_waiter {
162         struct list_head        waiter_list;
163
164         void (*callback)(struct sync_fence *fence, void *data);
165         void *callback_data;
166 };
167
168 /*
169  * API for sync_timeline implementers
170  */
171
172 /**
173  * sync_timeline_create() - creates a sync object
174  * @ops:        specifies the implemention ops for the object
175  * @size:       size to allocate for this obj
176  * @name:       sync_timeline name
177  *
178  * Creates a new sync_timeline which will use the implemetation specified by
179  * @ops.  @size bytes will be allocated allowing for implemntation specific
180  * data to be kept after the generic sync_timeline stuct.
181  */
182 struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
183                                            int size, const char *name);
184
185 /**
186  * sync_timeline_destory() - destorys a sync object
187  * @obj:        sync_timeline to destroy
188  *
189  * A sync implemntation should call this when the @obj is going away
190  * (i.e. module unload.)  @obj won't actually be freed until all its childern
191  * sync_pts are freed.
192  */
193 void sync_timeline_destroy(struct sync_timeline *obj);
194
195 /**
196  * sync_timeline_signal() - signal a status change on a sync_timeline
197  * @obj:        sync_timeline to signal
198  *
199  * A sync implemntation should call this any time one of it's sync_pts
200  * has signaled or has an error condition.
201  */
202 void sync_timeline_signal(struct sync_timeline *obj);
203
204 /**
205  * sync_pt_create() - creates a sync pt
206  * @parent:     sync_pt's parent sync_timeline
207  * @size:       size to allocate for this pt
208  *
209  * Creates a new sync_pt as a chiled of @parent.  @size bytes will be
210  * allocated allowing for implemntation specific data to be kept after
211  * the generic sync_timeline struct.
212  */
213 struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
214
215 /**
216  * sync_pt_free() - frees a sync pt
217  * @pt:         sync_pt to free
218  *
219  * This should only be called on sync_pts which have been created but
220  * not added to a fence.
221  */
222 void sync_pt_free(struct sync_pt *pt);
223
224 /**
225  * sync_fence_create() - creates a sync fence
226  * @name:       name of fence to create
227  * @pt:         sync_pt to add to the fence
228  *
229  * Creates a fence containg @pt.  Once this is called, the fence takes
230  * ownership of @pt.
231  */
232 struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
233
234 /*
235  * API for sync_fence consumers
236  */
237
238 /**
239  * sync_fence_merge() - merge two fences
240  * @name:       name of new fence
241  * @a:          fence a
242  * @b:          fence b
243  *
244  * Creates a new fence which contains copies of all the sync_pts in both
245  * @a and @b.  @a and @b remain valid, independent fences.
246  */
247 struct sync_fence *sync_fence_merge(const char *name,
248                                     struct sync_fence *a, struct sync_fence *b);
249
250 /**
251  * sync_fence_fdget() - get a fence from an fd
252  * @fd:         fd referencing a fence
253  *
254  * Ensures @fd references a valid fence, increments the refcount of the backing
255  * file, and returns the fence.
256  */
257 struct sync_fence *sync_fence_fdget(int fd);
258
259 /**
260  * sync_fence_put() - puts a refernnce of a sync fence
261  * @fence:      fence to put
262  *
263  * Puts a reference on @fence.  If this is the last reference, the fence and
264  * all it's sync_pts will be freed
265  */
266 void sync_fence_put(struct sync_fence *fence);
267
268 /**
269  * sync_fence_install() - installs a fence into a file descriptor
270  * @fence:      fence to instal
271  * @fd:         file descriptor in which to install the fence
272  *
273  * Installs @fence into @fd.  @fd's should be acquired through get_unused_fd().
274  */
275 void sync_fence_install(struct sync_fence *fence, int fd);
276
277 /**
278  * sync_fence_wait_async() - registers and async wait on the fence
279  * @fence:              fence to wait on
280  * @callback:           callback
281  * @callback_data       data to pass to the callback
282  *
283  * Returns 1 if @fence has already signaled.
284  *
285  * Registers a callback to be called when @fence signals or has an error
286  */
287 int sync_fence_wait_async(struct sync_fence *fence,
288                           void (*callback)(struct sync_fence *, void *data),
289                           void *callback_data);
290
291 /**
292  * sync_fence_wait() - wait on fence
293  * @fence:      fence to wait on
294  * @tiemout:    timeout in ms
295  *
296  * Wait for @fence to be signaled or have an error.  Waits indefintly
297  * if @timeout = 0
298  */
299 int sync_fence_wait(struct sync_fence *fence, long timeout);
300
301 #endif /* __KERNEL__ */
302
303 /**
304  * struct sync_merge_data - data passed to merge ioctl
305  * @fd2:        file descriptor of second fence
306  * @name:       name of new fence
307  * @fence:      returns the fd of the new fence to userspace
308  */
309 struct sync_merge_data {
310         __s32   fd2; /* fd of second fence */
311         char    name[32]; /* name of new fence */
312         __s32   fence; /* fd on newly created fence */
313 };
314
315 #define SYNC_IOC_MAGIC          '>'
316
317 /**
318  * DOC: SYNC_IOC_WAIT - wait for a fence to signal
319  *
320  * pass timeout in milliseconds.
321  */
322 #define SYNC_IOC_WAIT           _IOW(SYNC_IOC_MAGIC, 0, __u32)
323
324 /**
325  * DOC: SYNC_IOC_MERGE - merge two fences
326  *
327  * Takes a struct sync_merge_data.  Creates a new fence containing copies of
328  * the sync_pts in both the calling fd and sync_merge_data.fd2.  Returns the
329  * new fence's fd in sync_merge_data.fence
330  */
331 #define SYNC_IOC_MERGE          _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
332
333 #endif /* _LINUX_SYNC_H */