Source-Changes-HG archive

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

[src/trunk]: src/sys/external/bsd/drm2/linux drm: Support 64-bit fence contex...



details:   https://anonhg.NetBSD.org/src/rev/9af1346b68ed
branches:  trunk
changeset: 1028989:9af1346b68ed
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Dec 19 12:39:24 2021 +0000

description:
drm: Support 64-bit fence context and sequence numbers.

diffstat:

 sys/external/bsd/drm2/include/linux/dma-fence.h |  17 ++++---
 sys/external/bsd/drm2/linux/linux_dma_fence.c   |  57 ++++++++++++++++++++----
 2 files changed, 57 insertions(+), 17 deletions(-)

diffs (177 lines):

diff -r c614047016e1 -r 9af1346b68ed sys/external/bsd/drm2/include/linux/dma-fence.h
--- a/sys/external/bsd/drm2/include/linux/dma-fence.h   Sun Dec 19 12:39:16 2021 +0000
+++ b/sys/external/bsd/drm2/include/linux/dma-fence.h   Sun Dec 19 12:39:24 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dma-fence.h,v 1.15 2021/12/19 12:10:51 riastradh Exp $ */
+/*     $NetBSD: dma-fence.h,v 1.16 2021/12/19 12:39:24 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -50,8 +50,8 @@
        struct kref                     refcount;
        spinlock_t                      *lock;
        volatile unsigned long          flags;
-       unsigned                        context;
-       unsigned                        seqno;
+       uint64_t                        context;
+       uint64_t                        seqno;
        const struct dma_fence_ops      *ops;
        int                             error;
        ktime_t                         timestamp;
@@ -68,6 +68,7 @@
 #define        DMA_FENCE_FLAG_USER_BITS                3
 
 struct dma_fence_ops {
+       bool            use_64bit_seqno;
        const char      *(*get_driver_name)(struct dma_fence *);
        const char      *(*get_timeline_name)(struct dma_fence *);
        bool            (*enable_signaling)(struct dma_fence *);
@@ -84,6 +85,7 @@
        bool                            fcb_onqueue;
 };
 
+#define        __dma_fence_is_later            linux___dma_fence_is_later
 #define        __dma_fence_signal              linux___dma_fence_signal
 #define        __dma_fence_signal_wake         linux___dma_fence_signal_wake
 #define        dma_fence_add_callback          linux_dma_fence_add_callback
@@ -114,14 +116,15 @@
 extern int     linux_dma_fence_trace;
 
 void   dma_fence_init(struct dma_fence *, const struct dma_fence_ops *,
-           spinlock_t *, unsigned, unsigned);
+           spinlock_t *, uint64_t, uint64_t);
 void   dma_fence_reset(struct dma_fence *, const struct dma_fence_ops *,
-           spinlock_t *, unsigned, unsigned); /* XXX extension */
+           spinlock_t *, uint64_t, uint64_t); /* XXX extension */
 void   dma_fence_destroy(struct dma_fence *);
 void   dma_fence_free(struct dma_fence *);
 
-unsigned
+uint64_t
        dma_fence_context_alloc(unsigned);
+bool   __dma_fence_is_later(uint64_t, uint64_t, const struct dma_fence_ops *);
 bool   dma_fence_is_later(struct dma_fence *, struct dma_fence *);
 
 struct dma_fence *
@@ -163,7 +166,7 @@
 
        if (__predict_false(linux_dma_fence_trace)) {
                va_start(va, fmt);
-               printf("fence %u@%u: ", f->context, f->seqno);
+               printf("fence %"PRIu64"@%"PRIu64": ", f->context, f->seqno);
                vprintf(fmt, va);
                va_end(va);
        }
diff -r c614047016e1 -r 9af1346b68ed sys/external/bsd/drm2/linux/linux_dma_fence.c
--- a/sys/external/bsd/drm2/linux/linux_dma_fence.c     Sun Dec 19 12:39:16 2021 +0000
+++ b/sys/external/bsd/drm2/linux/linux_dma_fence.c     Sun Dec 19 12:39:24 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_dma_fence.c,v 1.37 2021/12/19 12:38:33 riastradh Exp $   */
+/*     $NetBSD: linux_dma_fence.c,v 1.38 2021/12/19 12:39:25 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,10 +30,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_dma_fence.c,v 1.37 2021/12/19 12:38:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_dma_fence.c,v 1.38 2021/12/19 12:39:25 riastradh Exp $");
 
 #include <sys/atomic.h>
 #include <sys/condvar.h>
+#include <sys/lock.h>
 #include <sys/queue.h>
 #include <sys/sdt.h>
 
@@ -120,7 +121,7 @@
  */
 void
 dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
-    spinlock_t *lock, unsigned context, unsigned seqno)
+    spinlock_t *lock, uint64_t context, uint64_t seqno)
 {
 
        kref_init(&fence->refcount);
@@ -151,7 +152,7 @@
  */
 void
 dma_fence_reset(struct dma_fence *fence, const struct dma_fence_ops *ops,
-    spinlock_t *lock, unsigned context, unsigned seqno)
+    spinlock_t *lock, uint64_t context, uint64_t seqno)
 {
 
        KASSERTMSG(fence->f_magic != FENCE_MAGIC_BAD, "fence %p", fence);
@@ -235,12 +236,46 @@
  *     Return the first of a contiguous sequence of unique
  *     identifiers, at least until the system wraps around.
  */
-unsigned
+uint64_t
 dma_fence_context_alloc(unsigned n)
 {
-       static volatile unsigned next_context = 0;
+       static struct {
+               volatile unsigned lock;
+               uint64_t context;
+       } S;
+       uint64_t c;
+
+       while (__predict_false(atomic_cas_uint(&S.lock, 0, 1) != 0))
+               SPINLOCK_BACKOFF_HOOK;
+       membar_enter();
+       c = S.context;
+       S.context += n;
+       atomic_store_release(&S.lock, 0);
+
+       return c;
+}
 
-       return atomic_add_int_nv(&next_context, n) - n;
+/*
+ * __dma_fence_is_later(a, b, ops)
+ *
+ *     True if sequence number a is later than sequence number b,
+ *     according to the given fence ops.
+ *
+ *     - For fence ops with 64-bit sequence numbers, this is simply
+ *       defined to be a > b as unsigned 64-bit integers.
+ *
+ *     - For fence ops with 32-bit sequence numbers, this is defined
+ *       to mean that the 32-bit unsigned difference a - b is less
+ *       than INT_MAX.
+ */
+bool
+__dma_fence_is_later(uint64_t a, uint64_t b, const struct dma_fence_ops *ops)
+{
+
+       if (ops->use_64bit_seqno)
+               return a > b;
+       else
+               return (unsigned)a - (unsigned)b < INT_MAX;
 }
 
 /*
@@ -252,7 +287,8 @@
  *     fence a is no more than INT_MAX past the sequence number of
  *     fence b.
  *
- *     The two fences must have the same context.
+ *     The two fences must have the context.  Whether sequence numbers
+ *     are 32-bit is determined by a.
  */
 bool
 dma_fence_is_later(struct dma_fence *a, struct dma_fence *b)
@@ -263,9 +299,10 @@
        KASSERTMSG(b->f_magic != FENCE_MAGIC_BAD, "fence %p", b);
        KASSERTMSG(b->f_magic == FENCE_MAGIC_GOOD, "fence %p", b);
        KASSERTMSG(a->context == b->context, "incommensurate fences"
-           ": %u @ %p =/= %u @ %p", a->context, a, b->context, b);
+           ": %"PRIu64" @ %p =/= %"PRIu64" @ %p",
+           a->context, a, b->context, b);
 
-       return a->seqno - b->seqno < INT_MAX;
+       return __dma_fence_is_later(a->seqno, b->seqno, a->ops);
 }
 
 static const char *dma_fence_stub_name(struct dma_fence *f)



Home | Main Index | Thread Index | Old Index