Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys/arch/sparc/sparc Pull up following revision(s) (reque...



details:   https://anonhg.NetBSD.org/src/rev/d5a4809d7214
branches:  netbsd-8
changeset: 447543:d5a4809d7214
user:      martin <martin%NetBSD.org@localhost>
date:      Tue Jan 15 18:40:15 2019 +0000

description:
Pull up following revision(s) (requested by mrg in ticket #1163):

        sys/arch/sparc/sparc/pmap.c: revision 1.366

switch sparc pmap lock to the scheme sparc64 uses:
- - local IPL_NONE mutex for general pmap locking operations, not
  kernel lock.
- - for pmap_activate()/pmap_deactivate(), switch to using the
  existing ctx_lock, and push handling of it into ctx_alloc() the
  ctx_free() callers.

fixes easy to trigger deadlocks on systems with >2 cpus.  without
this patch i usually hang during boot.  with it, i was able to
push the machine hard for over 12 hours.

XXX: pullup-8, and maybe -7.

diffstat:

 sys/arch/sparc/sparc/pmap.c |  47 +++++++++++++++++++++++---------------------
 1 files changed, 25 insertions(+), 22 deletions(-)

diffs (212 lines):

diff -r 77099a06c7e7 -r d5a4809d7214 sys/arch/sparc/sparc/pmap.c
--- a/sys/arch/sparc/sparc/pmap.c       Fri Jan 11 15:56:48 2019 +0000
+++ b/sys/arch/sparc/sparc/pmap.c       Tue Jan 15 18:40:15 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.361 2016/12/22 14:47:59 cherry Exp $ */
+/*     $NetBSD: pmap.c,v 1.361.8.1 2019/01/15 18:40:15 martin Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.361 2016/12/22 14:47:59 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.361.8.1 2019/01/15 18:40:15 martin Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -176,8 +176,8 @@
 paddr_t        vm_last_phys = 0;
 psize_t vm_num_phys;
 
-#define        PMAP_LOCK()     KERNEL_LOCK(1, NULL)
-#define        PMAP_UNLOCK()   KERNEL_UNLOCK_ONE(NULL)
+#define        PMAP_LOCK()     mutex_enter(&pmap_lock)
+#define        PMAP_UNLOCK()   mutex_exit(&pmap_lock)
 
 /*
  * Flags in pvlist.pv_flags.  Note that PV_MOD must be 1 and PV_REF must be 2
@@ -347,6 +347,7 @@
 int    seginval;               /* [4/4c] the invalid segment number */
 int    reginval;               /* [4/3mmu] the invalid region number */
 
+static kmutex_t pmap_lock;
 static kmutex_t demap_lock;
 static bool    lock_available = false; /* demap_lock has been initialized */
 
@@ -372,15 +373,15 @@
        struct  pmap *c_pmap;           /* pmap (if busy) */
 };
 
-static kmutex_t        ctx_lock;               /* lock for below */
+static kmutex_t        ctx_lock;               /* lock for below, and {,de}activate */
 union  ctxinfo *ctxinfo;               /* allocated at in pmap_bootstrap */
 union  ctxinfo *ctx_freelist;          /* context free list */
 int    ctx_kick;                       /* allocation rover when none free */
 int    ctx_kickdir;                    /* ctx_kick roves both directions */
 int    ncontext;                       /* sizeof ctx_freelist */
 
-void   ctx_alloc(struct pmap *);
-void   ctx_free(struct pmap *);
+static void    ctx_alloc(struct pmap *);
+static void    ctx_free(struct pmap *);
 
 /*void *       vdumppages;     -* 32KB worth of reserved dump pages */
 
@@ -2121,7 +2122,7 @@
  * This routine is only ever called from locore.s just after it has
  * saved away the previous process, so there are no active user windows.
  */
-void
+static void
 ctx_alloc(struct pmap *pm)
 {
        union ctxinfo *c;
@@ -2133,6 +2134,8 @@
        struct cpu_info *cpi;
 #endif
 
+       KASSERT(mutex_owned(&ctx_lock));
+
 /*XXX-GCC!*/gap_start=gap_end=0;
 #ifdef DEBUG
        if (pm->pm_ctx)
@@ -2145,7 +2148,6 @@
                gap_end = pm->pm_gap_end;
        }
 
-       mutex_spin_enter(&ctx_lock);
        if ((c = ctx_freelist) != NULL) {
                ctx_freelist = c->c_nextfree;
                cnum = c - ctxinfo;
@@ -2288,13 +2290,12 @@
                setcontext4m(cnum);
 #endif /* SUN4M || SUN4D */
        }
-       mutex_spin_exit(&ctx_lock);
 }
 
 /*
  * Give away a context.
  */
-void
+static void
 ctx_free(struct pmap *pm)
 {
        union ctxinfo *c;
@@ -2303,6 +2304,8 @@
        struct cpu_info *cpi;
 #endif
 
+       KASSERT(mutex_owned(&ctx_lock));
+
        c = pm->pm_ctx;
        ctx = pm->pm_ctxnum;
        pm->pm_ctx = NULL;
@@ -2316,8 +2319,6 @@
        }
 #endif /* SUN4 || SUN4C */
 
-       mutex_spin_enter(&ctx_lock);
-
 #if defined(SUN4M) || defined(SUN4D)
        if (CPU_HAS_SRMMU) {
                CPU_INFO_ITERATOR i;
@@ -2334,7 +2335,6 @@
 
        c->c_nextfree = ctx_freelist;
        ctx_freelist = c;
-       mutex_spin_exit(&ctx_lock);
 }
 
 
@@ -3070,6 +3070,7 @@
        }
 
        pmap_page_upload();
+       mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&demap_lock, MUTEX_DEFAULT, IPL_VM);
        mutex_init(&ctx_lock, MUTEX_DEFAULT, IPL_SCHED);
        lock_available = true;
@@ -4386,7 +4387,9 @@
 #endif
 
        if ((c = pm->pm_ctx) != NULL) {
+               mutex_spin_enter(&ctx_lock);
                ctx_free(pm);
+               mutex_spin_exit(&ctx_lock);
        }
 
 #if defined(SUN4M) || defined(SUN4D)
@@ -4656,7 +4659,7 @@
        }
 
        ctx = getcontext();
-       s = splvm();            /* XXX conservative */
+       s = splvm();
        PMAP_LOCK();
        for (; va < endva; va = nva) {
                /* do one virtual segment at a time */
@@ -6016,7 +6019,7 @@
        splx(s);
 }
 
-#if notyet
+#if notyet /* XXXMRG delete */
 void pmap_lockmmu(vaddr_t sva, size_t sz);
 
 void
@@ -6280,7 +6283,7 @@
        sp = &rp->rg_segmap[vs];
 
        kpreempt_disable();
-       s = splvm();            /* XXX way too conservative */
+       s = splvm();
        PMAP_LOCK();
 
        if (rp->rg_seg_ptps == NULL) /* enter new region */
@@ -6366,7 +6369,7 @@
        vr = VA_VREG(va);
        vs = VA_VSEG(va);
        rp = &pm->pm_regmap[vr];
-       s = splvm();                    /* XXX conservative */
+       s = splvm();
        PMAP_LOCK();
 
        if (rp->rg_segmap == NULL) {
@@ -7488,14 +7491,14 @@
                return;
        }
 
-       PMAP_LOCK();
+       mutex_spin_enter(&ctx_lock);
        if (pm->pm_ctx == NULL) {
                ctx_alloc(pm);  /* performs setcontext() */
        } else {
                setcontext(pm->pm_ctxnum);
        }
        PMAP_SET_CPUSET(pm, &cpuinfo);
-       PMAP_UNLOCK();
+       mutex_spin_exit(&ctx_lock);
 }
 
 /*
@@ -7512,7 +7515,7 @@
        }
 
        write_user_windows();
-       PMAP_LOCK();
+       mutex_spin_enter(&ctx_lock);
        if (pm->pm_ctx) {
                (*cpuinfo.pure_vcache_flush)();
 
@@ -7524,7 +7527,7 @@
 
        /* we no longer need broadcast tlb flushes for this pmap. */
        PMAP_CLR_CPUSET(pm, &cpuinfo);
-       PMAP_UNLOCK();
+       mutex_spin_exit(&ctx_lock);
 }
 
 #ifdef DEBUG



Home | Main Index | Thread Index | Old Index