diff options
author | alc <alc@FreeBSD.org> | 2007-07-01 07:08:26 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2007-07-01 07:08:26 +0000 |
commit | bc9594202b8807b4954908449530395b5dcfdaa4 (patch) | |
tree | f9838587f7565aec8c043a00539ed5d038bfe4d4 /sys/i386 | |
parent | 3b857ba02730954f8d406d9aeed2c611eab22cbc (diff) | |
download | FreeBSD-src-bc9594202b8807b4954908449530395b5dcfdaa4.zip FreeBSD-src-bc9594202b8807b4954908449530395b5dcfdaa4.tar.gz |
Pages that do belong to an object and page queue can now be freed without
holding the page queues lock. Thus, the page table pages released by
pmap_remove() and pmap_remove_pages() can be freed after the page queues
lock is released.
Approved by: re (kensmith)
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/pmap.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 01b2422..420936d 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -271,7 +271,8 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte); static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva, vm_page_t *free); -static void pmap_remove_page(struct pmap *pmap, vm_offset_t va); +static void pmap_remove_page(struct pmap *pmap, vm_offset_t va, + vm_page_t *free); static void pmap_remove_entry(struct pmap *pmap, vm_page_t m, vm_offset_t va); static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); @@ -1987,19 +1988,17 @@ pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va, vm_page_t *free) * Remove a single page from a process address space */ static void -pmap_remove_page(pmap_t pmap, vm_offset_t va) +pmap_remove_page(pmap_t pmap, vm_offset_t va, vm_page_t *free) { pt_entry_t *pte; - vm_page_t free = NULL; mtx_assert(&vm_page_queue_mtx, MA_OWNED); KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); PMAP_LOCK_ASSERT(pmap, MA_OWNED); if ((pte = pmap_pte_quick(pmap, va)) == NULL || *pte == 0) return; - pmap_remove_pte(pmap, pte, va, &free); + pmap_remove_pte(pmap, pte, va, free); pmap_invalidate_page(pmap, va); - pmap_free_zero_pages(free); } /* @@ -2036,7 +2035,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) */ if ((sva + PAGE_SIZE == eva) && ((pmap->pm_pdir[(sva >> PDRSHIFT)] & PG_PS) == 0)) { - pmap_remove_page(pmap, sva); + pmap_remove_page(pmap, sva, &free); goto out; } @@ -2095,12 +2094,11 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) } out: sched_unpin(); - if (anyvalid) { + if (anyvalid) pmap_invalidate_all(pmap); - pmap_free_zero_pages(free); - } vm_page_unlock_queues(); PMAP_UNLOCK(pmap); + pmap_free_zero_pages(free); } /* @@ -3119,9 +3117,9 @@ pmap_remove_pages(pmap_t pmap) } sched_unpin(); pmap_invalidate_all(pmap); - pmap_free_zero_pages(free); vm_page_unlock_queues(); PMAP_UNLOCK(pmap); + pmap_free_zero_pages(free); } /* |