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 drm: Work around busted kthread_...



details:   https://anonhg.NetBSD.org/src/rev/d451dcb7d2b5
branches:  trunk
changeset: 1029013:d451dcb7d2b5
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Dec 19 12:43:05 2021 +0000

description:
drm: Work around busted kthread_join.

diffstat:

 sys/external/bsd/drm2/linux/linux_kthread.c |  42 +++++++++++++++++++++++-----
 1 files changed, 34 insertions(+), 8 deletions(-)

diffs (100 lines):

diff -r 73ef3bec7596 -r d451dcb7d2b5 sys/external/bsd/drm2/linux/linux_kthread.c
--- a/sys/external/bsd/drm2/linux/linux_kthread.c       Sun Dec 19 12:42:58 2021 +0000
+++ b/sys/external/bsd/drm2/linux/linux_kthread.c       Sun Dec 19 12:43:05 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_kthread.c,v 1.8 2021/12/19 12:42:48 riastradh Exp $      */
+/*     $NetBSD: linux_kthread.c,v 1.9 2021/12/19 12:43:05 riastradh Exp $      */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_kthread.c,v 1.8 2021/12/19 12:42:48 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_kthread.c,v 1.9 2021/12/19 12:43:05 riastradh Exp $");
 
 #include <sys/types.h>
 
@@ -53,6 +53,8 @@
        bool            kt_shouldstop:1;
        bool            kt_shouldpark:1;
        bool            kt_parked:1;
+       bool            kt_exited:1;
+       int             kt_ret;
 
        int             (*kt_func)(void *);
        void            *kt_cookie;
@@ -111,7 +113,19 @@
        lwp_setspecific(linux_kthread_key, T);
 
        ret = (*T->kt_func)(T->kt_cookie);
-       kthread_exit(ret);
+
+       /*
+        * Mark the thread exited, set the return value, and wake any
+        * waiting kthread_stop.
+        */
+       mutex_enter(&T->kt_lock);
+       T->kt_exited = true;
+       T->kt_ret = ret;
+       cv_broadcast(&T->kt_cv);
+       mutex_exit(&T->kt_lock);
+
+       /* Exit the (NetBSD) kthread.  */
+       kthread_exit(0);
 }
 
 static struct task_struct *
@@ -125,6 +139,12 @@
        mutex_init(&T->kt_lock, MUTEX_DEFAULT, IPL_VM);
        cv_init(&T->kt_cv, "lnxkthrd");
 
+       T->kt_shouldstop = false;
+       T->kt_shouldpark = false;
+       T->kt_parked = false;
+       T->kt_exited = false;
+       T->kt_ret = 0;
+
        T->kt_func = func;
        T->kt_cookie = cookie;
        T->kt_interlock = interlock;
@@ -137,6 +157,8 @@
 kthread_free(struct task_struct *T)
 {
 
+       KASSERT(T->kt_exited);
+
        cv_destroy(&T->kt_cv);
        mutex_destroy(&T->kt_lock);
        kmem_free(T, sizeof(*T));
@@ -150,7 +172,7 @@
        int error;
 
        T = kthread_alloc(func, cookie, interlock, wq);
-       error = kthread_create(PRI_NONE, KTHREAD_MPSAFE|KTHREAD_MUSTJOIN, NULL,
+       error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
            linux_kthread_start, T, &T->kt_lwp, "%s", name);
        if (error) {
                kthread_free(T);
@@ -178,12 +200,16 @@
        cv_broadcast(&T->kt_cv);
        DRM_SPIN_WAKEUP_ALL(T->kt_wq, T->kt_interlock);
 
-       /* Release the locks.  */
-       mutex_exit(&T->kt_lock);
+       /* Release the interlock while we wait for thread to finish.  */
        spin_unlock(T->kt_interlock);
 
-       /* Wait for the (NetBSD) kthread to exit.  */
-       ret = kthread_join(T->kt_lwp);
+       /* Wait for the thread to finish.  */
+       while (!T->kt_exited)
+               cv_wait(&T->kt_cv, &T->kt_lock);
+
+       /* Grab the return code and release the lock -- we're done.  */
+       ret = T->kt_ret;
+       mutex_exit(&T->kt_lock);
 
        /* Free the (Linux) kthread.  */
        kthread_free(T);



Home | Main Index | Thread Index | Old Index