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