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