Module Name:    src
Committed By:   riastradh
Date:           Sun Dec 19 12:23:08 UTC 2021

Modified Files:
        src/sys/external/bsd/drm2/include/linux: kthread.h
        src/sys/external/bsd/drm2/linux: files.drmkms_linux linux_module.c
Added Files:
        src/sys/external/bsd/drm2/linux: linux_kthread.c

Log Message:
drm: linux kthread stubs


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/include/linux/kthread.h
cvs rdiff -u -r1.38 -r1.39 src/sys/external/bsd/drm2/linux/files.drmkms_linux
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/linux/linux_kthread.c
cvs rdiff -u -r1.12 -r1.13 src/sys/external/bsd/drm2/linux/linux_module.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/include/linux/kthread.h
diff -u src/sys/external/bsd/drm2/include/linux/kthread.h:1.2 src/sys/external/bsd/drm2/include/linux/kthread.h:1.3
--- src/sys/external/bsd/drm2/include/linux/kthread.h:1.2	Tue Mar 18 18:20:43 2014
+++ src/sys/external/bsd/drm2/include/linux/kthread.h	Sun Dec 19 12:23:07 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: kthread.h,v 1.2 2014/03/18 18:20:43 riastradh Exp $	*/
+/*	$NetBSD: kthread.h,v 1.3 2021/12/19 12:23:07 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,4 +32,29 @@
 #ifndef _LINUX_KTHREAD_H_
 #define _LINUX_KTHREAD_H_
 
+struct task_struct;
+
+#define	__kthread_should_park	linux___kthread_should_park
+#define	kthread_park		linux_kthread_park
+#define	kthread_parkme		linux_kthread_parkme
+#define	kthread_run		linux_kthread_run
+#define	kthread_should_park	linux_kthread_should_park
+#define	kthread_should_stop	linux_kthread_should_stop
+#define	kthread_stop		linux_kthread_stop
+#define	kthread_unpark		linux_kthread_unpark
+
+struct task_struct *kthread_run(int (*)(void *), void *, const char *);
+
+int kthread_stop(struct task_struct *);
+int kthread_should_stop(void);
+
+void kthread_park(struct task_struct *);
+void kthread_unpark(struct task_struct *);
+int __kthread_should_park(struct task_struct *);
+int kthread_should_park(void);
+void kthread_parkme(void);
+
+int linux_kthread_init(void);
+void linux_kthread_fini(void);
+
 #endif  /* _LINUX_KTHREAD_H_ */

Index: src/sys/external/bsd/drm2/linux/files.drmkms_linux
diff -u src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.38 src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.39
--- src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.38	Sun Dec 19 12:06:57 2021
+++ src/sys/external/bsd/drm2/linux/files.drmkms_linux	Sun Dec 19 12:23:07 2021
@@ -1,4 +1,4 @@
-#       $NetBSD: files.drmkms_linux,v 1.38 2021/12/19 12:06:57 riastradh Exp $
+#       $NetBSD: files.drmkms_linux,v 1.39 2021/12/19 12:23:07 riastradh Exp $
 
 define	drmkms_linux: i2cexec, i2c_bitbang
 
@@ -19,6 +19,7 @@ file	external/bsd/drm2/linux/linux_i2c.c
 file	external/bsd/drm2/linux/linux_idr.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_irq_work.c	drmkms_linux
 file	external/bsd/drm2/linux/linux_kmap.c		drmkms_linux
+file	external/bsd/drm2/linux/linux_kthread.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_list_sort.c	drmkms_linux
 file	external/bsd/drm2/linux/linux_module.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_notifier.c	drmkms_linux

Index: src/sys/external/bsd/drm2/linux/linux_module.c
diff -u src/sys/external/bsd/drm2/linux/linux_module.c:1.12 src/sys/external/bsd/drm2/linux/linux_module.c:1.13
--- src/sys/external/bsd/drm2/linux/linux_module.c:1.12	Sun Dec 19 11:49:57 2021
+++ src/sys/external/bsd/drm2/linux/linux_module.c	Sun Dec 19 12:23:07 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_module.c,v 1.12 2021/12/19 11:49:57 riastradh Exp $	*/
+/*	$NetBSD: linux_module.c,v 1.13 2021/12/19 12:23:07 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_module.c,v 1.12 2021/12/19 11:49:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_module.c,v 1.13 2021/12/19 12:23:07 riastradh Exp $");
 
 #include <sys/module.h>
 #ifndef _MODULE
@@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_module
 #include <linux/idr.h>
 #include <linux/io.h>
 #include <linux/irq_work.h>
+#include <linux/kthread.h>
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
 #include <linux/tasklet.h>
@@ -104,12 +105,19 @@ linux_init(void)
 		goto fail7;
 	}
 
+	error = linux_kthread_init();
+	if (error) {
+		printf("linux: unable to initialize kthread: %d\n", error);
+		goto fail8;
+	}
+
 	linux_irq_work_init();
 
 	return 0;
 
-fail8: __unused
-	linux_wait_bit_fini();
+fail9: __unused
+	linux_kthread_fini();
+fail8:	linux_wait_bit_fini();
 fail7:	linux_tasklets_fini();
 fail6:	linux_atomic64_fini();
 fail5:	linux_writecomb_fini();
@@ -138,6 +146,7 @@ linux_fini(void)
 {
 
 	linux_irq_work_fini();
+	linux_kthread_fini();
 	linux_wait_bit_fini();
 	linux_tasklets_fini();
 	linux_atomic64_fini();

Added files:

Index: src/sys/external/bsd/drm2/linux/linux_kthread.c
diff -u /dev/null src/sys/external/bsd/drm2/linux/linux_kthread.c:1.1
--- /dev/null	Sun Dec 19 12:23:08 2021
+++ src/sys/external/bsd/drm2/linux/linux_kthread.c	Sun Dec 19 12:23:07 2021
@@ -0,0 +1,233 @@
+/*	$NetBSD: linux_kthread.c,v 1.1 2021/12/19 12:23:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2021 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * 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_kthread.c,v 1.1 2021/12/19 12:23:07 riastradh Exp $");
+
+#include <sys/types.h>
+
+#include <sys/condvar.h>
+#include <sys/kmem.h>
+#include <sys/kthread.h>
+#include <sys/lwp.h>
+#include <sys/mutex.h>
+#include <sys/specificdata.h>
+
+#include <linux/kthread.h>
+
+struct task_struct {
+	kmutex_t	kt_lock;
+	kcondvar_t	kt_cv;
+	bool		kt_shouldstop:1;
+	bool		kt_shouldpark:1;
+	bool		kt_parked:1;
+
+	int		(*kt_func)(void *);
+	void		*kt_cookie;
+	struct lwp	*kt_lwp;
+};
+
+static specificdata_key_t linux_kthread_key __read_mostly = -1;
+
+int
+linux_kthread_init(void)
+{
+	int error;
+
+	error = lwp_specific_key_create(&linux_kthread_key, NULL);
+	if (error)
+		goto out;
+
+	/* Success!  */
+	error = 0;
+
+out:	if (error)
+		linux_kthread_fini();
+	return error;
+}
+
+void
+linux_kthread_fini(void)
+{
+
+	if (linux_kthread_key != -1) {
+		lwp_specific_key_delete(linux_kthread_key);
+		linux_kthread_key = -1;
+	}
+}
+
+#define	linux_kthread()	_linux_kthread(__func__)
+static struct task_struct *
+_linux_kthread(const char *caller)
+{
+	struct task_struct *T;
+
+	T = lwp_getspecific(linux_kthread_key);
+	KASSERTMSG(T != NULL, "%s must be called from Linux kthread", caller);
+
+	return T;
+}
+
+static void
+linux_kthread_start(void *cookie)
+{
+	struct task_struct *T = cookie;
+	int ret;
+
+	lwp_setspecific(linux_kthread_key, T);
+
+	ret = (*T->kt_func)(T->kt_cookie);
+	kthread_exit(ret);
+}
+
+static struct task_struct *
+kthread_alloc(int (*func)(void *), void *cookie)
+{
+	struct task_struct *T;
+
+	T = kmem_zalloc(sizeof(*T), KM_SLEEP);
+
+	mutex_init(&T->kt_lock, MUTEX_DEFAULT, IPL_NONE);
+	cv_init(&T->kt_cv, "lnxkthrd");
+
+	T->kt_func = func;
+	T->kt_cookie = cookie;
+
+	return T;
+}
+
+static void
+kthread_free(struct task_struct *T)
+{
+
+	cv_destroy(&T->kt_cv);
+	mutex_destroy(&T->kt_lock);
+	kmem_free(T, sizeof(*T));
+}
+
+struct task_struct *
+kthread_run(int (*func)(void *), void *cookie, const char *name)
+{
+	struct task_struct *T;
+	int error;
+
+	T = kthread_alloc(func, cookie);
+	error = kthread_create(PRI_NONE, KTHREAD_MPSAFE|KTHREAD_MUSTJOIN, NULL,
+	    linux_kthread_start, T, &T->kt_lwp, "%s", name);
+	if (error) {
+		kthread_free(T);
+		T = NULL;
+	}
+
+	return T;
+}
+
+int
+kthread_stop(struct task_struct *T)
+{
+	int ret;
+
+	mutex_enter(&T->kt_lock);
+	T->kt_shouldpark = false;
+	T->kt_shouldstop = true;
+	cv_broadcast(&T->kt_cv);
+	mutex_exit(&T->kt_lock);
+
+	ret = kthread_join(T->kt_lwp);
+
+	kthread_free(T);
+
+	return ret;
+}
+
+int
+kthread_should_stop(void)
+{
+
+	return linux_kthread()->kt_shouldstop;
+}
+
+void
+kthread_park(struct task_struct *T)
+{
+
+	mutex_enter(&T->kt_lock);
+	KASSERT(!T->kt_shouldstop);
+	T->kt_shouldpark = true;
+	while (!T->kt_parked)
+		cv_wait(&T->kt_cv, &T->kt_lock);
+	mutex_exit(&T->kt_lock);
+}
+
+void
+kthread_unpark(struct task_struct *T)
+{
+
+	mutex_enter(&T->kt_lock);
+	T->kt_shouldpark = false;
+	cv_broadcast(&T->kt_cv);
+	mutex_exit(&T->kt_lock);
+}
+
+int
+__kthread_should_park(struct task_struct *T)
+{
+	bool shouldpark;
+
+	mutex_enter(&T->kt_lock);
+	shouldpark = T->kt_shouldpark;
+	mutex_exit(&T->kt_lock);
+
+	return shouldpark;
+}
+
+int
+kthread_should_park(void)
+{
+	struct task_struct *T = linux_kthread();
+
+	return __kthread_should_park(T);
+}
+
+void
+kthread_parkme(void)
+{
+	struct task_struct *T = linux_kthread();
+
+	mutex_enter(&T->kt_lock);
+	while (T->kt_shouldpark) {
+		T->kt_parked = true;
+		cv_broadcast(&T->kt_cv);
+		cv_wait(&T->kt_cv, &T->kt_lock);
+		T->kt_parked = false;
+	}
+	mutex_exit(&T->kt_lock);
+}

Reply via email to