Module Name:    src
Committed By:   riastradh
Date:           Sun Dec 19 01:22:15 UTC 2021

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

Log Message:
linux/wait_bit.h


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/include/linux/wait_bit.h
cvs rdiff -u -r1.19 -r1.20 src/sys/external/bsd/drm2/linux/files.drmkms_linux
cvs rdiff -u -r1.10 -r1.11 src/sys/external/bsd/drm2/linux/linux_module.c
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/linux/linux_wait_bit.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/linux/files.drmkms_linux
diff -u src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.19 src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.20
--- src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.19	Sun Dec 19 00:58:22 2021
+++ src/sys/external/bsd/drm2/linux/files.drmkms_linux	Sun Dec 19 01:22:15 2021
@@ -1,4 +1,4 @@
-#       $NetBSD: files.drmkms_linux,v 1.19 2021/12/19 00:58:22 riastradh Exp $
+#       $NetBSD: files.drmkms_linux,v 1.20 2021/12/19 01:22:15 riastradh Exp $
 
 define	drmkms_linux: i2cexec, i2c_bitbang
 
@@ -18,5 +18,6 @@ file	external/bsd/drm2/linux/linux_pci.c
 file	external/bsd/drm2/linux/linux_rcu.c		drmkms_linux
 file	external/bsd/drm2/linux/linux_reservation.c	drmkms_linux
 file	external/bsd/drm2/linux/linux_srcu.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

Index: src/sys/external/bsd/drm2/linux/linux_module.c
diff -u src/sys/external/bsd/drm2/linux/linux_module.c:1.10 src/sys/external/bsd/drm2/linux/linux_module.c:1.11
--- src/sys/external/bsd/drm2/linux/linux_module.c:1.10	Sun Dec 19 01:17:14 2021
+++ src/sys/external/bsd/drm2/linux/linux_module.c	Sun Dec 19 01:22:15 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_module.c,v 1.10 2021/12/19 01:17:14 riastradh Exp $	*/
+/*	$NetBSD: linux_module.c,v 1.11 2021/12/19 01:22:15 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.10 2021/12/19 01:17:14 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_module.c,v 1.11 2021/12/19 01:22:15 riastradh Exp $");
 
 #include <sys/module.h>
 #ifndef _MODULE
@@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_module
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
 #include <linux/tasklet.h>
+#include <linux/wait_bit.h>
 #include <linux/workqueue.h>
 
 MODULE(MODULE_CLASS_MISC, drmkms_linux, "i2cexec");
@@ -96,10 +97,17 @@ linux_init(void)
 		goto fail6;
 	}
 
+	error = linux_wait_bit_init();
+	if (error) {
+		printf("linux: unable to initialize wait_bit: %d\n", error);
+		goto fail7;
+	}
+
 	return 0;
 
-fail7: __unused
-	linux_tasklets_fini();
+fail8: __unused
+	linux_wait_bit_fini();
+fail7:	linux_tasklets_fini();
 fail6:	linux_atomic64_fini();
 fail5:	linux_writecomb_fini();
 fail4:	linux_workqueue_fini();
@@ -126,6 +134,7 @@ static void
 linux_fini(void)
 {
 
+	linux_wait_bit_fini();
 	linux_tasklets_fini();
 	linux_atomic64_fini();
 	linux_writecomb_fini();

Added files:

Index: src/sys/external/bsd/drm2/include/linux/wait_bit.h
diff -u /dev/null src/sys/external/bsd/drm2/include/linux/wait_bit.h:1.1
--- /dev/null	Sun Dec 19 01:22:15 2021
+++ src/sys/external/bsd/drm2/include/linux/wait_bit.h	Sun Dec 19 01:22:15 2021
@@ -0,0 +1,45 @@
+/*	$NetBSD: wait_bit.h,v 1.1 2021/12/19 01:22:15 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef	_LINUX_WAIT_BIT_H_
+#define	_LINUX_WAIT_BIT_H_
+
+#define	wait_on_bit_timeout	linux_wait_on_bit_timeout
+#define	wake_up_bit		linux_wake_up_bit
+
+int	linux_wait_bit_init(void);
+void	linux_wait_bit_fini(void);
+
+void	wake_up_bit(const volatile unsigned long *, unsigned);
+int	wait_on_bit_timeout(const volatile unsigned long *, unsigned, int,
+	    unsigned long);
+
+#endif	/* _LINUX_WAIT_BIT_H_ */

Index: src/sys/external/bsd/drm2/linux/linux_wait_bit.c
diff -u /dev/null src/sys/external/bsd/drm2/linux/linux_wait_bit.c:1.1
--- /dev/null	Sun Dec 19 01:22:15 2021
+++ src/sys/external/bsd/drm2/linux/linux_wait_bit.c	Sun Dec 19 01:22:15 2021
@@ -0,0 +1,162 @@
+/*	$NetBSD: linux_wait_bit.c,v 1.1 2021/12/19 01:22:15 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2018 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_wait_bit.c,v 1.1 2021/12/19 01:22:15 riastradh Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/bitops.h>
+#include <sys/condvar.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+#include <linux/bitops.h>
+#include <linux/sched.h>
+#include <linux/wait_bit.h>
+
+static struct {
+	struct waitbitentry {
+		kmutex_t	lock;
+		kcondvar_t	cv;
+	}		ent;
+	char		pad[CACHE_LINE_SIZE - sizeof(struct waitbitentry)];
+} waitbittab[PAGE_SIZE/CACHE_LINE_SIZE] __cacheline_aligned;
+CTASSERT(sizeof(waitbittab) == PAGE_SIZE);
+CTASSERT(sizeof(waitbittab[0]) == CACHE_LINE_SIZE);
+
+int
+linux_wait_bit_init(void)
+{
+	size_t i;
+
+	for (i = 0; i < __arraycount(waitbittab); i++) {
+		mutex_init(&waitbittab[i].ent.lock, MUTEX_DEFAULT, IPL_VM);
+		cv_init(&waitbittab[i].ent.cv, "waitbit");
+	}
+
+	return 0;
+}
+
+void
+linux_wait_bit_fini(void)
+{
+	size_t i;
+
+	for (i = 0; i < __arraycount(waitbittab); i++) {
+		cv_destroy(&waitbittab[i].ent.cv);
+		mutex_destroy(&waitbittab[i].ent.lock);
+	}
+}
+
+static inline size_t
+wait_bit_hash(const volatile unsigned long *bitmap, unsigned bit)
+{
+	/* Try to avoid cache line collisions.  */
+	const volatile unsigned long *word = bitmap + bit/(NBBY*sizeof(*word));
+
+	return ((uintptr_t)word >> ilog2(CACHE_LINE_SIZE)) %
+	    __arraycount(waitbittab);
+}
+
+static struct waitbitentry *
+wait_bit_enter(const volatile unsigned long *bitmap, unsigned bit)
+{
+	struct waitbitentry *wbe = &waitbittab[wait_bit_hash(bitmap, bit)].ent;
+
+	mutex_enter(&wbe->lock);
+
+	return wbe;
+}
+
+static void
+wait_bit_exit(struct waitbitentry *wbe)
+{
+
+	mutex_exit(&wbe->lock);
+}
+
+void
+wake_up_bit(const volatile unsigned long *bitmap, unsigned bit)
+{
+	struct waitbitentry *wbe;
+
+	wbe = wait_bit_enter(bitmap, bit);
+	cv_broadcast(&wbe->cv);
+	wait_bit_exit(wbe);
+}
+
+int
+wait_on_bit_timeout(const volatile unsigned long *bitmap, unsigned bit,
+    int flags, unsigned long timeout)
+{
+	struct waitbitentry *wbe;
+	int error, ret;
+
+	if (test_bit(bit, bitmap))
+		return timeout;
+
+	wbe = wait_bit_enter(bitmap, bit);
+
+	while (!test_bit(bit, bitmap)) {
+		unsigned starttime, endtime;
+
+		starttime = hardclock_ticks;
+		if (flags & TASK_UNINTERRUPTIBLE) {
+			error = cv_timedwait(&wbe->cv, &wbe->lock,
+			    MIN(INT_MAX, timeout));
+		} else {
+			error = cv_timedwait_sig(&wbe->cv, &wbe->lock,
+			    MIN(INT_MAX, timeout));
+		}
+		endtime = hardclock_ticks;
+
+		/* If we timed out, return zero time left.  */
+		if (error == EWOULDBLOCK || endtime - starttime < timeout) {
+			ret = 0;
+			goto out;
+		}
+
+		/* If we were interrupted, return -ERESTARTSYS.  */
+		if (error == EINTR || error == EWOULDBLOCK) {
+			ret = -ERESTARTSYS;
+			goto out;
+		}
+
+		/* Otherwise, debit the time spent.  */
+		timeout -= (endtime - starttime);
+	}
+	/* Bit is set.  Return the time left.  */
+	ret = timeout;
+
+out:	wait_bit_exit(wbe);
+	return ret;
+}

Reply via email to