dma-fence: Wrap querying the fence->status
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 4 Jan 2017 14:12:21 +0000 (14:12 +0000)
committerSumit Semwal <sumit.semwal@linaro.org>
Mon, 9 Jan 2017 14:36:58 +0000 (20:06 +0530)
The fence->status is an optional field that is only valid once the fence
has been signaled. (Driver may fill the fence->status with an error code
prior to calling dma_fence_signal().) Given the restriction upon its
validity, wrap querying of the fence->status into a helper
dma_fence_get_status().

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-2-chris@chris-wilson.co.uk
drivers/dma-buf/dma-fence.c
drivers/dma-buf/sync_debug.c
drivers/dma-buf/sync_file.c
include/linux/dma-fence.h

index cb6eef3..5e66dfe 100644 (file)
@@ -282,6 +282,31 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,
 EXPORT_SYMBOL(dma_fence_add_callback);
 
 /**
+ * dma_fence_get_status - returns the status upon completion
+ * @fence: [in]        the dma_fence to query
+ *
+ * This wraps dma_fence_get_status_locked() to return the error status
+ * condition on a signaled fence. See dma_fence_get_status_locked() for more
+ * details.
+ *
+ * Returns 0 if the fence has not yet been signaled, 1 if the fence has
+ * been signaled without an error condition, or a negative error code
+ * if the fence has been completed in err.
+ */
+int dma_fence_get_status(struct dma_fence *fence)
+{
+       unsigned long flags;
+       int status;
+
+       spin_lock_irqsave(fence->lock, flags);
+       status = dma_fence_get_status_locked(fence);
+       spin_unlock_irqrestore(fence->lock, flags);
+
+       return status;
+}
+EXPORT_SYMBOL(dma_fence_get_status);
+
+/**
  * dma_fence_remove_callback - remove a callback from the signaling list
  * @fence:     [in]    the fence to wait on
  * @cb:                [in]    the callback to remove
index 48b20e3..c769dc6 100644 (file)
@@ -62,30 +62,29 @@ void sync_file_debug_remove(struct sync_file *sync_file)
 
 static const char *sync_status_str(int status)
 {
-       if (status == 0)
-               return "signaled";
+       if (status < 0)
+               return "error";
 
        if (status > 0)
-               return "active";
+               return "signaled";
 
-       return "error";
+       return "active";
 }
 
 static void sync_print_fence(struct seq_file *s,
                             struct dma_fence *fence, bool show)
 {
-       int status = 1;
        struct sync_timeline *parent = dma_fence_parent(fence);
+       int status;
 
-       if (dma_fence_is_signaled_locked(fence))
-               status = fence->status;
+       status = dma_fence_get_status_locked(fence);
 
        seq_printf(s, "  %s%sfence %s",
                   show ? parent->name : "",
                   show ? "_" : "",
                   sync_status_str(status));
 
-       if (status <= 0) {
+       if (status) {
                struct timespec64 ts64 =
                        ktime_to_timespec64(fence->timestamp);
 
@@ -136,7 +135,7 @@ static void sync_print_sync_file(struct seq_file *s,
        int i;
 
        seq_printf(s, "[%p] %s: %s\n", sync_file, sync_file->name,
-                  sync_status_str(!dma_fence_is_signaled(sync_file->fence)));
+                  sync_status_str(dma_fence_get_status(sync_file->fence)));
 
        if (dma_fence_is_array(sync_file->fence)) {
                struct dma_fence_array *array = to_dma_fence_array(sync_file->fence);
index 07cb9b9..2321035 100644 (file)
@@ -373,10 +373,8 @@ static void sync_fill_fence_info(struct dma_fence *fence,
                sizeof(info->obj_name));
        strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
                sizeof(info->driver_name));
-       if (dma_fence_is_signaled(fence))
-               info->status = fence->status >= 0 ? 1 : fence->status;
-       else
-               info->status = 0;
+
+       info->status = dma_fence_get_status(fence);
        info->timestamp_ns = ktime_to_ns(fence->timestamp);
 }
 
index d51a7d2..19f7af9 100644 (file)
@@ -378,6 +378,30 @@ static inline struct dma_fence *dma_fence_later(struct dma_fence *f1,
                return dma_fence_is_signaled(f2) ? NULL : f2;
 }
 
+/**
+ * dma_fence_get_status_locked - returns the status upon completion
+ * @fence: [in]        the dma_fence to query
+ *
+ * Drivers can supply an optional error status condition before they signal
+ * the fence (to indicate whether the fence was completed due to an error
+ * rather than success). The value of the status condition is only valid
+ * if the fence has been signaled, dma_fence_get_status_locked() first checks
+ * the signal state before reporting the error status.
+ *
+ * Returns 0 if the fence has not yet been signaled, 1 if the fence has
+ * been signaled without an error condition, or a negative error code
+ * if the fence has been completed in err.
+ */
+static inline int dma_fence_get_status_locked(struct dma_fence *fence)
+{
+       if (dma_fence_is_signaled_locked(fence))
+               return fence->status < 0 ? fence->status : 1;
+       else
+               return 0;
+}
+
+int dma_fence_get_status(struct dma_fence *fence);
+
 signed long dma_fence_wait_timeout(struct dma_fence *,
                                   bool intr, signed long timeout);
 signed long dma_fence_wait_any_timeout(struct dma_fence **fences,