[PATCH 2/4] sync_file: add replace and export some functionality (v2)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dave Airlie <airlied@xxxxxxxxxx>

Using sync_file to back vulkan semaphores means need to replace
the fence underlying the sync file. This replace function removes
the callback, swaps the fence, and returns the old one. This
also exports the alloc and fdget functionality for the semaphore
wrapper code.

v2: use rcu.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 drivers/dma-buf/sync_file.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 include/linux/sync_file.h   |  5 ++++-
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 8b34f21..9fcc0a4 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -32,7 +32,14 @@ static const struct file_operations sync_file_fops;
 #define sync_file_assert_held(obj) \
 	lockdep_assert_held(&(obj)->lock)
 
-static struct sync_file *sync_file_alloc(void)
+/**
+ * sync_file_alloc() - allocate an unfenced sync file
+ *
+ * Creates a sync_file.
+ * The sync_file can be released with fput(sync_file->file).
+ * Returns the sync_file or NULL in case of error.
+ */
+struct sync_file *sync_file_alloc(void)
 {
 	struct sync_file *sync_file;
 
@@ -60,6 +67,7 @@ static struct sync_file *sync_file_alloc(void)
 	kfree(sync_file);
 	return NULL;
 }
+EXPORT_SYMBOL(sync_file_alloc);
 
 static void fence_check_cb_func(struct dma_fence *f, struct dma_fence_cb *cb)
 {
@@ -100,7 +108,7 @@ struct sync_file *sync_file_create(struct dma_fence *fence)
 }
 EXPORT_SYMBOL(sync_file_create);
 
-static struct sync_file *sync_file_fdget(int fd)
+struct sync_file *sync_file_fdget(int fd)
 {
 	struct file *file = fget(fd);
 
@@ -116,6 +124,7 @@ static struct sync_file *sync_file_fdget(int fd)
 	fput(file);
 	return NULL;
 }
+EXPORT_SYMBOL(sync_file_fdget);
 
 /**
  * sync_file_get_fence - get the fence related to the sync_file fd
@@ -153,6 +162,35 @@ sync_file_get_fence_locked(struct sync_file *sync_file)
 					 sync_file_held(sync_file));
 }
 
+/**
+ * sync_file_replace_fence - replace the fence related to the sync_file
+ * @sync_file:	 sync file to replace fence in
+ * @fence: fence to replace with (or NULL for no fence).
+ * Returns previous fence.
+ */
+struct dma_fence *sync_file_replace_fence(struct sync_file *sync_file,
+					  struct dma_fence *fence)
+{
+	struct dma_fence *ret_fence = NULL;
+
+	if (fence)
+		dma_fence_get(fence);
+
+	mutex_lock(&sync_file->lock);
+
+	ret_fence = sync_file_get_fence_locked(sync_file);
+	if (ret_fence) {
+		if (test_bit(POLL_ENABLED, &ret_fence->flags))
+			dma_fence_remove_callback(ret_fence, &sync_file->cb);
+	}
+
+	RCU_INIT_POINTER(sync_file->fence, fence);
+
+	mutex_unlock(&sync_file->lock);
+	return ret_fence;
+}
+EXPORT_SYMBOL(sync_file_replace_fence);
+
 static int sync_file_set_fence(struct sync_file *sync_file,
 			       struct dma_fence **fences, int num_fences)
 {
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
index 006412f..555ae99 100644
--- a/include/linux/sync_file.h
+++ b/include/linux/sync_file.h
@@ -50,7 +50,10 @@ struct sync_file {
 
 #define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS
 
+struct sync_file *sync_file_alloc(void);
 struct sync_file *sync_file_create(struct dma_fence *fence);
 struct dma_fence *sync_file_get_fence(int fd);
-
+struct sync_file *sync_file_fdget(int fd);
+struct dma_fence *sync_file_replace_fence(struct sync_file *sync_file,
+					  struct dma_fence *fence);
 #endif /* _LINUX_SYNC_H */
-- 
2.7.4



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux