diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2016-08-05 09:39:38 -0400 |
---|---|---|
committer | Sumit Semwal <sumit.semwal@linaro.org> | 2016-08-11 06:09:38 -0400 |
commit | e24165537312723e2900831dd6e7415b8d85278c (patch) | |
tree | 50fdfc4cbedb2b92a1a96c79141d0605ad63bf6e | |
parent | 395dec6f6bc53277bc2b034c7a232ae0c51141b7 (diff) |
dma-buf/sync_file: only enable fence signalling on poll()
Signalling doesn't need to be enabled at sync_file creation, it is only
required if userspace waiting the fence to signal through poll().
Thus we delay fence_add_callback() until poll is called. It only adds the
callback the first time poll() is called. This avoid re-adding the same
callback multiple times.
v2: rebase and update to work with new fence support for sync_file
v3: use atomic operation to set enabled and protect fence_add_callback()
v4: use user bit from fence flags (comment from Chris Wilson)
v5: use ternary if on poll return (comment from Chris Wilson)
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
[sumits: remove unused var status]
Link: http://patchwork.freedesktop.org/patch/msgid/1470404378-27961-1-git-send-email-gustavo@padovan.org
-rw-r--r-- | drivers/dma-buf/sync_file.c | 21 | ||||
-rw-r--r-- | include/linux/sync_file.h | 2 |
2 files changed, 10 insertions, 13 deletions
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 2873760e02a9..486d29c1a830 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c | |||
@@ -86,8 +86,6 @@ struct sync_file *sync_file_create(struct fence *fence) | |||
86 | fence->ops->get_timeline_name(fence), fence->context, | 86 | fence->ops->get_timeline_name(fence), fence->context, |
87 | fence->seqno); | 87 | fence->seqno); |
88 | 88 | ||
89 | fence_add_callback(fence, &sync_file->cb, fence_check_cb_func); | ||
90 | |||
91 | return sync_file; | 89 | return sync_file; |
92 | } | 90 | } |
93 | EXPORT_SYMBOL(sync_file_create); | 91 | EXPORT_SYMBOL(sync_file_create); |
@@ -274,9 +272,6 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, | |||
274 | goto err; | 272 | goto err; |
275 | } | 273 | } |
276 | 274 | ||
277 | fence_add_callback(sync_file->fence, &sync_file->cb, | ||
278 | fence_check_cb_func); | ||
279 | |||
280 | strlcpy(sync_file->name, name, sizeof(sync_file->name)); | 275 | strlcpy(sync_file->name, name, sizeof(sync_file->name)); |
281 | return sync_file; | 276 | return sync_file; |
282 | 277 | ||
@@ -291,7 +286,8 @@ static void sync_file_free(struct kref *kref) | |||
291 | struct sync_file *sync_file = container_of(kref, struct sync_file, | 286 | struct sync_file *sync_file = container_of(kref, struct sync_file, |
292 | kref); | 287 | kref); |
293 | 288 | ||
294 | fence_remove_callback(sync_file->fence, &sync_file->cb); | 289 | if (test_bit(POLL_ENABLED, &sync_file->fence->flags)) |
290 | fence_remove_callback(sync_file->fence, &sync_file->cb); | ||
295 | fence_put(sync_file->fence); | 291 | fence_put(sync_file->fence); |
296 | kfree(sync_file); | 292 | kfree(sync_file); |
297 | } | 293 | } |
@@ -307,17 +303,16 @@ static int sync_file_release(struct inode *inode, struct file *file) | |||
307 | static unsigned int sync_file_poll(struct file *file, poll_table *wait) | 303 | static unsigned int sync_file_poll(struct file *file, poll_table *wait) |
308 | { | 304 | { |
309 | struct sync_file *sync_file = file->private_data; | 305 | struct sync_file *sync_file = file->private_data; |
310 | int status; | ||
311 | 306 | ||
312 | poll_wait(file, &sync_file->wq, wait); | 307 | poll_wait(file, &sync_file->wq, wait); |
313 | 308 | ||
314 | status = fence_is_signaled(sync_file->fence); | 309 | if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { |
310 | if (fence_add_callback(sync_file->fence, &sync_file->cb, | ||
311 | fence_check_cb_func) < 0) | ||
312 | wake_up_all(&sync_file->wq); | ||
313 | } | ||
315 | 314 | ||
316 | if (status) | 315 | return fence_is_signaled(sync_file->fence) ? POLLIN : 0; |
317 | return POLLIN; | ||
318 | if (status < 0) | ||
319 | return POLLERR; | ||
320 | return 0; | ||
321 | } | 316 | } |
322 | 317 | ||
323 | static long sync_file_ioctl_merge(struct sync_file *sync_file, | 318 | static long sync_file_ioctl_merge(struct sync_file *sync_file, |
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h index f7de5a0b3d12..aa17ccfc2f57 100644 --- a/include/linux/sync_file.h +++ b/include/linux/sync_file.h | |||
@@ -45,6 +45,8 @@ struct sync_file { | |||
45 | struct fence_cb cb; | 45 | struct fence_cb cb; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #define POLL_ENABLED FENCE_FLAG_USER_BITS | ||
49 | |||
48 | struct sync_file *sync_file_create(struct fence *fence); | 50 | struct sync_file *sync_file_create(struct fence *fence); |
49 | struct fence *sync_file_get_fence(int fd); | 51 | struct fence *sync_file_get_fence(int fd); |
50 | 52 | ||