Module Name: src
Committed By: riastradh
Date: Sun Dec 19 12:39:25 UTC 2021
Modified Files:
src/sys/external/bsd/drm2/include/linux: dma-fence.h
src/sys/external/bsd/drm2/linux: linux_dma_fence.c
Log Message:
drm: Support 64-bit fence context and sequence numbers.
To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 \
src/sys/external/bsd/drm2/include/linux/dma-fence.h
cvs rdiff -u -r1.37 -r1.38 src/sys/external/bsd/drm2/linux/linux_dma_fence.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/external/bsd/drm2/include/linux/dma-fence.h
diff -u src/sys/external/bsd/drm2/include/linux/dma-fence.h:1.15 src/sys/external/bsd/drm2/include/linux/dma-fence.h:1.16
--- src/sys/external/bsd/drm2/include/linux/dma-fence.h:1.15 Sun Dec 19 12:10:51 2021
+++ src/sys/external/bsd/drm2/include/linux/dma-fence.h Sun Dec 19 12:39:24 2021
@@ -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 dma_fence {
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 @@ struct dma_fence {
#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 @@ struct dma_fence_cb {
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 @@ struct dma_fence_cb {
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 @@ DMA_FENCE_TRACE(struct dma_fence *f, con
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);
}
Index: src/sys/external/bsd/drm2/linux/linux_dma_fence.c
diff -u src/sys/external/bsd/drm2/linux/linux_dma_fence.c:1.37 src/sys/external/bsd/drm2/linux/linux_dma_fence.c:1.38
--- src/sys/external/bsd/drm2/linux/linux_dma_fence.c:1.37 Sun Dec 19 12:38:33 2021
+++ src/sys/external/bsd/drm2/linux/linux_dma_fence.c Sun Dec 19 12:39:25 2021
@@ -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 @@ dma_fence_referenced_p(struct dma_fence
*/
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 @@ dma_fence_init(struct dma_fence *fence,
*/
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 @@ dma_fence_free(struct dma_fence *fence)
* 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;
- return atomic_add_int_nv(&next_context, n) - n;
+ 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;
+}
+
+/*
+ * __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 @@ dma_fence_context_alloc(unsigned n)
* 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 @@ dma_fence_is_later(struct dma_fence *a,
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)