summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-04-19 16:15:42 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-04-19 16:15:42 +0000
commitcc0f91b0228b9cd0c517eabd6655c9b953bd0968 (patch)
treea57f0f10bbc232242d6d86c617907aa2bdb1a553 /sys/arch
parent1e15bf2bebd5ef66a6bedf8a6e63fbbb9d270488 (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.c34
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);
+ }
}
/*