Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/vax Implement CAS using a RAS for non-MP VAX system...
details: https://anonhg.NetBSD.org/src/rev/dc8df3ba6dee
branches: trunk
changeset: 758675:dc8df3ba6dee
user: matt <matt%NetBSD.org@localhost>
date: Sat Nov 13 02:23:27 2010 +0000
description:
Implement CAS using a RAS for non-MP VAX systems. This technique uses the
atomicity of indirect addressing for correctness. It also uses the knowledge
of dereferencing an address outside the page table length will cause a PTELEN
trap. [Tested on netbsd-5]
diffstat:
sys/arch/vax/include/cpu.h | 3 +-
sys/arch/vax/include/trap.h | 5 ++-
sys/arch/vax/vax/genassym.cf | 5 ++-
sys/arch/vax/vax/lock_stubs.S | 64 ++++++++++++++++++++++++++++++++++++------
sys/arch/vax/vax/trap.c | 23 ++++++++++++++-
5 files changed, 85 insertions(+), 15 deletions(-)
diffs (246 lines):
diff -r 9a54b209efdc -r dc8df3ba6dee sys/arch/vax/include/cpu.h
--- a/sys/arch/vax/include/cpu.h Sat Nov 13 02:07:28 2010 +0000
+++ b/sys/arch/vax/include/cpu.h Sat Nov 13 02:23:27 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.89 2010/07/01 19:50:12 ragge Exp $ */
+/* $NetBSD: cpu.h,v 1.90 2010/11/13 02:23:27 matt Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden
@@ -145,6 +145,7 @@
struct trapframe *ci_ddb_regs; /* Used by DDB */
SIMPLEQ_ENTRY(cpu_info) ci_next; /* next cpu_info */
#endif
+ uintptr_t ci_cas_addr; /* current address doing CAS in a RAS */
};
#define CI_MASTERCPU 1 /* Set if master CPU */
#define CI_RUNNING 2 /* Set when a slave CPU is running */
diff -r 9a54b209efdc -r dc8df3ba6dee sys/arch/vax/include/trap.h
--- a/sys/arch/vax/include/trap.h Sat Nov 13 02:07:28 2010 +0000
+++ b/sys/arch/vax/include/trap.h Sat Nov 13 02:23:27 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.h,v 1.22 2009/02/16 23:55:31 christos Exp $ */
+/* $NetBSD: trap.h,v 1.23 2010/11/13 02:23:27 matt Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -73,6 +73,9 @@
#define AFLT_FLTDIV 0x9 /* floating divide-by-zero */
#define AFLT_FLTUND 0xa /* floating underflow */
+/* Used by RAS to detect an interrupted CAS */
+#define CASMAGIC 0xBEDABABE /* high end of S0 space */
+
/* Trap's coming from user mode */
#define T_USER 0x100
diff -r 9a54b209efdc -r dc8df3ba6dee sys/arch/vax/vax/genassym.cf
--- a/sys/arch/vax/vax/genassym.cf Sat Nov 13 02:07:28 2010 +0000
+++ b/sys/arch/vax/vax/genassym.cf Sat Nov 13 02:23:27 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.46 2010/05/12 14:43:48 matt Exp $
+# $NetBSD: genassym.cf,v 1.47 2010/11/13 02:23:27 matt Exp $
#
# Copyright (c) 1997 Ludd, University of Lule}, Sweden.
# All rights reserved.
@@ -99,6 +99,7 @@
define CI_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count)
define CI_MTX_OLDSPL offsetof(struct cpu_info, ci_mtx_oldspl)
define CI_SOFTLWPS offsetof(struct cpu_info, ci_softlwps)
+define CI_CAS_ADDR offsetof(struct cpu_info, ci_cas_addr)
# mtpr register numbers
define PR_KSP PR_KSP
@@ -135,6 +136,8 @@
define T_ASTFLT T_ASTFLT
define T_KDBTRAP T_KDBTRAP
+define CASMAGIC CASMAGIC
+
define USPACE USPACE
define TRAPFRAMELEN sizeof(struct trapframe)
define CALLSFRAMELEN sizeof(struct callsframe)
diff -r 9a54b209efdc -r dc8df3ba6dee sys/arch/vax/vax/lock_stubs.S
--- a/sys/arch/vax/vax/lock_stubs.S Sat Nov 13 02:07:28 2010 +0000
+++ b/sys/arch/vax/vax/lock_stubs.S Sat Nov 13 02:23:27 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lock_stubs.S,v 1.16 2010/07/01 19:50:12 ragge Exp $ */
+/* $NetBSD: lock_stubs.S,v 1.17 2010/11/13 02:23:27 matt Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 The NetBSD Foundation, Inc.
@@ -61,6 +61,9 @@
#endif
clrl %r2 /* set old value (zero) */
mfpr $PR_SSP, %r3 /* set new value (curlwp) */
+#ifndef MULTIPROCESSOR
+ addl3 $CI_CAS_ADDR, L_CPU(%r3), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
bsbw _do_cas+2 /* do the compare-and-swap */
tstl %r0 /* is the old value what we wanted? */
beql 2f /* yep, just branch to the return */
@@ -78,6 +81,9 @@
#endif
mfpr $PR_SSP, %r2 /* get curlwp (old) */
clrl %r3 /* get zero (new) */
+#ifndef MULTIPROCESSOR
+ addl3 $CI_CAS_ADDR, L_CPU(%r2), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
bsbw _do_cas+2 /* do the compare-and-swap */
cmpl %r0,%r2 /* return == old? */
beql 2f /* yes, branch to return */
@@ -160,6 +166,10 @@
/* write active or pending? */
bneq 3f /* yep, go slow */
addl3 $RW_READ_INCR, %r2, %r3 /* incr. reader count (new) */
+#ifndef MULTIPROCESSOR
+ mfpr $PR_SSP, %r4
+ addl3 $CI_CAS_ADDR, L_CPU(%r4), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
1: bsbw _do_cas+2 /* do the compare-and-swap */
cmpl %r0, %r2 /* did it succeed? */
bneq 3f /* nope, go slow */
@@ -167,6 +177,9 @@
2: clrl %r2 /* get old value (zero) */
mfpr $PR_SSP, %r3 /* get new value (curlwp) */
+#ifndef MULTIPROCESSOR
+ addl3 $CI_CAS_ADDR, L_CPU(%r3), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
bisl2 $RW_WRITE_LOCKED, %r3 /* show that it's a write */
brb 1b /* do the compare-and-swap */
@@ -185,12 +198,19 @@
blbs %r2, 3f /* RW_HAS_WAITERS mbz */
subl3 $RW_READ_INCR, %r2, %r3 /* decr. reader count (new) */
blss 3f /* if less then 0, go slow */
+#ifndef MULTIPROCESSOR
+ mfpr $PR_SSP, %r4 /* get curlwp */
+ addl3 $CI_CAS_ADDR, L_CPU(%r4), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
1: bsbw _do_cas+2 /* do the compare-and-swap */
cmpl %r0, %r2 /* did it succeed? */
bneq 3f /* nope, go slow */
ret /* yes, return */
2: mfpr $PR_SSP, %r2 /* get old (curlwp) */
+#ifndef MULTIPROCESSOR
+ addl3 $CI_CAS_ADDR, L_CPU(%r2), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
bisl2 $RW_WRITE_LOCKED, %r2 /* show that it's a write */
clrl %r3 /* get new (zero) */
brb 1b /* do the compare-and-swap */
@@ -211,6 +231,10 @@
/* write active or pending? */
bneq 2f /* yes, return failure */
addl3 $RW_READ_INCR, %r2, %r3 /* incr reader count (new) */
+#ifndef MULTIPROCESSOR
+ mfpr $PR_SSP, %r4
+ addl3 $CI_CAS_ADDR, L_CPU(%r4), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
1: bsbw _do_cas+2 /* do the compare-and-swap */
cmpl %r0, %r2 /* did it succeed? */
bneq 2f /* no, we failed. */
@@ -221,6 +245,9 @@
3: clrl %r2 /* set old value (0) */
mfpr $PR_SSP, %r3 /* set new value (curlwp) */
+#ifndef MULTIPROCESSOR
+ addl3 $CI_CAS_ADDR, L_CPU(%r3), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
bisl2 $RW_WRITE_LOCKED, %r3 /* show that it's a write */
brb 1b /* do the compare-and-swap */
#endif /* LOCKDEBUG */
@@ -231,6 +258,10 @@
ENTRY(_atomic_cas_32, 0)
movq 4(%ap), %r1 /* cache ptr, old */
movl 12(%ap), %r3 /* cache new */
+#ifndef MULTIPROCESSOR
+ mfpr $PR_SSP, %r4
+ addl3 $CI_CAS_ADDR, L_CPU(%r4), %r4 /* r4 == &curcpu()->ci_cas_addr */
+#endif
bsbw _do_cas+2 /* do it */
ret
@@ -257,15 +288,28 @@
4:
rsb /* return */
#else
- mfpr $PR_IPL, %r5 /* save IPL */
- mtpr $IPL_SCHED, $PR_IPL /* block interrupts */
- movl (%r1), %r0 /* get current value */
- cmpl %r2, %r0 /* does it equal old value? */
- bneq 1f /* no, don't update */
- movl %r3, (%r1) /* yes, update */
-1: mtpr %r5, $PR_IPL /* drop/restore IPL */
- rsb /* return */
-#endif
+/*
+ * entry:
+ * r1 = address to be CAS'ed
+ * r2 = old value
+ * r3 = new value
+ * r4 = global cell to hold CAS address (common to all callers)
+ * e.g. address of curcpu()->ci_cas_addr
+ * exit:
+ * r0 = old value
+ */
+ .globl cas32_ras_start, cas32_ras_end
+cas32_ras_start:
+ movl %r1, (%r4)
+ movl *(%r4), %r0
+ cmpl %r2, %r0
+ bneq 1f
+ movl %r3, *(%r4)
+cas32_ras_end:
+1:
+ movl $CASMAGIC, (%r4)
+ rsb
+#endif /* !MULTIPROCESSOR */
STRONG_ALIAS(atomic_cas_ptr,_atomic_cas_32)
STRONG_ALIAS(_atomic_cas_ptr,_atomic_cas_32)
STRONG_ALIAS(atomic_cas_uint,_atomic_cas_32)
diff -r 9a54b209efdc -r dc8df3ba6dee sys/arch/vax/vax/trap.c
--- a/sys/arch/vax/vax/trap.c Sat Nov 13 02:07:28 2010 +0000
+++ b/sys/arch/vax/vax/trap.c Sat Nov 13 02:23:27 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.124 2010/04/23 19:18:10 rmind Exp $ */
+/* $NetBSD: trap.c,v 1.125 2010/11/13 02:23:27 matt Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
@@ -33,7 +33,7 @@
/* All bugs are subject to removal without further notice */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.124 2010/04/23 19:18:10 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.125 2010/11/13 02:23:27 matt Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -179,6 +179,25 @@
}
case T_PTELEN:
+#ifndef MULTIPROCESSOR
+ /*
+ * If we referred to an address beyond the end of the system
+ * page table, it may be due to a failed CAS
+ * restartable-atomic-sequence. If it is, restart it at the
+ * beginning and restart.
+ */
+ {
+ extern const uint8_t cas32_ras_start[], cas32_ras_end[];
+ if (frame->code == CASMAGIC
+ && frame->pc >= (uintptr_t) cas32_ras_start
+ && frame->pc < (uintptr_t) cas32_ras_end) {
+ frame->pc = (uintptr_t) cas32_ras_start;
+ trapsig = false;
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+#endif
case T_ACCFLT:
#ifdef TRAPDEBUG
if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
Home |
Main Index |
Thread Index |
Old Index