OSDN Git Service

freedreno: expose refcnt'ing on ringbuffers
authorRob Clark <robclark@freedesktop.org>
Tue, 9 Oct 2018 19:33:39 +0000 (15:33 -0400)
committerRob Clark <robclark@freedesktop.org>
Sat, 13 Oct 2018 21:18:43 +0000 (17:18 -0400)
Move this out of msm_ringbuffer backend so that the gallium driver can
refcnt rb's

Signed-off-by: Rob Clark <robclark@freedesktop.org>
freedreno/freedreno-symbol-check
freedreno/freedreno_ringbuffer.c
freedreno/freedreno_ringbuffer.h
freedreno/kgsl/kgsl_ringbuffer.c
freedreno/msm/msm_ringbuffer.c

index 6da9d66..002a398 100755 (executable)
@@ -49,6 +49,7 @@ fd_ringbuffer_flush
 fd_ringbuffer_grow
 fd_ringbuffer_new
 fd_ringbuffer_new_object
+fd_ringbuffer_ref
 fd_ringbuffer_reloc
 fd_ringbuffer_reloc2
 fd_ringbuffer_reset
index 1fa33b7..80af736 100644 (file)
@@ -71,11 +71,21 @@ fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size)
 
 drm_public void fd_ringbuffer_del(struct fd_ringbuffer *ring)
 {
-       if (!(ring->flags & FD_RINGBUFFER_OBJECT))
-               fd_ringbuffer_reset(ring);
+       if (!atomic_dec_and_test(&ring->refcnt))
+               return;
+
+       fd_ringbuffer_reset(ring);
        ring->funcs->destroy(ring);
 }
 
+drm_public struct fd_ringbuffer *
+fd_ringbuffer_ref(struct fd_ringbuffer *ring)
+{
+       STATIC_ASSERT(sizeof(ring->refcnt) <= sizeof(ring->__pad));
+       atomic_inc(&ring->refcnt);
+       return ring;
+}
+
 /* ringbuffers which are IB targets should set the toplevel rb (ie.
  * the IB source) as it's parent before emitting reloc's, to ensure
  * the bookkeeping works out properly.
index 69e7ed9..b2e8024 100644 (file)
@@ -53,6 +53,19 @@ struct fd_ringbuffer {
        void *user;
 
        uint32_t flags;
+
+       /* This is a bit gross, but we can't use atomic_t in exported
+        * headers.  OTOH, we don't need the refcnt to be publicly
+        * visible.  The only reason that this struct is exported is
+        * because fd_ringbuffer_emit needs to be something that can
+        * be inlined for performance reasons.
+        */
+       union {
+#ifdef HAS_ATOMIC_OPS
+               atomic_t refcnt;
+#endif
+               uint64_t __pad;
+       };
 };
 
 struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe,
@@ -60,6 +73,7 @@ struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe,
 struct fd_ringbuffer * fd_ringbuffer_new_object(struct fd_pipe *pipe,
                uint32_t size);
 
+struct fd_ringbuffer *fd_ringbuffer_ref(struct fd_ringbuffer *ring);
 void fd_ringbuffer_del(struct fd_ringbuffer *ring);
 void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
                struct fd_ringbuffer *parent);
index e4fdf34..7361f7d 100644 (file)
@@ -216,6 +216,8 @@ drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
        }
 
        ring = &kgsl_ring->base;
+       atomic_set(&ring->refcnt, 1);
+
        ring->funcs = &funcs;
        ring->size = size;
 
index 5a08881..a102ca3 100644 (file)
@@ -29,6 +29,7 @@
 #include <assert.h>
 #include <inttypes.h>
 
+#include "xf86atomic.h"
 #include "freedreno_ringbuffer.h"
 #include "msm_priv.h"
 
@@ -50,8 +51,6 @@ struct msm_cmd {
 struct msm_ringbuffer {
        struct fd_ringbuffer base;
 
-       atomic_t refcnt;
-
        /* submit ioctl related tables:
         * Note that bos and cmds are tracked by the parent ringbuffer, since
         * that is global to the submit ioctl call.  The reloc's table is tracked
@@ -97,9 +96,6 @@ static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
        return (struct msm_ringbuffer *)x;
 }
 
-static void msm_ringbuffer_unref(struct fd_ringbuffer *ring);
-static void msm_ringbuffer_ref(struct fd_ringbuffer *ring);
-
 #define INIT_SIZE 0x1000
 
 static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -454,7 +450,7 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
                if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) {
                        /* we could have dropped last reference: */
                        msm_ring->cmds[i] = NULL;
-                       msm_ringbuffer_unref(msm_cmd->ring);
+                       fd_ringbuffer_del(msm_cmd->ring);
                        free(U642VOID(cmd->relocs));
                }
        }
@@ -568,7 +564,7 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
         * destroyed after emitted but before flush, so we must hold a ref:
         */
        if (added_cmd && (target->flags & FD_RINGBUFFER_OBJECT)) {
-               msm_ringbuffer_ref(target);
+               fd_ringbuffer_ref(target);
        }
 
        return size;
@@ -579,13 +575,10 @@ static uint32_t msm_ringbuffer_cmd_count(struct fd_ringbuffer *ring)
        return to_msm_ringbuffer(ring)->cmd_count;
 }
 
-static void msm_ringbuffer_unref(struct fd_ringbuffer *ring)
+static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring)
 {
        struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
 
-       if (!atomic_dec_and_test(&msm_ring->refcnt))
-               return;
-
        flush_reset(ring);
        delete_cmds(msm_ring);
 
@@ -596,12 +589,6 @@ static void msm_ringbuffer_unref(struct fd_ringbuffer *ring)
        free(msm_ring);
 }
 
-static void msm_ringbuffer_ref(struct fd_ringbuffer *ring)
-{
-       struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
-       atomic_inc(&msm_ring->refcnt);
-}
-
 static const struct fd_ringbuffer_funcs funcs = {
                .hostptr = msm_ringbuffer_hostptr,
                .flush = msm_ringbuffer_flush,
@@ -610,7 +597,7 @@ static const struct fd_ringbuffer_funcs funcs = {
                .emit_reloc = msm_ringbuffer_emit_reloc,
                .emit_reloc_ring = msm_ringbuffer_emit_reloc_ring,
                .cmd_count = msm_ringbuffer_cmd_count,
-               .destroy = msm_ringbuffer_unref,
+               .destroy = msm_ringbuffer_destroy,
 };
 
 drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
@@ -633,9 +620,10 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
 
        list_inithead(&msm_ring->cmd_list);
        msm_ring->seqno = ++to_msm_device(pipe->dev)->ring_cnt;
-       atomic_set(&msm_ring->refcnt, 1);
 
        ring = &msm_ring->base;
+       atomic_set(&ring->refcnt, 1);
+
        ring->funcs = &funcs;
        ring->size = size;
        ring->pipe = pipe;   /* needed in ring_cmd_new() */