Skip to content

Commit

Permalink
dma-buf/sync_file: Allow multiple sync_files to wrap a single dma-fence
Browse files Browse the repository at this point in the history
Up until recently sync_file were create to export a single dma-fence to
userspace, and so we could canabalise a bit insie dma-fence to mark
whether or not we had enable polling for the sync_file itself. However,
with the advent of syncobj, we do allow userspace to create multiple
sync_files for a single dma-fence. (Similarly, that the sw-sync
validation framework also started returning multiple sync-files wrapping
a single dma-fence for a syncpt also triggering the problem.)

This patch reverts my suggestion in commit e241655
("dma-buf/sync_file: only enable fence signalling on poll()") to use a
single bit in the shared dma-fence and restores the sync_file->flags for
tracking the bits individually.

Reported-by: Gustavo Padovan <[email protected]>
Fixes: f1e8c67 ("dma-buf/sw-sync: Use an rbtree to sort fences in the timeline")
Fixes: e908342 ("drm: introduce sync objects (v4)")
Signed-off-by: Chris Wilson <[email protected]>
Cc: Sumit Semwal <[email protected]>
Cc: Sean Paul <[email protected]>
Cc: Gustavo Padovan <[email protected]>
Cc: [email protected]
Cc: <[email protected]> # v4.13-rc1+
Signed-off-by: Gustavo Padovan <[email protected]>
Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
(cherry picked from commit db1fc97)
  • Loading branch information
ickle authored and padovan committed Jul 31, 2017
1 parent d630213 commit 99f8284
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 3 deletions.
5 changes: 3 additions & 2 deletions drivers/dma-buf/sync_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ static int sync_file_release(struct inode *inode, struct file *file)
{
struct sync_file *sync_file = file->private_data;

if (test_bit(POLL_ENABLED, &sync_file->fence->flags))
if (test_bit(POLL_ENABLED, &sync_file->flags))
dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
dma_fence_put(sync_file->fence);
kfree(sync_file);
Expand All @@ -318,7 +318,8 @@ static unsigned int sync_file_poll(struct file *file, poll_table *wait)

poll_wait(file, &sync_file->wq, wait);

if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) {
if (list_empty(&sync_file->cb.node) &&
!test_and_set_bit(POLL_ENABLED, &sync_file->flags)) {
if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
fence_check_cb_func) < 0)
wake_up_all(&sync_file->wq);
Expand Down
3 changes: 2 additions & 1 deletion include/linux/sync_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ struct sync_file {
#endif

wait_queue_head_t wq;
unsigned long flags;

struct dma_fence *fence;
struct dma_fence_cb cb;
};

#define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS
#define POLL_ENABLED 0

struct sync_file *sync_file_create(struct dma_fence *fence);
struct dma_fence *sync_file_get_fence(int fd);
Expand Down

0 comments on commit 99f8284

Please sign in to comment.