Module Name:    src
Committed By:   riastradh
Date:           Sun Dec 19 10:45:50 UTC 2021

Modified Files:
        src/sys/external/bsd/drm2/dist/drm: drm_atomic_uapi.c
        src/sys/external/bsd/drm2/include/linux: sync_file.h
        src/sys/external/bsd/drm2/linux: files.drmkms_linux
Added Files:
        src/sys/external/bsd/drm2/linux: linux_sync_file.c

Log Message:
Draft sync_file.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c
cvs rdiff -u -r1.3 -r1.4 src/sys/external/bsd/drm2/include/linux/sync_file.h
cvs rdiff -u -r1.24 -r1.25 src/sys/external/bsd/drm2/linux/files.drmkms_linux
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/linux/linux_sync_file.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/dist/drm/drm_atomic_uapi.c
diff -u src/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c:1.6 src/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c:1.7
--- src/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c:1.6	Sun Dec 19 01:58:41 2021
+++ src/sys/external/bsd/drm2/dist/drm/drm_atomic_uapi.c	Sun Dec 19 10:45:49 2021
@@ -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 @@ static int setup_out_fence(struct drm_ou
 		ret = -ENOMEM;
 		goto out;
 	}
+	fd_affix(curproc, fp, fd);
 	fp = NULL;		/* sync_file consumes */
 
 out:	if (fp != NULL) {

Index: src/sys/external/bsd/drm2/include/linux/sync_file.h
diff -u src/sys/external/bsd/drm2/include/linux/sync_file.h:1.3 src/sys/external/bsd/drm2/include/linux/sync_file.h:1.4
--- src/sys/external/bsd/drm2/include/linux/sync_file.h:1.3	Sun Dec 19 00:58:42 2021
+++ src/sys/external/bsd/drm2/include/linux/sync_file.h	Sun Dec 19 10:45:49 2021
@@ -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 *

Index: src/sys/external/bsd/drm2/linux/files.drmkms_linux
diff -u src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.24 src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.25
--- src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.24	Sun Dec 19 10:19:53 2021
+++ src/sys/external/bsd/drm2/linux/files.drmkms_linux	Sun Dec 19 10:45:50 2021
@@ -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_list_
 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

Added files:

Index: src/sys/external/bsd/drm2/linux/linux_sync_file.c
diff -u /dev/null src/sys/external/bsd/drm2/linux/linux_sync_file.c:1.1
--- /dev/null	Sun Dec 19 10:45:50 2021
+++ src/sys/external/bsd/drm2/linux/linux_sync_file.c	Sun Dec 19 10:45:50 2021
@@ -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);
+
+	return fence;
+}
+
+static const struct fileops sync_file_ops = {
+	.fo_name = "linux_sync_file",
+	.fo_read = fbadop_read,
+	.fo_write = fbadop_write,
+	.fo_ioctl = fbadop_ioctl,
+	.fo_fcntl = fnullop_fcntl,
+	.fo_poll = sync_file_poll,
+	.fo_stat = fbadop_stat,	/* XXX */
+	.fo_close = sync_file_close,
+	.fo_kqfilter = sync_file_kqfilter,
+	.fo_restart = fnullop_restart,
+	.fo_mmap = NULL,
+};

Reply via email to