Commit | Line | Data |
---|---|---|
7ad530bf EG |
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> | |
01544170 | 17 | #include <linux/kref.h> |
97a84843 | 18 | #include <linux/ktime.h> |
7ad530bf EG |
19 | #include <linux/list.h> |
20 | #include <linux/spinlock.h> | |
0f0d8406 | 21 | #include <linux/fence.h> |
7ad530bf | 22 | |
64907b94 CC |
23 | #include "uapi/sync.h" |
24 | ||
7ad530bf | 25 | struct sync_timeline; |
d7fdb0ae | 26 | struct sync_file; |
7ad530bf EG |
27 | |
28 | /** | |
29 | * struct sync_timeline_ops - sync object implementation ops | |
4e20effa | 30 | * @driver_name: name of the implementation |
7ad530bf EG |
31 | * @has_signaled: returns: |
32 | * 1 if pt has signaled | |
33 | * 0 if pt has not signaled | |
34 | * <0 on error | |
dbd52390 | 35 | * @timeline_value_str: fill str with the value of the sync_timeline's counter |
b55b54b5 | 36 | * @fence_value_str: fill str with the value of the fence |
7ad530bf EG |
37 | */ |
38 | struct sync_timeline_ops { | |
39 | const char *driver_name; | |
40 | ||
7ad530bf | 41 | /* required */ |
b55b54b5 | 42 | int (*has_signaled)(struct fence *fence); |
7ad530bf | 43 | |
dbd52390 EG |
44 | /* optional */ |
45 | void (*timeline_value_str)(struct sync_timeline *timeline, char *str, | |
46 | int size); | |
47 | ||
48 | /* optional */ | |
b55b54b5 | 49 | void (*fence_value_str)(struct fence *fence, char *str, int size); |
7ad530bf EG |
50 | }; |
51 | ||
52 | /** | |
53 | * struct sync_timeline - sync object | |
c5b86b74 | 54 | * @kref: reference count on fence. |
4e20effa | 55 | * @ops: ops that define the implementation of the sync_timeline |
7ad530bf | 56 | * @name: name of the sync_timeline. Useful for debugging |
4e20effa | 57 | * @destroyed: set when sync_timeline is destroyed |
7ad530bf EG |
58 | * @child_list_head: list of children sync_pts for this sync_timeline |
59 | * @child_list_lock: lock protecting @child_list_head, destroyed, and | |
b55b54b5 | 60 | * fence.status |
7ad530bf | 61 | * @active_list_head: list of active (unsignaled/errored) sync_pts |
af7582f2 | 62 | * @sync_timeline_list: membership in global sync_timeline_list |
7ad530bf EG |
63 | */ |
64 | struct sync_timeline { | |
c5b86b74 | 65 | struct kref kref; |
7ad530bf EG |
66 | const struct sync_timeline_ops *ops; |
67 | char name[32]; | |
68 | ||
69 | /* protected by child_list_lock */ | |
70 | bool destroyed; | |
0f0d8406 | 71 | int context, value; |
7ad530bf EG |
72 | |
73 | struct list_head child_list_head; | |
74 | spinlock_t child_list_lock; | |
75 | ||
76 | struct list_head active_list_head; | |
af7582f2 | 77 | |
0f0d8406 | 78 | #ifdef CONFIG_DEBUG_FS |
af7582f2 | 79 | struct list_head sync_timeline_list; |
0f0d8406 | 80 | #endif |
7ad530bf EG |
81 | }; |
82 | ||
b55b54b5 | 83 | static inline struct sync_timeline *fence_parent(struct fence *fence) |
0f0d8406 | 84 | { |
b55b54b5 | 85 | return container_of(fence->lock, struct sync_timeline, |
0f0d8406 ML |
86 | child_list_lock); |
87 | } | |
97a84843 | 88 | |
d7fdb0ae | 89 | struct sync_file_cb { |
0f0d8406 | 90 | struct fence_cb cb; |
c88b26dd | 91 | struct fence *fence; |
d7fdb0ae | 92 | struct sync_file *sync_file; |
7ad530bf EG |
93 | }; |
94 | ||
95 | /** | |
d7fdb0ae | 96 | * struct sync_file - sync file to export to the userspace |
7ad530bf | 97 | * @file: file representing this fence |
4e20effa | 98 | * @kref: reference count on fence. |
d7fdb0ae GP |
99 | * @name: name of sync_file. Useful for debugging |
100 | * @sync_file_list: membership in global file list | |
9b32381c GP |
101 | * @num_fences number of sync_pts in the fence |
102 | * @wq: wait queue for fence signaling | |
103 | * @status: 0: signaled, >0:active, <0: error | |
104 | * @cbs: sync_pts callback information | |
7ad530bf | 105 | */ |
d7fdb0ae | 106 | struct sync_file { |
7ad530bf | 107 | struct file *file; |
01544170 | 108 | struct kref kref; |
7ad530bf | 109 | char name[32]; |
0f0d8406 | 110 | #ifdef CONFIG_DEBUG_FS |
d7fdb0ae | 111 | struct list_head sync_file_list; |
0f0d8406 ML |
112 | #endif |
113 | int num_fences; | |
7ad530bf EG |
114 | |
115 | wait_queue_head_t wq; | |
0f0d8406 | 116 | atomic_t status; |
af7582f2 | 117 | |
d7fdb0ae | 118 | struct sync_file_cb cbs[]; |
7ad530bf EG |
119 | }; |
120 | ||
7ad530bf EG |
121 | /* |
122 | * API for sync_timeline implementers | |
123 | */ | |
124 | ||
125 | /** | |
126 | * sync_timeline_create() - creates a sync object | |
4e20effa | 127 | * @ops: specifies the implementation ops for the object |
7ad530bf EG |
128 | * @size: size to allocate for this obj |
129 | * @name: sync_timeline name | |
130 | * | |
4e20effa MI |
131 | * Creates a new sync_timeline which will use the implementation specified by |
132 | * @ops. @size bytes will be allocated allowing for implementation specific | |
9b32381c GP |
133 | * data to be kept after the generic sync_timeline struct. Returns the |
134 | * sync_timeline object or NULL in case of error. | |
7ad530bf EG |
135 | */ |
136 | struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, | |
137 | int size, const char *name); | |
138 | ||
139 | /** | |
4e20effa | 140 | * sync_timeline_destroy() - destroys a sync object |
7ad530bf EG |
141 | * @obj: sync_timeline to destroy |
142 | * | |
4e20effa MI |
143 | * A sync implementation should call this when the @obj is going away |
144 | * (i.e. module unload.) @obj won't actually be freed until all its children | |
b55b54b5 | 145 | * fences are freed. |
7ad530bf EG |
146 | */ |
147 | void sync_timeline_destroy(struct sync_timeline *obj); | |
148 | ||
149 | /** | |
150 | * sync_timeline_signal() - signal a status change on a sync_timeline | |
151 | * @obj: sync_timeline to signal | |
152 | * | |
b55b54b5 | 153 | * A sync implementation should call this any time one of it's fences |
7ad530bf EG |
154 | * has signaled or has an error condition. |
155 | */ | |
156 | void sync_timeline_signal(struct sync_timeline *obj); | |
157 | ||
158 | /** | |
159 | * sync_pt_create() - creates a sync pt | |
b55b54b5 | 160 | * @parent: fence's parent sync_timeline |
7ad530bf EG |
161 | * @size: size to allocate for this pt |
162 | * | |
b55b54b5 | 163 | * Creates a new fence as a child of @parent. @size bytes will be |
4e20effa | 164 | * allocated allowing for implementation specific data to be kept after |
b55b54b5 | 165 | * the generic sync_timeline struct. Returns the fence object or |
9b32381c | 166 | * NULL in case of error. |
7ad530bf | 167 | */ |
b55b54b5 | 168 | struct fence *sync_pt_create(struct sync_timeline *parent, int size); |
7ad530bf EG |
169 | |
170 | /** | |
b55b54b5 GP |
171 | * sync_fence_create() - creates a sync fence |
172 | * @name: name of fence to create | |
173 | * @fence: fence to add to the sync_fence | |
7ad530bf | 174 | * |
b55b54b5 GP |
175 | * Creates a sync_file containg @fence. Once this is called, the sync_file |
176 | * takes ownership of @fence. | |
7ad530bf | 177 | */ |
b55b54b5 | 178 | struct sync_file *sync_file_create(const char *name, struct fence *fence); |
7ad530bf EG |
179 | |
180 | /* | |
d7fdb0ae | 181 | * API for sync_file consumers |
7ad530bf EG |
182 | */ |
183 | ||
184 | /** | |
d7fdb0ae | 185 | * sync_file_merge() - merge two sync_files |
7ad530bf | 186 | * @name: name of new fence |
d7fdb0ae GP |
187 | * @a: sync_file a |
188 | * @b: sync_file b | |
7ad530bf | 189 | * |
b55b54b5 | 190 | * Creates a new sync_file which contains copies of all the fences in both |
d7fdb0ae GP |
191 | * @a and @b. @a and @b remain valid, independent sync_file. Returns the |
192 | * new merged sync_file or NULL in case of error. | |
7ad530bf | 193 | */ |
d7fdb0ae GP |
194 | struct sync_file *sync_file_merge(const char *name, |
195 | struct sync_file *a, struct sync_file *b); | |
7ad530bf EG |
196 | |
197 | /** | |
d7fdb0ae | 198 | * sync_file_fdget() - get a sync_file from an fd |
7ad530bf EG |
199 | * @fd: fd referencing a fence |
200 | * | |
d7fdb0ae GP |
201 | * Ensures @fd references a valid sync_file, increments the refcount of the |
202 | * backing file. Returns the sync_file or NULL in case of error. | |
7ad530bf | 203 | */ |
d7fdb0ae | 204 | struct sync_file *sync_file_fdget(int fd); |
7ad530bf EG |
205 | |
206 | /** | |
d7fdb0ae GP |
207 | * sync_file_put() - puts a reference of a sync_file |
208 | * @sync_file: sync_file to put | |
7ad530bf | 209 | * |
d7fdb0ae GP |
210 | * Puts a reference on @sync_fence. If this is the last reference, the |
211 | * sync_fil and all it's sync_pts will be freed | |
7ad530bf | 212 | */ |
d7fdb0ae | 213 | void sync_file_put(struct sync_file *sync_file); |
7ad530bf EG |
214 | |
215 | /** | |
d7fdb0ae GP |
216 | * sync_file_install() - installs a sync_file into a file descriptor |
217 | * @sync_file: sync_file to install | |
7ad530bf EG |
218 | * @fd: file descriptor in which to install the fence |
219 | * | |
d7fdb0ae | 220 | * Installs @sync_file into @fd. @fd's should be acquired through |
ae664752 | 221 | * get_unused_fd_flags(O_CLOEXEC). |
7ad530bf | 222 | */ |
d7fdb0ae | 223 | void sync_file_install(struct sync_file *sync_file, int fd); |
7ad530bf | 224 | |
0f0d8406 ML |
225 | #ifdef CONFIG_DEBUG_FS |
226 | ||
d30649a8 JP |
227 | void sync_timeline_debug_add(struct sync_timeline *obj); |
228 | void sync_timeline_debug_remove(struct sync_timeline *obj); | |
d7fdb0ae GP |
229 | void sync_file_debug_add(struct sync_file *fence); |
230 | void sync_file_debug_remove(struct sync_file *fence); | |
d30649a8 | 231 | void sync_dump(void); |
0f0d8406 ML |
232 | |
233 | #else | |
234 | # define sync_timeline_debug_add(obj) | |
235 | # define sync_timeline_debug_remove(obj) | |
d7fdb0ae GP |
236 | # define sync_file_debug_add(fence) |
237 | # define sync_file_debug_remove(fence) | |
0f0d8406 ML |
238 | # define sync_dump() |
239 | #endif | |
0f0d8406 | 240 | |
7ad530bf | 241 | #endif /* _LINUX_SYNC_H */ |