diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2007-04-19 16:15:42 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2007-04-19 16:15:42 +0000 |
commit | cc0f91b0228b9cd0c517eabd6655c9b953bd0968 (patch) | |
tree | a57f0f10bbc232242d6d86c617907aa2bdb1a553 /sys/arch | |
parent | 1e15bf2bebd5ef66a6bedf8a6e63fbbb9d270488 (diff) |
Do the late freeing of ptps in pae pmap as well.
From mickey.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/pmapae.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/sys/arch/i386/i386/pmapae.c b/sys/arch/i386/i386/pmapae.c index 982be0bbeba..35848230f70 100644 --- a/sys/arch/i386/i386/pmapae.c +++ b/sys/arch/i386/i386/pmapae.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmapae.c,v 1.11 2007/04/13 18:57:49 art Exp $ */ +/* $OpenBSD: pmapae.c,v 1.12 2007/04/19 16:15:41 art Exp $ */ /* * Copyright (c) 2006 Michael Shalayeff @@ -1373,11 +1373,14 @@ pmap_remove_pae(struct pmap *pmap, vaddr_t sva, vaddr_t eva) vaddr_t blkendva; struct vm_page *ptp; int32_t cpumask = 0; + TAILQ_HEAD(, vm_page) empty_ptps; /* * we lock in the pmap => pv_head direction */ + TAILQ_INIT(&empty_ptps); + PMAP_MAP_TO_HEAD_LOCK(); ptes = pmap_map_ptes_pae(pmap); /* locks pmap */ /* @@ -1449,12 +1452,18 @@ pmap_remove_pae(struct pmap *pmap, vaddr_t sva, vaddr_t eva) pmap->pm_ptphint = TAILQ_FIRST(&pmap->pm_obj.memq); ptp->wire_count = 0; - uvm_pagefree(ptp); + /* Postpone free to after shootdown. */ + uvm_pagerealloc(ptp, NULL, 0); + TAILQ_INSERT_TAIL(&empty_ptps, ptp, listq); } } pmap_tlb_shootnow(cpumask); pmap_unmap_ptes_pae(pmap); /* unlock pmap */ PMAP_MAP_TO_HEAD_UNLOCK(); + while ((ptp = TAILQ_FIRST(&empty_ptps)) != NULL) { + TAILQ_REMOVE(&empty_ptps, ptp, listq); + uvm_pagefree(ptp); + } return; } @@ -1536,13 +1545,19 @@ pmap_remove_pae(struct pmap *pmap, vaddr_t sva, vaddr_t eva) pmap->pm_ptphint = TAILQ_FIRST(&pmap->pm_obj.memq); ptp->wire_count = 0; - uvm_pagefree(ptp); + /* Postpone free to after shootdown. */ + uvm_pagerealloc(ptp, NULL, 0); + TAILQ_INSERT_TAIL(&empty_ptps, ptp, listq); } } pmap_tlb_shootnow(cpumask); pmap_unmap_ptes_pae(pmap); PMAP_MAP_TO_HEAD_UNLOCK(); + while ((ptp = TAILQ_FIRST(&empty_ptps)) != NULL) { + TAILQ_REMOVE(&empty_ptps, ptp, listq); + uvm_pagefree(ptp); + } } /* @@ -1560,6 +1575,8 @@ pmap_page_remove_pae(struct vm_page *pg) struct pv_entry *pve; pt_entry_t *ptes, opte; int32_t cpumask = 0; + TAILQ_HEAD(, vm_page) empty_ptps; + struct vm_page *ptp; /* XXX: vm_page should either contain pv_head or have a pointer to it */ bank = vm_physseg_find(atop(VM_PAGE_TO_PHYS(pg)), &off); @@ -1573,6 +1590,8 @@ pmap_page_remove_pae(struct vm_page *pg) return; } + TAILQ_INIT(&empty_ptps); + /* set pv_head => pmap locking */ PMAP_HEAD_TO_MAP_LOCK(); @@ -1646,7 +1665,10 @@ pmap_page_remove_pae(struct vm_page *pg) pve->pv_pmap->pm_ptphint = TAILQ_FIRST(&pve->pv_pmap->pm_obj.memq); pve->pv_ptp->wire_count = 0; - uvm_pagefree(pve->pv_ptp); + /* Postpone free to after shootdown. */ + uvm_pagerealloc(pve->pv_ptp, NULL, 0); + TAILQ_INSERT_TAIL(&empty_ptps, pve->pv_ptp, + listq); } } pmap_unmap_ptes_pae(pve->pv_pmap); /* unlocks pmap */ @@ -1656,6 +1678,10 @@ pmap_page_remove_pae(struct vm_page *pg) simple_unlock(&pvh->pvh_lock); PMAP_HEAD_TO_MAP_UNLOCK(); pmap_tlb_shootnow(cpumask); + while ((ptp = TAILQ_FIRST(&empty_ptps)) != NULL) { + TAILQ_REMOVE(&empty_ptps, ptp, listq); + uvm_pagefree(ptp); + } } /* |