aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo Padovan <gustavo.padovan@collabora.co.uk>2016-08-05 09:39:38 -0400
committerSumit Semwal <sumit.semwal@linaro.org>2016-08-11 06:09:38 -0400
commite24165537312723e2900831dd6e7415b8d85278c (patch)
tree50fdfc4cbedb2b92a1a96c79141d0605ad63bf6e
parent395dec6f6bc53277bc2b034c7a232ae0c51141b7 (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.c21
-rw-r--r--include/linux/sync_file.h2
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}
93EXPORT_SYMBOL(sync_file_create); 91EXPORT_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)
307static unsigned int sync_file_poll(struct file *file, poll_table *wait) 303static 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
323static long sync_file_ioctl_merge(struct sync_file *sync_file, 318static 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
48struct sync_file *sync_file_create(struct fence *fence); 50struct sync_file *sync_file_create(struct fence *fence);
49struct fence *sync_file_get_fence(int fd); 51struct fence *sync_file_get_fence(int fd);
50 52