summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2011-01-04 15:55:15 +0000
committercperciva <cperciva@FreeBSD.org>2011-01-04 15:55:15 +0000
commit1b29205c00bce60716d42457eade3832205e1719 (patch)
tree636f71b07c63ac5a49bed7a5e02f14451dbbe42f
parentb5469e8b581b388e373b5a39d23cc88058622db2 (diff)
downloadFreeBSD-src-1b29205c00bce60716d42457eade3832205e1719.zip
FreeBSD-src-1b29205c00bce60716d42457eade3832205e1719.tar.gz
Add hamfisted locking to the Xen/PV pmap code: Only allow one thread to
be in {pmap_pinit, pmap_copy, pmap_release} at a time. This reduces the rate of panics when running 'make index' from ~0.6/hour to ~0.02/hour (p < 10^-30). At a later date this locking will be removed, and for this reason, it is wrapped in #ifdef HAMFISTED_LOCKING; this temporary hack is being put in place with the intention of shipping somewhat-stable Xen bits in FreeBSD 8.2-RELEASE. PR: kern/153672 MFC after: 3 days
-rw-r--r--sys/i386/xen/pmap.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index e91ebaf..4416f1b 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -202,6 +202,11 @@ __FBSDID("$FreeBSD$");
#define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
+#define HAMFISTED_LOCKING
+#ifdef HAMFISTED_LOCKING
+static struct mtx createdelete_lock;
+#endif
+
struct pmap kernel_pmap_store;
LIST_HEAD(pmaplist, pmap);
static struct pmaplist allpmaps;
@@ -502,6 +507,10 @@ pmap_bootstrap(vm_paddr_t firstaddr)
/* Turn on PG_G on kernel page(s) */
pmap_set_pg();
#endif
+
+#ifdef HAMFISTED_LOCKING
+ mtx_init(&createdelete_lock, "pmap create/delete", NULL, MTX_DEF);
+#endif
}
/*
@@ -1462,6 +1471,10 @@ pmap_pinit(pmap_t pmap)
static int color;
int i;
+#ifdef HAMFISTED_LOCKING
+ mtx_lock(&createdelete_lock);
+#endif
+
PMAP_LOCK_INIT(pmap);
/*
@@ -1473,6 +1486,9 @@ pmap_pinit(pmap_t pmap)
NBPTD);
if (pmap->pm_pdir == NULL) {
PMAP_LOCK_DESTROY(pmap);
+#ifdef HAMFISTED_LOCKING
+ mtx_unlock(&createdelete_lock);
+#endif
return (0);
}
#ifdef PAE
@@ -1545,6 +1561,9 @@ pmap_pinit(pmap_t pmap)
TAILQ_INIT(&pmap->pm_pvchunk);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+#ifdef HAMFISTED_LOCKING
+ mtx_unlock(&createdelete_lock);
+#endif
return (1);
}
@@ -1776,6 +1795,10 @@ pmap_release(pmap_t pmap)
pmap->pm_stats.resident_count));
PT_UPDATES_FLUSH();
+#ifdef HAMFISTED_LOCKING
+ mtx_lock(&createdelete_lock);
+#endif
+
pmap_lazyfix(pmap);
mtx_lock_spin(&allpmaps_lock);
LIST_REMOVE(pmap, pm_list);
@@ -1811,6 +1834,10 @@ pmap_release(pmap_t pmap)
pmap_qremove((vm_offset_t)pmap->pm_pdpt, 1);
#endif
PMAP_LOCK_DESTROY(pmap);
+
+#ifdef HAMFISTED_LOCKING
+ mtx_unlock(&createdelete_lock);
+#endif
}
static int
@@ -3136,6 +3163,10 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
CTR5(KTR_PMAP, "pmap_copy: dst_pmap=%p src_pmap=%p dst_addr=0x%x len=%d src_addr=0x%x",
dst_pmap, src_pmap, dst_addr, len, src_addr);
+#ifdef HAMFISTED_LOCKING
+ mtx_lock(&createdelete_lock);
+#endif
+
vm_page_lock_queues();
if (dst_pmap < src_pmap) {
PMAP_LOCK(dst_pmap);
@@ -3225,6 +3256,10 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
vm_page_unlock_queues();
PMAP_UNLOCK(src_pmap);
PMAP_UNLOCK(dst_pmap);
+
+#ifdef HAMFISTED_LOCKING
+ mtx_unlock(&createdelete_lock);
+#endif
}
static __inline void
OpenPOWER on IntegriCloud