diff mbox series

dma-fance: Add dma_fence_assert_in_signalling_section

Message ID 20220225073351.3565619-1-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show
Series dma-fance: Add dma_fence_assert_in_signalling_section | expand

Commit Message

Daniel Vetter Feb. 25, 2022, 7:33 a.m. UTC
Useful for checking for dma-fence signalling annotations since they
don't quite nest as freely as we'd like to.

Cc: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: "Christian König" <christian.koenig@amd.com>
Cc: linux-media@vger.kernel.org
Cc: linaro-mm-sig@lists.linaro.org
---
 drivers/dma-buf/dma-fence.c | 19 +++++++++++++++++++
 include/linux/dma-fence.h   |  2 ++
 2 files changed, 21 insertions(+)

Comments

Christian König Feb. 25, 2022, 10:05 a.m. UTC | #1
Am 25.02.22 um 08:33 schrieb Daniel Vetter:
> Useful for checking for dma-fence signalling annotations since they
> don't quite nest as freely as we'd like to.
>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Gustavo Padovan <gustavo@padovan.org>
> Cc: "Christian König" <christian.koenig@amd.com>
> Cc: linux-media@vger.kernel.org
> Cc: linaro-mm-sig@lists.linaro.org
> ---
>   drivers/dma-buf/dma-fence.c | 19 +++++++++++++++++++
>   include/linux/dma-fence.h   |  2 ++
>   2 files changed, 21 insertions(+)
>
> diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
> index 066400ed8841..2b7c3fc965e6 100644
> --- a/drivers/dma-buf/dma-fence.c
> +++ b/drivers/dma-buf/dma-fence.c
> @@ -307,6 +307,25 @@ bool dma_fence_begin_signalling(void)
>   }
>   EXPORT_SYMBOL(dma_fence_begin_signalling);
>   
> +/**
> + * dma_fence_assert_in_signalling_section - check fence signalling annotations
> + *
> + * Since dma_fence_begin_signalling() and dma_fence_end_signalling() are built
> + * using lockdep annotations they have limitations on how freely they can be
> + * nested. Specifically, they cannot be on both inside and outside of locked
> + * sections, which in practice means the annotations often have to be pushed out
> + * to the top level callers.
> + *
> + * To ensure low-level functions are only called with the correction
> + * annotations, this function can be used to check for that.

I think I need a concrete example to understand what this is good for.

Christian.

> + */
> +void dma_fence_assert_in_signalling_section(void)
> +{
> +	if (!in_atomic())
> +		lockdep_assert(lock_is_held(&dma_fence_lockdep_map));
> +}
> +EXPORT_SYMBOL(dma_fence_assert_in_signalling_section);
> +
>   /**
>    * dma_fence_end_signalling - end a critical DMA fence signalling section
>    * @cookie: opaque cookie from dma_fence_begin_signalling()
> diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
> index 775cdc0b4f24..7179a5692f72 100644
> --- a/include/linux/dma-fence.h
> +++ b/include/linux/dma-fence.h
> @@ -356,6 +356,7 @@ dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep)
>   
>   #ifdef CONFIG_LOCKDEP
>   bool dma_fence_begin_signalling(void);
> +void dma_fence_assert_in_signalling_section(void);
>   void dma_fence_end_signalling(bool cookie);
>   void __dma_fence_might_wait(void);
>   #else
> @@ -363,6 +364,7 @@ static inline bool dma_fence_begin_signalling(void)
>   {
>   	return true;
>   }
> +static inline void dma_fence_assert_in_signalling_section(void) {}
>   static inline void dma_fence_end_signalling(bool cookie) {}
>   static inline void __dma_fence_might_wait(void) {}
>   #endif
diff mbox series

Patch

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 066400ed8841..2b7c3fc965e6 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -307,6 +307,25 @@  bool dma_fence_begin_signalling(void)
 }
 EXPORT_SYMBOL(dma_fence_begin_signalling);
 
+/**
+ * dma_fence_assert_in_signalling_section - check fence signalling annotations
+ *
+ * Since dma_fence_begin_signalling() and dma_fence_end_signalling() are built
+ * using lockdep annotations they have limitations on how freely they can be
+ * nested. Specifically, they cannot be on both inside and outside of locked
+ * sections, which in practice means the annotations often have to be pushed out
+ * to the top level callers.
+ *
+ * To ensure low-level functions are only called with the correction
+ * annotations, this function can be used to check for that.
+ */
+void dma_fence_assert_in_signalling_section(void)
+{
+	if (!in_atomic())
+		lockdep_assert(lock_is_held(&dma_fence_lockdep_map));
+}
+EXPORT_SYMBOL(dma_fence_assert_in_signalling_section);
+
 /**
  * dma_fence_end_signalling - end a critical DMA fence signalling section
  * @cookie: opaque cookie from dma_fence_begin_signalling()
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index 775cdc0b4f24..7179a5692f72 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -356,6 +356,7 @@  dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep)
 
 #ifdef CONFIG_LOCKDEP
 bool dma_fence_begin_signalling(void);
+void dma_fence_assert_in_signalling_section(void);
 void dma_fence_end_signalling(bool cookie);
 void __dma_fence_might_wait(void);
 #else
@@ -363,6 +364,7 @@  static inline bool dma_fence_begin_signalling(void)
 {
 	return true;
 }
+static inline void dma_fence_assert_in_signalling_section(void) {}
 static inline void dma_fence_end_signalling(bool cookie) {}
 static inline void __dma_fence_might_wait(void) {}
 #endif