diff options
| author | ad <ad@NetBSD.org> | 2008-03-10 13:36:22 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2008-03-10 13:36:22 +0000 |
| commit | 8228d024b77bbc4e5467e02c7f1c0bc239d630d8 (patch) | |
| tree | d1745bbad13234a1678997591da1b6394b76b0e9 /sys | |
| parent | ee76f56f7043ab793e5d63ef84cc9526a0194347 (diff) | |
Use atomics to maintain the number of special page references. Should fix
locking problems including in revision 1.232.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/alpha/alpha/pmap.c | 52 | ||||
| -rw-r--r-- | sys/arch/alpha/include/vmparam.h | 4 |
2 files changed, 13 insertions, 43 deletions
diff --git a/sys/arch/alpha/alpha/pmap.c b/sys/arch/alpha/alpha/pmap.c index 24102b6a56a..30b3ff908ac 100644 --- a/sys/arch/alpha/alpha/pmap.c +++ b/sys/arch/alpha/alpha/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.232 2008/02/21 17:12:58 ad Exp $ */ +/* $NetBSD: pmap.c,v 1.233 2008/03/10 13:36:22 ad Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001, 2007, 2008 The NetBSD Foundation, Inc. @@ -147,7 +147,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.232 2008/02/21 17:12:58 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.233 2008/03/10 13:36:22 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -2998,9 +2998,6 @@ pmap_physpage_alloc(int usage, paddr_t *pap) { struct vm_page *pg; paddr_t pa; -#ifdef DEBUG - kmutex_t *lock; -#endif /* * Don't ask for a zero'd page in the L1PT case -- we will @@ -3011,16 +3008,12 @@ pmap_physpage_alloc(int usage, paddr_t *pap) UVM_PGA_USERESERVE : UVM_PGA_USERESERVE|UVM_PGA_ZERO); if (pg != NULL) { pa = VM_PAGE_TO_PHYS(pg); - #ifdef DEBUG - lock = pmap_pvh_lock(pg); - mutex_enter(lock); - if (pg->wire_count != 0) { + if (pg->mdpage.pvh_refcnt != 0) { printf("pmap_physpage_alloc: page 0x%lx has " - "%d references\n", pa, pg->wire_count); + "%d references\n", pa, pg->mdpage.pvh_refcnt); panic("pmap_physpage_alloc"); } - mutex_exit(lock); #endif *pap = pa; return (true); @@ -3042,13 +3035,8 @@ pmap_physpage_free(paddr_t pa) panic("pmap_physpage_free: bogus physical page address"); #ifdef DEBUG - { - kmutex_t *lock = pmap_pvh_lock(pg); - mutex_enter(lock); - if (pg->wire_count != 0) - panic("pmap_physpage_free: page still has references"); - mutex_exit(lock); - } + if (pg->mdpage.pvh_refcnt != 0) + panic("pmap_physpage_free: page still has references"); #endif uvm_pagefree(pg); @@ -3064,18 +3052,13 @@ pmap_physpage_addref(void *kva) { struct vm_page *pg; paddr_t pa; - int rval; - kmutex_t *lock; pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva)); pg = PHYS_TO_VM_PAGE(pa); - lock = pmap_pvh_lock(pg); - mutex_enter(lock); - rval = ++pg->wire_count; - mutex_exit(lock); + KASSERT((int)pg->mdpage.pvh_refcnt >= 0); - return (rval); + return atomic_inc_uint_nv(&pg->mdpage.pvh_refcnt); } /* @@ -3088,28 +3071,13 @@ pmap_physpage_delref(void *kva) { struct vm_page *pg; paddr_t pa; - int rval; - kmutex_t *lock; pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva)); pg = PHYS_TO_VM_PAGE(pa); - lock = pmap_pvh_lock(pg); - mutex_enter(lock); - -#ifdef DIAGNOSTIC - /* - * Make sure we never have a negative reference count. - */ - if (pg->wire_count == 0) - panic("pmap_physpage_delref: reference count already zero"); -#endif - - rval = --pg->wire_count; - - mutex_exit(lock); + KASSERT((int)pg->mdpage.pvh_refcnt > 0); - return (rval); + return atomic_dec_uint_nv(&pg->mdpage.pvh_refcnt); } /******************** page table page management ********************/ diff --git a/sys/arch/alpha/include/vmparam.h b/sys/arch/alpha/include/vmparam.h index 082c14f310d..7ad1996db77 100644 --- a/sys/arch/alpha/include/vmparam.h +++ b/sys/arch/alpha/include/vmparam.h @@ -1,4 +1,4 @@ -/* $NetBSD: vmparam.h,v 1.31 2008/02/21 17:12:58 ad Exp $ */ +/* $NetBSD: vmparam.h,v 1.32 2008/03/10 13:36:22 ad Exp $ */ /* * Copyright (c) 1992, 1993 @@ -167,11 +167,13 @@ struct vm_page_md { struct pv_entry *pvh_list; /* pv_entry list */ int pvh_attrs; /* page attributes */ + unsigned pvh_refcnt; }; #define VM_MDPAGE_INIT(pg) \ do { \ (pg)->mdpage.pvh_list = NULL; \ + (pg)->mdpage.pvh_refcnt = 0; \ } while (/*CONSTCOND*/0) #endif /* ! _ALPHA_VMPARAM_H_ */ |
