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: Draft dma-fence-array.
details: https://anonhg.NetBSD.org/src/rev/043cf7d829ab
branches: trunk
changeset: 1028883:043cf7d829ab
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Dec 19 12:23:50 2021 +0000
description:
drm: Draft dma-fence-array.
diffstat:
sys/external/bsd/drm2/include/linux/dma-fence-array.h | 19 +-
sys/external/bsd/drm2/linux/linux_dma_fence_array.c | 149 +++++++++++++++++-
2 files changed, 160 insertions(+), 8 deletions(-)
diffs (215 lines):
diff -r 93e9b3e6e6d5 -r 043cf7d829ab sys/external/bsd/drm2/include/linux/dma-fence-array.h
--- a/sys/external/bsd/drm2/include/linux/dma-fence-array.h Sun Dec 19 12:23:42 2021 +0000
+++ b/sys/external/bsd/drm2/include/linux/dma-fence-array.h Sun Dec 19 12:23:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dma-fence-array.h,v 1.5 2021/12/19 12:01:40 riastradh Exp $ */
+/* $NetBSD: dma-fence-array.h,v 1.6 2021/12/19 12:23:50 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -35,15 +35,26 @@
#include <sys/stdbool.h>
#include <linux/dma-fence.h>
+#include <linux/irq_work.h>
#define dma_fence_array_create linux_dma_fence_array_create
#define dma_fence_is_array linux_dma_fence_is_array
#define to_dma_fence_array linux_to_dma_fence_array
+struct dma_fence_array_cb {
+ struct dma_fence_array *dfac_array;
+ struct dma_fence_cb dfac_cb;
+};
+
struct dma_fence_array {
- struct dma_fence base;
- struct dma_fence **fences;
- unsigned num_fences;
+ struct dma_fence base;
+ struct dma_fence **fences;
+ unsigned num_fences;
+
+ spinlock_t dfa_lock;
+ int dfa_npending;
+ struct irq_work dfa_work;
+ struct dma_fence_array_cb dfa_cb[];
};
struct dma_fence_array *
diff -r 93e9b3e6e6d5 -r 043cf7d829ab sys/external/bsd/drm2/linux/linux_dma_fence_array.c
--- a/sys/external/bsd/drm2/linux/linux_dma_fence_array.c Sun Dec 19 12:23:42 2021 +0000
+++ b/sys/external/bsd/drm2/linux/linux_dma_fence_array.c Sun Dec 19 12:23:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_dma_fence_array.c,v 1.1 2021/12/19 11:50:09 riastradh Exp $ */
+/* $NetBSD: linux_dma_fence_array.c,v 1.2 2021/12/19 12:23:50 riastradh Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -30,22 +30,163 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_dma_fence_array.c,v 1.1 2021/12/19 11:50:09 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_dma_fence_array.c,v 1.2 2021/12/19 12:23:50 riastradh Exp $");
#include <sys/systm.h>
#include <linux/dma-fence-array.h>
+static const char *
+dma_fence_array_driver_name(struct dma_fence *fence)
+{
+ return "dma-fence-array";
+}
+
+static const char *
+dma_fence_array_timeline_name(struct dma_fence *fence)
+{
+ return "dma-fence-array-timeline";
+}
+
+static void
+dma_fence_array_done1(struct dma_fence *fence, struct dma_fence_cb *cb)
+{
+ struct dma_fence_array_cb *C =
+ container_of(cb, struct dma_fence_array_cb, dfac_cb);
+ struct dma_fence_array *A = C->dfac_array;
+
+ KASSERT(spin_is_locked(&A->dfa_lock));
+
+ if (fence->error && A->base.error == 1) {
+ KASSERT(fence->error != 1);
+ A->base.error = fence->error;
+ }
+ if (--A->dfa_npending) {
+ dma_fence_put(&A->base);
+ return;
+ }
+
+ /* Last one out, hit the lights -- dma_fence_array_done. */
+ irq_work_queue(&A->dfa_work);
+}
+
+static void
+dma_fence_array_done(struct irq_work *W)
+{
+ struct dma_fence_array *A = container_of(W, struct dma_fence_array,
+ dfa_work);
+
+ spin_lock(&A->dfa_lock);
+ if (A->base.error == 1)
+ A->base.error = 0;
+ dma_fence_signal_locked(&A->base);
+ spin_unlock(&A->dfa_lock);
+
+ dma_fence_put(&A->base);
+}
+
+static bool
+dma_fence_array_enable_signaling(struct dma_fence *fence)
+{
+ struct dma_fence_array *A = to_dma_fence_array(fence);
+ struct dma_fence_array_cb *C;
+ unsigned i;
+ int error;
+
+ KASSERT(spin_is_locked(&A->dfa_lock));
+
+ for (i = 0; i < A->num_fences; i++) {
+ C = &A->dfa_cb[i];
+ C->dfac_array = A;
+ dma_fence_get(&A->base);
+ if (dma_fence_add_callback(A->fences[i], &C->dfac_cb,
+ dma_fence_array_done1)) {
+ error = A->fences[i]->error;
+ if (error) {
+ KASSERT(error != 1);
+ if (A->base.error == 1)
+ A->base.error = error;
+ }
+ dma_fence_put(&A->base);
+ if (--A->dfa_npending == 0) {
+ if (A->base.error == 1)
+ A->base.error = 0;
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool
+dma_fence_array_signaled(struct dma_fence *fence)
+{
+ struct dma_fence_array *A = to_dma_fence_array(fence);
+
+ KASSERT(spin_is_locked(&A->dfa_lock));
+
+ return A->dfa_npending == 0;
+}
+
+static void
+dma_fence_array_release(struct dma_fence *fence)
+{
+ struct dma_fence_array *A = to_dma_fence_array(fence);
+ unsigned i;
+
+ for (i = 0; i < A->num_fences; i++)
+ dma_fence_put(A->fences[i]);
+
+ kfree(A->fences);
+ dma_fence_free(fence);
+}
+
+static const struct dma_fence_ops dma_fence_array_ops = {
+ .get_driver_name = dma_fence_array_driver_name,
+ .get_timeline_name = dma_fence_array_timeline_name,
+ .enable_signaling = dma_fence_array_enable_signaling,
+ .signaled = dma_fence_array_signaled,
+ .release = dma_fence_array_release,
+};
+
+struct dma_fence_array *
+dma_fence_array_create(int num_fences, struct dma_fence **fences,
+ unsigned context, unsigned seqno, bool signal_on_any)
+{
+ struct dma_fence_array *A;
+
+ /*
+ * Must be allocated with kmalloc or equivalent because
+ * dma-fence will free it with kfree.
+ */
+ A = kzalloc(struct_size(A, dfa_cb, num_fences), GFP_KERNEL);
+ if (A == NULL)
+ return NULL;
+
+ A->fences = fences;
+ A->num_fences = num_fences;
+ A->dfa_npending = signal_on_any ? 1 : num_fences;
+
+ spin_lock_init(&A->dfa_lock);
+ dma_fence_init(&A->base, &dma_fence_array_ops, &A->dfa_lock,
+ context, seqno);
+ init_irq_work(&A->dfa_work, dma_fence_array_done);
+
+ return A;
+}
+
bool
dma_fence_is_array(struct dma_fence *fence)
{
- return false;
+ return fence->ops == &dma_fence_array_ops;
}
struct dma_fence_array *
to_dma_fence_array(struct dma_fence *fence)
{
- panic("NYI");
+ KASSERT(dma_fence_is_array(fence));
+ return container_of(fence, struct dma_fence_array, base);
}
Home |
Main Index |
Thread Index |
Old Index