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