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 Draft sync_file.
details: https://anonhg.NetBSD.org/src/rev/1c61ff03b7f7
branches: trunk
changeset: 1028342:1c61ff03b7f7
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Dec 19 10:45:49 2021 +0000
description:
Draft sync_file.
diffstat:
sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c | 5 +-
sys/external/bsd/drm2/include/linux/sync_file.h | 18 +-
sys/external/bsd/drm2/linux/files.drmkms_linux | 3 +-
sys/external/bsd/drm2/linux/linux_sync_file.c | 233 +++++++++++++++++++++++
4 files changed, 254 insertions(+), 5 deletions(-)
diffs (truncated from 317 to 300 lines):
diff -r 695b6879f3e2 -r 1c61ff03b7f7 sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c
--- a/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c Sun Dec 19 10:45:33 2021 +0000
+++ b/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c Sun Dec 19 10:45:49 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_atomic_uapi.c,v 1.6 2021/12/19 01:58:41 riastradh Exp $ */
+/* $NetBSD: drm_atomic_uapi.c,v 1.7 2021/12/19 10:45:49 riastradh Exp $ */
/*
* Copyright (C) 2014 Red Hat
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_atomic_uapi.c,v 1.6 2021/12/19 01:58:41 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_atomic_uapi.c,v 1.7 2021/12/19 10:45:49 riastradh Exp $");
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic.h>
@@ -1114,6 +1114,7 @@
ret = -ENOMEM;
goto out;
}
+ fd_affix(curproc, fp, fd);
fp = NULL; /* sync_file consumes */
out: if (fp != NULL) {
diff -r 695b6879f3e2 -r 1c61ff03b7f7 sys/external/bsd/drm2/include/linux/sync_file.h
--- a/sys/external/bsd/drm2/include/linux/sync_file.h Sun Dec 19 10:45:33 2021 +0000
+++ b/sys/external/bsd/drm2/include/linux/sync_file.h Sun Dec 19 10:45:49 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sync_file.h,v 1.3 2021/12/19 00:58:42 riastradh Exp $ */
+/* $NetBSD: sync_file.h,v 1.4 2021/12/19 10:45:49 riastradh Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -32,12 +32,26 @@
#ifndef _LINUX_SYNC_FILE_H_
#define _LINUX_SYNC_FILE_H_
+#include <sys/mutex.h>
+#include <sys/select.h>
+
+#include <linux/dma-fence.h>
+
struct dma_fence;
struct file;
struct sync_file;
struct sync_file {
- struct file *file;
+ /* Linux API */
+ struct file *file;
+
+ /* Private */
+ struct dma_fence *sf_fence;
+ kmutex_t sf_lock;
+ struct selinfo sf_selq;
+ struct dma_fence_cb sf_fcb;
+ bool sf_polling;
+ bool sf_signalled;
};
struct sync_file *
diff -r 695b6879f3e2 -r 1c61ff03b7f7 sys/external/bsd/drm2/linux/files.drmkms_linux
--- a/sys/external/bsd/drm2/linux/files.drmkms_linux Sun Dec 19 10:45:33 2021 +0000
+++ b/sys/external/bsd/drm2/linux/files.drmkms_linux Sun Dec 19 10:45:49 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.drmkms_linux,v 1.24 2021/12/19 10:19:53 riastradh Exp $
+# $NetBSD: files.drmkms_linux,v 1.25 2021/12/19 10:45:50 riastradh Exp $
define drmkms_linux: i2cexec, i2c_bitbang
@@ -17,6 +17,7 @@
file external/bsd/drm2/linux/linux_module.c drmkms_linux
file external/bsd/drm2/linux/linux_pci.c drmkms_linux
file external/bsd/drm2/linux/linux_stop_machine.c drmkms_linux
+file external/bsd/drm2/linux/linux_sync_file.c drmkms_linux
file external/bsd/drm2/linux/linux_wait_bit.c drmkms_linux
file external/bsd/drm2/linux/linux_writecomb.c drmkms_linux
file external/bsd/drm2/linux/linux_ww_mutex.c drmkms_linux
diff -r 695b6879f3e2 -r 1c61ff03b7f7 sys/external/bsd/drm2/linux/linux_sync_file.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/linux/linux_sync_file.c Sun Dec 19 10:45:49 2021 +0000
@@ -0,0 +1,233 @@
+/* $NetBSD: linux_sync_file.c,v 1.1 2021/12/19 10:45:50 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux_sync_file.c,v 1.1 2021/12/19 10:45:50 riastradh Exp $");
+
+#include <sys/event.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/queue.h>
+
+#include <linux/dma-fence.h>
+#include <linux/sync_file.h>
+
+static const struct fileops sync_file_ops;
+
+struct sync_file *
+sync_file_create(struct dma_fence *fence, struct file *fp)
+{
+ struct sync_file *sf;
+
+ sf = kmem_zalloc(sizeof(*sf), KM_SLEEP);
+ sf->file = fp;
+ sf->sf_fence = dma_fence_get(fence);
+ mutex_init(&sf->sf_lock, MUTEX_DEFAULT, IPL_VM);
+ selinit(&sf->sf_selq);
+ sf->sf_polling = false;
+ sf->sf_signalled = false;
+
+ fp->f_type = DTYPE_MISC;
+ fp->f_flag = FREAD | FWRITE;
+ fp->f_ops = &sync_file_ops;
+
+ return sf;
+}
+
+static int
+sync_file_close(struct file *fp)
+{
+ struct sync_file *sf = fp->f_data;
+
+ if (sf->sf_polling)
+ dma_fence_remove_callback(sf->sf_fence, &sf->sf_fcb);
+ dma_fence_put(sf->sf_fence);
+ sf->sf_fence = NULL;
+
+ kmem_free(sf, sizeof(*sf));
+
+ return 0;
+}
+
+static void
+sync_file_fence_cb(struct dma_fence *fence, struct dma_fence_cb *fcb)
+{
+ struct sync_file *sf = container_of(fcb, struct sync_file, sf_fcb);
+
+ mutex_enter(&sf->sf_lock);
+ sf->sf_signalled = true;
+ selnotify(&sf->sf_selq, POLLIN, NOTE_SUBMIT);
+ mutex_exit(&sf->sf_lock);
+}
+
+static int
+sync_file_poll(struct file *fp, int events)
+{
+ struct sync_file *sf = fp->f_data;
+ int revents = 0;
+ int ret;
+
+ if ((events & POLLIN) == 0)
+ return 0;
+
+ mutex_enter(&sf->sf_lock);
+ if (sf->sf_signalled) {
+ revents |= POLLIN;
+ } else if (sf->sf_polling) {
+ selrecord(curlwp, &sf->sf_selq);
+ } else {
+ sf->sf_polling = true;
+ mutex_exit(&sf->sf_lock);
+ ret = dma_fence_add_callback(sf->sf_fence, &sf->sf_fcb,
+ sync_file_fence_cb);
+ mutex_enter(&sf->sf_lock);
+ if (ret < 0) {
+ sf->sf_signalled = true;
+ selnotify(&sf->sf_selq, POLLIN, NOTE_SUBMIT);
+ revents |= POLLIN;
+ } else {
+ selrecord(curlwp, &sf->sf_selq);
+ }
+ }
+ mutex_exit(&sf->sf_lock);
+
+ return revents;
+}
+
+static const struct filterops sync_file_filtops;
+
+static int
+sync_file_kqfilter(struct file *fp, struct knote *kn)
+{
+ struct sync_file *sf = fp->f_data;
+
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &sync_file_filtops;
+ kn->kn_hook = sf;
+ mutex_enter(&sf->sf_lock);
+ SLIST_INSERT_HEAD(&sf->sf_selq.sel_klist, kn, kn_selnext);
+ mutex_exit(&sf->sf_lock);
+ return 0;
+ default:
+ return EINVAL;
+ }
+}
+
+static void
+filt_sync_file_detach(struct knote *kn)
+{
+ struct sync_file *sf = kn->kn_hook;
+
+ mutex_enter(&sf->sf_lock);
+ SLIST_REMOVE(&sf->sf_selq.sel_klist, kn, knote, kn_selnext);
+ mutex_exit(&sf->sf_lock);
+}
+
+static int
+filt_sync_file_event(struct knote *kn, long hint)
+{
+ struct sync_file *sf = kn->kn_hook;
+ int ret;
+
+ if (hint == NOTE_SUBMIT)
+ KASSERT(mutex_owned(&sf->sf_lock));
+ else
+ mutex_enter(&sf->sf_lock);
+
+ if (sf->sf_signalled) {
+ kn->kn_data = 0; /* XXX Does this work?? */
+ ret = 1;
+ } else if (sf->sf_polling) {
+ ret = 0;
+ } else {
+ sf->sf_polling = true;
+ mutex_exit(&sf->sf_lock);
+ ret = dma_fence_add_callback(sf->sf_fence, &sf->sf_fcb,
+ sync_file_fence_cb);
+ mutex_enter(&sf->sf_lock);
+ if (ret < 0) {
+ sf->sf_signalled = true;
+ selnotify(&sf->sf_selq, POLLIN, NOTE_SUBMIT);
+ kn->kn_data = 0;
+ ret = 1;
+ } else {
+ selrecord(curlwp, &sf->sf_selq);
+ ret = 0;
+ }
+ }
+
+ if (hint == NOTE_SUBMIT)
+ KASSERT(mutex_owned(&sf->sf_lock));
+ else
+ mutex_exit(&sf->sf_lock);
+
+ return ret;
+}
+
+static const struct filterops sync_file_filtops = {
+ .f_flags = FILTEROP_ISFD,
+ .f_attach = NULL,
+ .f_detach = filt_sync_file_detach,
+ .f_event = filt_sync_file_event,
+};
+
+struct dma_fence *
+sync_file_get_fence(int fd)
+{
+ struct file *fp;
+ struct sync_file *sf;
+ struct dma_fence *fence;
+
+ if ((fp = fd_getfile(fd)) == NULL)
+ return NULL;
+ sf = fp->f_data;
+ fence = dma_fence_get(sf->sf_fence);
+ fd_putfile(fd);
Home |
Main Index |
Thread Index |
Old Index