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 Hash-locked atomic64 to give ports lik...



details:   https://anonhg.NetBSD.org/src/rev/2153450da16c
branches:  trunk
changeset: 366378:2153450da16c
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Aug 27 15:08:54 2018 +0000

description:
Hash-locked atomic64 to give ports like powerpc32 a chance at radeon.

diffstat:

 sys/external/bsd/drm2/include/linux/atomic.h   |   25 +++-
 sys/external/bsd/drm2/linux/files.drmkms_linux |    3 +-
 sys/external/bsd/drm2/linux/linux_atomic64.c   |  194 +++++++++++++++++++++++++
 sys/external/bsd/drm2/linux/linux_module.c     |   17 +-
 4 files changed, 233 insertions(+), 6 deletions(-)

diffs (truncated from 313 to 300 lines):

diff -r 714782a4d11d -r 2153450da16c sys/external/bsd/drm2/include/linux/atomic.h
--- a/sys/external/bsd/drm2/include/linux/atomic.h      Mon Aug 27 15:08:25 2018 +0000
+++ b/sys/external/bsd/drm2/include/linux/atomic.h      Mon Aug 27 15:08:54 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atomic.h,v 1.14 2018/08/27 13:58:16 riastradh Exp $    */
+/*     $NetBSD: atomic.h,v 1.15 2018/08/27 15:08:54 riastradh Exp $    */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -229,6 +229,11 @@
 
 typedef struct atomic64 atomic64_t;
 
+int            linux_atomic64_init(void);
+void           linux_atomic64_fini(void);
+
+#ifdef __HAVE_ATOMIC64_OPS
+
 static inline uint64_t
 atomic64_read(const struct atomic64 *a)
 {
@@ -286,6 +291,24 @@
        return old;
 }
 
+#else  /* !defined(__HAVE_ATOMIC64_OPS) */
+
+#define        atomic64_read           linux_atomic64_read
+#define        atomic64_set            linux_atomic64_set
+#define        atomic64_add            linux_atomic64_add
+#define        atomic64_sub            linux_atomic64_sub
+#define        atomic64_xchg           linux_atomic64_xchg
+#define        atomic64_cmpxchg        linux_atomic64_cmpxchg
+
+uint64_t       atomic64_read(const struct atomic64 *);
+void           atomic64_set(struct atomic64 *, uint64_t);
+void           atomic64_add(long long, struct atomic64 *);
+void           atomic64_sub(long long, struct atomic64 *);
+uint64_t       atomic64_xchg(struct atomic64 *, uint64_t);
+uint64_t       atomic64_cmpxchg(struct atomic64 *, uint64_t, uint64_t);
+
+#endif
+
 struct atomic_long {
        volatile unsigned long  al_v;
 };
diff -r 714782a4d11d -r 2153450da16c sys/external/bsd/drm2/linux/files.drmkms_linux
--- a/sys/external/bsd/drm2/linux/files.drmkms_linux    Mon Aug 27 15:08:25 2018 +0000
+++ b/sys/external/bsd/drm2/linux/files.drmkms_linux    Mon Aug 27 15:08:54 2018 +0000
@@ -1,10 +1,11 @@
-#       $NetBSD: files.drmkms_linux,v 1.15 2018/08/27 14:16:38 riastradh Exp $
+#       $NetBSD: files.drmkms_linux,v 1.16 2018/08/27 15:08:54 riastradh Exp $
 
 define drmkms_linux: i2cexec, i2c_bitbang
 
 makeoptions    drmkms_linux    CPPFLAGS+="-I$S/external/bsd/common/include"
 makeoptions    drmkms_linux    CPPFLAGS+="-I$S/external/bsd/drm2/include"
 
+file   external/bsd/drm2/linux/linux_atomic64.c        drmkms_linux
 file   external/bsd/drm2/linux/linux_dmi.c             drmkms_linux
 file   external/bsd/drm2/linux/linux_fence.c           drmkms_linux
 file   external/bsd/drm2/linux/linux_i2c.c             drmkms_linux
diff -r 714782a4d11d -r 2153450da16c sys/external/bsd/drm2/linux/linux_atomic64.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/linux/linux_atomic64.c      Mon Aug 27 15:08:54 2018 +0000
@@ -0,0 +1,194 @@
+/*     $NetBSD: linux_atomic64.c,v 1.1 2018/08/27 15:08:54 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_atomic64.c,v 1.1 2018/08/27 15:08:54 riastradh Exp $");
+
+#include <sys/param.h>
+#include <sys/bitops.h>
+#include <sys/lock.h>
+
+#include <linux/atomic.h>
+
+#ifdef __HAVE_ATOMIC64_OPS
+
+int
+linux_atomic64_init(void)
+{
+       return 0;
+}
+
+void
+linux_atomic64_fini(void)
+{
+}
+
+#else
+
+static struct {
+       kmutex_t        lock;
+       uint32_t        gen;    /* for unlocked read */
+       char            pad[CACHE_LINE_SIZE -
+                           sizeof(kmutex_t) - sizeof(uint32_t)];
+} atomic64_tab[PAGE_SIZE/CACHE_LINE_SIZE] __cacheline_aligned;
+CTASSERT(sizeof(atomic64_tab) == PAGE_SIZE);
+CTASSERT(sizeof(atomic64_tab[0]) == CACHE_LINE_SIZE);
+
+int
+linux_atomic64_init(void)
+{
+       size_t i;
+
+       for (i = 0; i < __arraycount(atomic64_tab); i++) {
+               mutex_init(&atomic64_tab[i].lock, MUTEX_DEFAULT, IPL_HIGH);
+               atomic64_tab[i].gen = 0;
+       }
+
+       return 0;
+}
+
+void
+linux_atomic64_fini(void)
+{
+       size_t i;
+
+       for (i = 0; i < __arraycount(atomic64_tab); i++) {
+               KASSERT((atomic64_tab[i].gen & 1) == 0);
+               mutex_destroy(&atomic64_tab[i].lock);
+       }
+}
+
+static inline size_t
+atomic64_hash(const struct atomic64 *a)
+{
+
+       return ((uintptr_t)a >> ilog2(CACHE_LINE_SIZE)) %
+           __arraycount(atomic64_tab);
+}
+
+static void
+atomic64_lock(struct atomic64 *a)
+{
+       size_t i = atomic64_hash(a);
+
+       mutex_spin_enter(&atomic64_tab[i].lock);
+       KASSERT((atomic64_tab[i].gen & 1) == 0);
+       atomic64_tab[i].gen |= 1;
+       membar_producer();
+}
+
+static void
+atomic64_unlock(struct atomic64 *a)
+{
+       size_t i = atomic64_hash(a);
+
+       KASSERT(mutex_owned(&atomic64_tab[i].lock));
+       KASSERT((atomic64_tab[i].gen & 1) == 1);
+
+       membar_producer();
+       atomic64_tab[i].gen |= 1; /* paranoia */
+       atomic64_tab[i].gen++;
+       mutex_spin_exit(&atomic64_tab[i].lock);
+}
+
+uint64_t
+atomic64_read(const struct atomic64 *a)
+{
+       size_t i = atomic64_hash(a);
+       uint32_t gen;
+       uint64_t value;
+
+       do {
+               while (__predict_false((gen = atomic64_tab[i].gen) & 1))
+                       SPINLOCK_BACKOFF_HOOK;
+               membar_consumer();
+               value = a->a_v;
+               membar_consumer();
+       } while (__predict_false(atomic64_tab[i].gen != gen));
+
+       return value;
+}
+
+void
+atomic64_set(struct atomic64 *a, uint64_t value)
+{
+
+       atomic64_lock(a);
+       a->a_v = value;
+       atomic64_unlock(a);
+}
+
+void
+atomic64_add(long long delta, struct atomic64 *a)
+{
+
+       atomic64_lock(a);
+       a->a_v += delta;
+       atomic64_unlock(a);
+}
+
+void
+atomic64_sub(long long delta, struct atomic64 *a)
+{
+
+       atomic64_lock(a);
+       a->a_v -= delta;
+       atomic64_unlock(a);
+}
+
+uint64_t
+atomic64_xchg(struct atomic64 *a, uint64_t new)
+{
+       uint64_t old;
+
+       atomic64_lock(a);
+       old = a->a_v;
+       a->a_v = new;
+       atomic64_unlock(a);
+
+       return old;
+}
+
+uint64_t
+atomic64_cmpxchg(struct atomic64 *a, uint64_t expect, uint64_t new)
+{
+       uint64_t old;
+
+       atomic64_lock(a);
+       old = a->a_v;
+       if (old == expect)
+               a->a_v = new;
+       atomic64_unlock(a);
+
+       return old;
+}
+
+#endif
diff -r 714782a4d11d -r 2153450da16c sys/external/bsd/drm2/linux/linux_module.c
--- a/sys/external/bsd/drm2/linux/linux_module.c        Mon Aug 27 15:08:25 2018 +0000
+++ b/sys/external/bsd/drm2/linux/linux_module.c        Mon Aug 27 15:08:54 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_module.c,v 1.8 2018/08/27 13:33:59 riastradh Exp $       */
+/*     $NetBSD: linux_module.c,v 1.9 2018/08/27 15:08:54 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,13 +30,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_module.c,v 1.8 2018/08/27 13:33:59 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_module.c,v 1.9 2018/08/27 15:08:54 riastradh Exp $");
 
 #include <sys/module.h>
 #ifndef _MODULE
 #include <sys/once.h>
 #endif
 
+#include <linux/atomic.h>
 #include <linux/highmem.h>
 #include <linux/idr.h>
 #include <linux/io.h>
@@ -82,10 +83,17 @@
                goto fail4;
        }
 
+       error = linux_atomic64_init();
+       if (error) {
+               printf("linux: unable to initialize atomic64: %d\n", error);
+               goto fail5;
+       }
+
        return 0;
 
-fail5: __unused
-       linux_writecomb_fini();
+fail6: __unused



Home | Main Index | Thread Index | Old Index