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 Implement poll for reservations and dm...
details: https://anonhg.NetBSD.org/src/rev/acf7a7af8f0a
branches: trunk
changeset: 835484:acf7a7af8f0a
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Aug 27 15:25:13 2018 +0000
description:
Implement poll for reservations and dma bufs.
diffstat:
sys/external/bsd/drm2/include/linux/dma-buf.h | 4 +-
sys/external/bsd/drm2/include/linux/reservation.h | 25 +-
sys/external/bsd/drm2/linux/linux_dma_buf.c | 22 +-
sys/external/bsd/drm2/linux/linux_reservation.c | 269 +++++++++++++++++++++-
4 files changed, 300 insertions(+), 20 deletions(-)
diffs (truncated from 439 to 300 lines):
diff -r 3179122039da -r acf7a7af8f0a sys/external/bsd/drm2/include/linux/dma-buf.h
--- a/sys/external/bsd/drm2/include/linux/dma-buf.h Mon Aug 27 15:24:53 2018 +0000
+++ b/sys/external/bsd/drm2/include/linux/dma-buf.h Mon Aug 27 15:25:13 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dma-buf.h,v 1.3 2018/08/27 15:22:54 riastradh Exp $ */
+/* $NetBSD: dma-buf.h,v 1.4 2018/08/27 15:25:13 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -88,7 +88,7 @@
kmutex_t db_lock;
volatile unsigned db_refcnt;
- struct selinfo db_selq;
+ struct reservation_poll db_resv_poll;
struct reservation_object db_resv_int[];
};
diff -r 3179122039da -r acf7a7af8f0a sys/external/bsd/drm2/include/linux/reservation.h
--- a/sys/external/bsd/drm2/include/linux/reservation.h Mon Aug 27 15:24:53 2018 +0000
+++ b/sys/external/bsd/drm2/include/linux/reservation.h Mon Aug 27 15:25:13 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: reservation.h,v 1.7 2018/08/27 14:01:14 riastradh Exp $ */
+/* $NetBSD: reservation.h,v 1.8 2018/08/27 15:25:13 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -32,11 +32,10 @@
#ifndef _LINUX_RESERVATION_H_
#define _LINUX_RESERVATION_H_
+#include <linux/fence.h>
#include <linux/rcupdate.h>
#include <linux/ww_mutex.h>
-struct fence;
-
struct reservation_object {
struct ww_mutex lock;
@@ -54,6 +53,14 @@
struct fence __rcu *shared[];
};
+/* NetBSD addition */
+struct reservation_poll {
+ kmutex_t rp_lock;
+ struct selinfo rp_selq;
+ struct fence_cb rp_fcb;
+ bool rp_claimed;
+};
+
#define reservation_object_add_excl_fence linux_reservation_object_add_excl_fence
#define reservation_object_add_shared_fence linux_reservation_object_add_shared_fence
#define reservation_object_fini linux_reservation_object_fini
@@ -62,9 +69,13 @@
#define reservation_object_get_list linux_reservation_object_get_list
#define reservation_object_held linux_reservation_object_held
#define reservation_object_init linux_reservation_object_init
+#define reservation_object_kqfilter linux_reservation_object_kqfilter
+#define reservation_object_poll linux_reservation_object_poll
#define reservation_object_reserve_shared linux_reservation_object_reserve_shared
#define reservation_object_test_signaled_rcu linux_reservation_object_test_signaled_rcu
#define reservation_object_wait_timeout_rcu linux_reservation_object_wait_timeout_rcu
+#define reservation_poll_fini linux_reservation_poll_fini
+#define reservation_poll_init linux_reservation_poll_init
#define reservation_ww_class linux_reservation_ww_class
extern struct ww_class reservation_ww_class;
@@ -90,4 +101,12 @@
long reservation_object_wait_timeout_rcu(struct reservation_object *,
bool, bool, unsigned long);
+/* NetBSD additions */
+void reservation_poll_init(struct reservation_poll *);
+void reservation_poll_fini(struct reservation_poll *);
+int reservation_object_poll(struct reservation_object *, int,
+ struct reservation_poll *);
+int reservation_object_kqfilter(struct reservation_object *,
+ struct knote *, struct reservation_poll *);
+
#endif /* _LINUX_RESERVATION_H_ */
diff -r 3179122039da -r acf7a7af8f0a sys/external/bsd/drm2/linux/linux_dma_buf.c
--- a/sys/external/bsd/drm2/linux/linux_dma_buf.c Mon Aug 27 15:24:53 2018 +0000
+++ b/sys/external/bsd/drm2/linux/linux_dma_buf.c Mon Aug 27 15:25:13 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_dma_buf.c,v 1.3 2018/08/27 15:24:40 riastradh Exp $ */
+/* $NetBSD: linux_dma_buf.c,v 1.4 2018/08/27 15:25:13 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.3 2018/08/27 15:24:40 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.4 2018/08/27 15:25:13 riastradh Exp $");
#include <sys/types.h>
#include <sys/atomic.h>
@@ -87,6 +87,7 @@
mutex_init(&dmabuf->db_lock, MUTEX_DEFAULT, IPL_NONE);
dmabuf->db_refcnt = 1;
+ reservation_poll_init(&dmabuf->db_resv_poll);
if (dmabuf->resv == NULL) {
dmabuf->resv = &dmabuf->db_resv_int[0];
@@ -167,6 +168,7 @@
if (atomic_dec_uint_nv(&dmabuf->db_refcnt) != 0)
return;
+ reservation_poll_fini(&dmabuf->db_resv_poll);
mutex_destroy(&dmabuf->db_lock);
if (dmabuf->resv == &dmabuf->db_resv_int[0]) {
reservation_object_fini(dmabuf->resv);
@@ -239,27 +241,21 @@
static int
dmabuf_fop_poll(struct file *file, int events)
{
-#ifdef notyet
struct dma_buf_file *dbf = file->f_data;
struct dma_buf *dmabuf = dbf->dbf_dmabuf;
+ struct reservation_poll *rpoll = &dmabuf->db_resv_poll;
- return reservation_object_poll(dmabuf->resv, events);
-#else
- return -ENOSYS;
-#endif
+ return reservation_object_poll(dmabuf->resv, events, rpoll);
}
static int
-dmabuf_fop_kqfilter(struct file *file, struct knote *knote)
+dmabuf_fop_kqfilter(struct file *file, struct knote *kn)
{
-#ifdef notyet
struct dma_buf_file *dbf = file->f_data;
struct dma_buf *dmabuf = dbf->dbf_dmabuf;
+ struct reservation_poll *rpoll = &dmabuf->db_resv_poll;
- return reservation_object_kqfilter(dmabuf->resv, knote);
-#else
- return -ENOSYS;
-#endif
+ return reservation_object_kqfilter(dmabuf->resv, kn, rpoll);
}
static int
diff -r 3179122039da -r acf7a7af8f0a sys/external/bsd/drm2/linux/linux_reservation.c
--- a/sys/external/bsd/drm2/linux/linux_reservation.c Mon Aug 27 15:24:53 2018 +0000
+++ b/sys/external/bsd/drm2/linux/linux_reservation.c Mon Aug 27 15:25:13 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_reservation.c,v 1.7 2018/08/27 14:14:13 riastradh Exp $ */
+/* $NetBSD: linux_reservation.c,v 1.8 2018/08/27 15:25:14 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,10 +30,15 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_reservation.c,v 1.7 2018/08/27 14:14:13 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_reservation.c,v 1.8 2018/08/27 15:25:14 riastradh Exp $");
+
+#include <sys/param.h>
+#include <sys/poll.h>
+#include <sys/select.h>
#include <linux/fence.h>
#include <linux/reservation.h>
+#include <linux/ww_mutex.h>
DEFINE_WW_CLASS(reservation_ww_class __cacheline_aligned);
@@ -792,3 +797,263 @@
return timeout;
goto top;
}
+
+/*
+ * reservation_poll_init(rpoll, lock)
+ *
+ * Initialize reservation poll state.
+ */
+void
+reservation_poll_init(struct reservation_poll *rpoll)
+{
+
+ mutex_init(&rpoll->rp_lock, MUTEX_DEFAULT, IPL_VM);
+ selinit(&rpoll->rp_selq);
+ rpoll->rp_claimed = 0;
+}
+
+/*
+ * reservation_poll_fini(rpoll)
+ *
+ * Release any resource associated with reservation poll state.
+ */
+void
+reservation_poll_fini(struct reservation_poll *rpoll)
+{
+
+ KASSERT(rpoll->rp_claimed == 0);
+ seldestroy(&rpoll->rp_selq);
+ mutex_destroy(&rpoll->rp_lock);
+}
+
+/*
+ * reservation_poll_cb(fence, fcb)
+ *
+ * Callback to notify a reservation poll that a fence has
+ * completed. Notify any waiters and allow the next poller to
+ * claim the callback.
+ *
+ * If one thread is waiting for the exclusive fence only, and we
+ * spuriously notify them about a shared fence, tough.
+ */
+static void
+reservation_poll_cb(struct fence *fence, struct fence_cb *fcb)
+{
+ struct reservation_poll *rpoll = container_of(fcb,
+ struct reservation_poll, rp_fcb);
+
+ mutex_enter(&rpoll->rp_lock);
+ selnotify(&rpoll->rp_selq, 0, NOTE_SUBMIT);
+ rpoll->rp_claimed = 0;
+ mutex_exit(&rpoll->rp_lock);
+}
+
+/*
+ * reservation_object_poll(robj, events, rpoll)
+ *
+ * POLLOUT wait for all fences shared and exclusive
+ * POLLIN wait for the exclusive fence
+ */
+int
+reservation_object_poll(struct reservation_object *robj, int events,
+ struct reservation_poll *rpoll)
+{
+ struct reservation_object_read_ticket ticket;
+ struct reservation_object_list *list;
+ struct fence *fence;
+ uint32_t i, shared_count;
+ int revents;
+ bool recorded = false; /* curlwp is on the selq */
+ bool claimed = false; /* we claimed the callback */
+ bool callback = false; /* we requested a callback */
+
+ /*
+ * Start with the maximal set of events that could be ready.
+ * We will eliminate the events that are definitely not ready
+ * as we go at the same time as we add callbacks to notify us
+ * that they may be ready.
+ */
+ revents = events & (POLLIN|POLLOUT);
+ if (revents == 0)
+ return 0;
+
+top:
+ /* Enter an RCU read section and get a read ticket. */
+ rcu_read_lock();
+ reservation_object_read_begin(robj, &ticket);
+
+ /* If we want to wait for all fences, get the shared list. */
+ if ((events & POLLOUT) && (list = robj->robj_list) != NULL) do {
+ /* Make sure the content of the list has been published. */
+ membar_datadep_consumer();
+
+ /* Find out how long it is. */
+ shared_count = list->shared_count;
+
+ /*
+ * Make sure we saw a consistent snapshot of the list
+ * pointer and length.
+ */
+ if (!reservation_object_read_valid(robj, &ticket))
+ goto restart;
+
+ /*
+ * For each fence, if it is going away, restart.
+ * Otherwise, acquire a reference to it to test whether
+ * it is signalled. Stop and request a callback if we
+ * find any that is not signalled.
+ */
+ for (i = 0; i < shared_count; i++) {
+ fence = fence_get_rcu(list->shared[i]);
+ if (fence == NULL)
+ goto restart;
+ if (!fence_is_signaled(fence)) {
+ fence_put(fence);
+ break;
+ }
+ fence_put(fence);
+ }
+
+ /* If all shared fences have been signalled, move on. */
+ if (i == shared_count)
+ break;
+
Home |
Main Index |
Thread Index |
Old Index