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