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/dist/drm Tweak fd, timedwait APIs.



details:   https://anonhg.NetBSD.org/src/rev/7c7de79c851d
branches:  trunk
changeset: 1027917:7c7de79c851d
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Dec 19 01:16:13 2021 +0000

description:
Tweak fd, timedwait APIs.

diffstat:

 sys/external/bsd/drm2/dist/drm/drm_syncobj.c |  155 ++++++++++++++++++++++++++-
 1 files changed, 153 insertions(+), 2 deletions(-)

diffs (truncated from 316 to 300 lines):

diff -r 6d4fd977e510 -r 7c7de79c851d sys/external/bsd/drm2/dist/drm/drm_syncobj.c
--- a/sys/external/bsd/drm2/dist/drm/drm_syncobj.c      Sun Dec 19 01:16:05 2021 +0000
+++ b/sys/external/bsd/drm2/dist/drm/drm_syncobj.c      Sun Dec 19 01:16:13 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: drm_syncobj.c,v 1.2 2021/12/18 23:44:57 riastradh Exp $        */
+/*     $NetBSD: drm_syncobj.c,v 1.3 2021/12/19 01:16:13 riastradh Exp $        */
 
 /*
  * Copyright 2017 Red Hat
@@ -125,7 +125,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_syncobj.c,v 1.2 2021/12/18 23:44:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_syncobj.c,v 1.3 2021/12/19 01:16:13 riastradh Exp $");
 
 #include <linux/anon_inodes.h>
 #include <linux/file.h>
@@ -146,7 +146,12 @@
 
 struct syncobj_wait_entry {
        struct list_head node;
+#ifdef __NetBSD__
+       kmutex_t        *lock;
+       kcondvar_t      *cv;
+#else
        struct task_struct *task;
+#endif
        struct dma_fence *fence;
        struct dma_fence_cb fence_cb;
        u64    point;
@@ -499,17 +504,40 @@
        return 0;
 }
 
+#ifdef __NetBSD__
+static int drm_syncobj_fop_close(struct file *file)
+#else
 static int drm_syncobj_file_release(struct inode *inode, struct file *file)
+#endif
 {
+#ifdef __NetBSD__
+       struct drm_syncobj *syncobj = file->f_data;
+#else
        struct drm_syncobj *syncobj = file->private_data;
+#endif
 
        drm_syncobj_put(syncobj);
        return 0;
 }
 
+#ifdef __NetBSD__
+static const struct fileops drm_syncobj_file_ops = {
+       .fo_name = "drm_syncobj",
+       .fo_read = fbadop_read,
+       .fo_write = fbadop_write,
+       .fo_ioctl = fbadop_ioctl,
+       .fo_fcntl = fnullop_fcntl,
+       .fo_poll = fnullop_poll,
+       .fo_stat = fbadop_stat,
+       .fo_close = drm_syncobj_fop_close,
+       .fo_kqfilter = fnullop_kqfilter,
+       .fo_restart = fnullop_restart,
+};
+#else
 static const struct file_operations drm_syncobj_file_fops = {
        .release = drm_syncobj_file_release,
 };
+#endif
 
 /**
  * drm_syncobj_get_fd - get a file descriptor from a syncobj
@@ -524,7 +552,19 @@
 {
        struct file *file;
        int fd;
+#ifdef __NetBSD__
+       int ret;
+#endif
 
+#ifdef __NetBSD__
+       fd = -1;
+       /* XXX errno NetBSD->Linux */
+       ret = -fd_allocfile(&file, &fd);
+       if (ret)
+               return ret;
+       file->f_data = syncobj;
+       file->f_ops = &drm_syncobj_file_ops;
+#else
        fd = get_unused_fd_flags(O_CLOEXEC);
        if (fd < 0)
                return fd;
@@ -536,6 +576,7 @@
                put_unused_fd(fd);
                return PTR_ERR(file);
        }
+#endif
 
        drm_syncobj_get(syncobj);
        fd_install(fd, file);
@@ -569,13 +610,24 @@
        if (!f.file)
                return -EINVAL;
 
+#ifdef __NetBSD__
+       if (file->f_ops != &drm_syncobj_file_ops) {
+               fd_putfile(fd);
+               return -EINVAL;
+       }
+#else
        if (f.file->f_op != &drm_syncobj_file_fops) {
                fdput(f);
                return -EINVAL;
        }
+#endif
 
        /* take a reference to put in the idr */
+#ifdef __NetBSD__
+       syncobj = f.file->f_data;
+#else
        syncobj = f.file->private_data;
+#endif
        drm_syncobj_get(syncobj);
 
        idr_preload(GFP_KERNEL);
@@ -590,7 +642,11 @@
        } else
                drm_syncobj_put(syncobj);
 
+#ifdef __NetBSD__
+       fd_putfile(fd);
+#else
        fdput(f);
+#endif
        return ret;
 }
 
@@ -618,6 +674,50 @@
 static int drm_syncobj_export_sync_file(struct drm_file *file_private,
                                        int handle, int *p_fd)
 {
+#ifdef __NetBSD__
+       struct dma_fence *fence;
+       struct sync_file *sync_file;
+       struct file *fp = NULL;
+       int fd = -1;
+       int ret;
+
+       /* Allocate a file and descriptor.  */
+       /* XXX errno NetBSD->Linux */
+       ret = -fd_allocfile(&fp, &fd);
+       if (ret)
+               goto out;
+
+       /* Find the fence.  */
+       ret = drm_syncobj_find_fence(file_private, handle, &fence);
+       if (ret)
+               goto out;
+
+       /* Create the sync file.  */
+       sync_file = sync_file_create(fence, fp);
+
+       /* Release the fence.  */
+       dma_fence_put(fence);
+
+       /* If the sync file creation failed, bail.  */
+       if (sync_file == NULL)
+               goto out;
+
+       /* Success!  */
+       fd_affix(curproc, fp, fd);
+       fp = NULL;              /* sync_file consumes */
+       ret = 0;
+
+out:
+       /* If anything went wrong and we still have an unused file, abort.  */
+       if (fp != NULL) {
+               fd_abort(curproc, fp, fd);
+               fd = -1;
+       }
+
+       /* Return the descriptor or -1.  */
+       *p_fd = fd;
+       return ret;
+#else
        int ret;
        struct dma_fence *fence;
        struct sync_file *sync_file;
@@ -646,6 +746,7 @@
 err_put_fd:
        put_unused_fd(fd);
        return ret;
+#endif
 }
 /**
  * drm_syncobj_open - initalizes syncobj file-private structures at devnode open time
@@ -683,6 +784,7 @@
 {
        idr_for_each(&file_private->syncobj_idr,
                     &drm_syncobj_release_handle, file_private);
+       spin_lock_destroy(&file_private->syncobj_table_lock);
        idr_destroy(&file_private->syncobj_idr);
 }
 
@@ -847,7 +949,13 @@
        struct syncobj_wait_entry *wait =
                container_of(cb, struct syncobj_wait_entry, fence_cb);
 
+#ifdef __NetBSD__
+       mutex_enter(wait->lock);
+       cv_broadcast(wait->cv);
+       mutex_exit(wait->lock);
+#else
        wake_up_process(wait->task);
+#endif
 }
 
 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
@@ -868,7 +976,14 @@
                wait->fence = fence;
        }
 
+#ifdef __NetBSD__
+       KASSERT(spin_is_locked(&syncobj->lock));
+       mutex_enter(wait->lock);
+       cv_broadcast(wait->cv);
+       mutex_exit(wait->lock);
+#else
        wake_up_process(wait->task);
+#endif
        list_del_init(&wait->node);
 }
 
@@ -883,6 +998,12 @@
        struct dma_fence *fence;
        uint64_t *points;
        uint32_t signaled_count, i;
+#ifdef __NetBSD__
+       kmutex_t lock;
+       kcondvar_t cv;
+       mutex_init(&lock, MUTEX_DEFAULT, IPL_VM);
+       cv_init(&cv, "drmsynco");
+#endif
 
        points = kmalloc_array(count, sizeof(*points), GFP_KERNEL);
        if (points == NULL)
@@ -911,7 +1032,12 @@
        for (i = 0; i < count; ++i) {
                struct dma_fence *fence;
 
+#ifdef __NetBSD__
+               entries[i].lock = &lock;
+               entries[i].cv = &cv;
+#else
                entries[i].task = current;
+#endif
                entries[i].point = points[i];
                fence = drm_syncobj_fence_get(syncobjs[i]);
                if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) {
@@ -955,7 +1081,9 @@
        }
 
        do {
+#ifndef __NetBSD__
                set_current_state(TASK_INTERRUPTIBLE);
+#endif
 
                signaled_count = 0;
                for (i = 0; i < count; ++i) {
@@ -988,16 +1116,37 @@
                        goto done_waiting;
                }
 
+#ifdef __NetBSD__
+               unsigned long ticks = ret;
+               unsigned starttime = hardclock_ticks;
+               mutex_enter(&lock);
+               ret = -cv_timedwait_sig(&cv, &lock, MIN(ticks, INT_MAX));
+               mutex_exit(&lock);
+               unsigned endtime = hardclock_ticks;
+               if (ret == -EINTR || ret == -ERESTART) {
+                       ret = -ERESTARTSYS;
+               } else if (ret == -EWOULDBLOCK) {
+                       if (endtime - starttime < ticks)
+                               ret = ticks - (endtime - starttime);
+                       else
+                               ret = 0;
+               } else {
+                       KASSERTMSG(ret == 0, "%ld", ret);
+               }
+#else
                if (signal_pending(current)) {
                        timeout = -ERESTARTSYS;
                        goto done_waiting;
                }
 
                timeout = schedule_timeout(timeout);
+#endif
        } while (1);
 



Home | Main Index | Thread Index | Old Index