diff options
author | cperciva <cperciva@FreeBSD.org> | 2011-01-04 15:55:15 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2011-01-04 15:55:15 +0000 |
commit | 1b29205c00bce60716d42457eade3832205e1719 (patch) | |
tree | 636f71b07c63ac5a49bed7a5e02f14451dbbe42f /sys/i386/xen/pmap.c | |
parent | b5469e8b581b388e373b5a39d23cc88058622db2 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/i386/xen/pmap.c')
-rw-r--r-- | sys/i386/xen/pmap.c | 35 |
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 |