From: Jérôme Glisse <jgli...@redhat.com>

The debugfs take reference on fence without dropping them. Also the
rcu section are not well balance. Fix all that ...

Changed since v1:
    - moved fobj logic around to be rcu safe

Signed-off-by: Jérôme Glisse <jgli...@redhat.com>
Cc: Christian König <christian.koe...@amd.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Sumit Semwal <sumit.sem...@linaro.org>
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Cc: Stéphane Marchesin <marc...@chromium.org>
Cc: sta...@vger.kernel.org
---
 drivers/dma-buf/dma-buf.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 13884474d158..9688d99894d6 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1048,27 +1048,38 @@ static int dma_buf_debug_show(struct seq_file *s, void 
*unused)
                while (true) {
                        seq = read_seqcount_begin(&robj->seq);
                        rcu_read_lock();
-                       fobj = rcu_dereference(robj->fence);
-                       shared_count = fobj ? fobj->shared_count : 0;
                        fence = rcu_dereference(robj->fence_excl);
+                       fence = dma_fence_get_rcu(fence);
                        if (!read_seqcount_retry(&robj->seq, seq))
                                break;
                        rcu_read_unlock();
                }
-
-               if (fence)
+               if (fence) {
                        seq_printf(s, "\tExclusive fence: %s %s %ssignalled\n",
                                   fence->ops->get_driver_name(fence),
                                   fence->ops->get_timeline_name(fence),
                                   dma_fence_is_signaled(fence) ? "" : "un");
-               for (i = 0; i < shared_count; i++) {
+                       dma_fence_put(fence);
+               }
+
+               rcu_read_lock();
+               fobj = rcu_dereference(robj->fence);
+               shared_count = fobj ? fobj->shared_count : 0;
+               for (i = 0, fence = NULL; i < shared_count; i++) {
                        fence = rcu_dereference(fobj->shared[i]);
                        if (!dma_fence_get_rcu(fence))
                                continue;
+                       rcu_read_unlock();
+
                        seq_printf(s, "\tShared fence: %s %s %ssignalled\n",
                                   fence->ops->get_driver_name(fence),
                                   fence->ops->get_timeline_name(fence),
                                   dma_fence_is_signaled(fence) ? "" : "un");
+                       dma_fence_put(fence);
+
+                       rcu_read_lock();
+                       fobj = rcu_dereference(robj->fence);
+                       shared_count = fobj ? fobj->shared_count : 0;
                }
                rcu_read_unlock();
 
-- 
2.17.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to