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)