Date: Sat, 08 Sep 2012 19:01:26 -0500 From: Alan Cox <alc@rice.edu> To: "arm@freebsd.org" <arm@freebsd.org> Cc: Alan Cox <alc@rice.edu> Subject: armv6 pmap patch Message-ID: <504BDC56.3060607@rice.edu>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------060005020600030203000200 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Can someone here please test this patch to the new armv6 pmap? It eliminates the use of the page queues lock and updates some comments. Similar changes were recently made to the original arm pmap. Thanks, Alan --------------060005020600030203000200 Content-Type: text/plain; name="armv6-pmap2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="armv6-pmap2.patch" Index: arm/arm/pmap-v6.c =================================================================== --- arm/arm/pmap-v6.c (revision 240246) +++ arm/arm/pmap-v6.c (working copy) @@ -153,10 +153,12 @@ __FBSDID("$FreeBSD$"); #include <sys/msgbuf.h> #include <sys/vmmeter.h> #include <sys/mman.h> +#include <sys/rwlock.h> #include <sys/smp.h> #include <sys/sched.h> #include <vm/vm.h> +#include <vm/vm_param.h> #include <vm/uma.h> #include <vm/pmap.h> #include <vm/vm_kern.h> @@ -164,12 +166,10 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_map.h> #include <vm/vm_page.h> #include <vm/vm_pageout.h> -#include <vm/vm_param.h> #include <vm/vm_extern.h> #include <sys/lock.h> #include <sys/mutex.h> #include <machine/md_var.h> -#include <machine/vmparam.h> #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/pcb.h> @@ -400,6 +400,7 @@ static vm_offset_t pmap_kernel_l2ptp_kva; static vm_paddr_t pmap_kernel_l2ptp_phys; static struct vm_object pvzone_obj; static int pv_entry_count=0, pv_entry_max=0, pv_entry_high_water=0; +static struct rwlock pvh_global_lock; int l1_mem_types[] = { ARM_L1S_STRONG_ORD, @@ -613,7 +614,7 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va) l1idx = L1_IDX(va); PMAP_ASSERT_LOCKED(pm); - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL) { /* * No mapping at this address, as there is @@ -622,19 +623,19 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va) */ again_l2table: PMAP_UNLOCK(pm); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); if ((l2 = pmap_alloc_l2_dtable()) == NULL) { - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); return (NULL); } - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); if (pm->pm_l2[L2_IDX(l1idx)] != NULL) { PMAP_UNLOCK(pm); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); uma_zfree(l2table_zone, l2); - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); l2 = pm->pm_l2[L2_IDX(l1idx)]; if (l2 == NULL) @@ -666,16 +667,16 @@ again_l2table: */ again_ptep: PMAP_UNLOCK(pm); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); ptep = (void*)uma_zalloc(l2zone, M_NOWAIT|M_USE_RESERVE); - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); if (l2b->l2b_kva != 0) { /* We lost the race. */ PMAP_UNLOCK(pm); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); uma_zfree(l2zone, ptep); - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); if (l2b->l2b_kva == 0) goto again_ptep; @@ -851,7 +852,7 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits) u_int oflags; int count = 0; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); if (maskbits & PVF_WRITE) maskbits |= PVF_MOD; @@ -861,7 +862,7 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits) pg->md.pvh_attrs &= ~(maskbits & (PVF_MOD | PVF_REF)); if (TAILQ_EMPTY(&pg->md.pv_list)) { - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); return (0); } @@ -917,7 +918,7 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits) if (maskbits & PVF_WRITE) vm_page_aflag_clear(pg, PGA_WRITEABLE); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); return (count); } @@ -927,15 +928,15 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits) * pmap_remove_pv: remove a mappiing from a vm_page list * * NOTE: pmap_enter_pv expects to lock the pvh itself - * pmap_remove_pv expects te caller to lock the pvh before calling + * pmap_remove_pv expects the caller to lock the pvh before calling */ /* - * pmap_enter_pv: enter a mapping onto a vm_page lst + * pmap_enter_pv: enter a mapping onto a vm_page's PV list * - * => caller should hold the proper lock on pmap_main_lock + * => caller should hold the proper lock on pvh_global_lock * => caller should have pmap locked - * => we will gain the lock on the vm_page and allocate the new pv_entry + * => we will (someday) gain the lock on the vm_page's PV list * => caller should adjust ptp's wire_count before calling * => caller should not adjust pmap's wire_count */ @@ -944,7 +945,7 @@ pmap_enter_pv(struct vm_page *pg, struct pv_entry vm_offset_t va, u_int flags) { - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); PMAP_ASSERT_LOCKED(pm); pve->pv_pmap = pm; @@ -970,7 +971,7 @@ pmap_find_pv(struct vm_page *pg, pmap_t pm, vm_off { struct pv_entry *pv; - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) if (pm == pv->pv_pmap && va == pv->pv_va) break; @@ -1031,7 +1032,7 @@ static void pmap_nuke_pv(struct vm_page *pg, pmap_t pm, struct pv_entry *pve) { - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); PMAP_ASSERT_LOCKED(pm); TAILQ_REMOVE(&pg->md.pv_list, pve, pv_list); @@ -1064,7 +1065,7 @@ pmap_remove_pv(struct vm_page *pg, pmap_t pm, vm_o { struct pv_entry *pve; - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); pve = TAILQ_FIRST(&pg->md.pv_list); while (pve) { @@ -1096,7 +1097,7 @@ pmap_modify_pv(struct vm_page *pg, pmap_t pm, vm_o u_int flags, oflags; PMAP_ASSERT_LOCKED(pm); - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); if ((npv = pmap_find_pv(pg, pm, va)) == NULL) return (0); @@ -1210,7 +1211,7 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t va, vm_pro int rv = 0; l1idx = L1_IDX(va); - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); /* @@ -1374,7 +1375,7 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t va, vm_pro rv = 1; out: - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pm); return (rv); } @@ -1682,6 +1683,11 @@ pmap_bootstrap(vm_offset_t firstaddr, vm_offset_t TAILQ_INIT(&kernel_pmap->pm_pvlist); /* + * Initialize the global pv list lock. + */ + rw_init_flags(&pvh_global_lock, "pmap pv global", RW_RECURSE); + + /* * Reserve some special page table entries/VA space for temporary * mapping of pages. */ @@ -1946,7 +1952,7 @@ pmap_remove_pages(pmap_t pmap) vm_page_t m; pt_entry_t *pt; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) { if (pv->pv_flags & PVF_WIRED) { @@ -1969,7 +1975,7 @@ pmap_remove_pages(pmap_t pmap) pmap_free_pv_entry(pv); pmap_free_l2_bucket(pmap, l2b, 1); } - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); cpu_tlb_flushID(); cpu_cpwait(); PMAP_UNLOCK(pmap); @@ -2326,7 +2332,7 @@ pmap_remove_all(vm_page_t m) if (TAILQ_EMPTY(&m->md.pv_list)) return; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); pmap_remove_write(m); curpm = vmspace_pmap(curproc->p_vmspace); while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { @@ -2356,7 +2362,7 @@ pmap_remove_all(vm_page_t m) cpu_tlb_flushD(); } vm_page_aflag_clear(m, PGA_WRITEABLE); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); } int @@ -2444,7 +2450,7 @@ pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset return; } - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); /* @@ -2506,7 +2512,7 @@ pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset if (PV_BEEN_REFD(flags)) cpu_tlb_flushD(); } - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pm); } @@ -2530,11 +2536,11 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t vm_prot_t prot, boolean_t wired) { - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); pmap_enter_locked(pmap, va, m, prot, wired, M_WAITOK); PMAP_UNLOCK(pmap); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); } /* @@ -2554,7 +2560,7 @@ pmap_enter_locked(pmap_t pmap, vm_offset_t va, vm_ u_char user; PMAP_ASSERT_LOCKED(pmap); - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + rw_assert(&pvh_global_lock, RA_WLOCKED); if (va == vector_page) { pa = systempage.pv_pa; m = NULL; @@ -2594,9 +2600,9 @@ do_l2b_alloc: if (l2b == NULL) { if (flags & M_WAITOK) { PMAP_UNLOCK(pmap); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); VM_WAIT; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); goto do_l2b_alloc; } @@ -2789,7 +2795,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, psize = atop(end - start); m = m_start; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) { pmap_enter_locked(pmap, start + ptoa(diff), m, prot & @@ -2797,7 +2803,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, m = TAILQ_NEXT(m, listq); } PMAP_UNLOCK(pmap); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); } /* @@ -2813,12 +2819,12 @@ void pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) { - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); pmap_enter_locked(pmap, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE, M_NOWAIT); PMAP_UNLOCK(pmap); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); } /* @@ -2835,7 +2841,7 @@ pmap_change_wiring(pmap_t pmap, vm_offset_t va, bo pt_entry_t *ptep, pte; vm_page_t pg; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); l2b = pmap_get_l2_bucket(pmap, va); KASSERT(l2b, ("No l2b bucket in pmap_change_wiring")); @@ -2844,7 +2850,7 @@ pmap_change_wiring(pmap_t pmap, vm_offset_t va, bo pg = PHYS_TO_VM_PAGE(l2pte_pa(pte)); if (pg) pmap_modify_pv(pg, pmap, va, PVF_WIRED, wired); - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pmap); } @@ -3091,7 +3097,7 @@ pmap_remove(pmap_t pm, vm_offset_t sva, vm_offset_ * we lock in the pmap => pv_head direction */ - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); PMAP_LOCK(pm); total = 0; while (sva < eva) { @@ -3170,7 +3176,7 @@ pmap_remove(pmap_t pm, vm_offset_t sva, vm_offset_ pmap_free_l2_bucket(pm, l2b, mappings); } - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); if (flushall) cpu_tlb_flushID(); PMAP_UNLOCK(pm); @@ -3323,7 +3329,7 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_page_exists_quick: page %p is not managed", m)); rv = FALSE; - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { if (pv->pv_pmap == pmap) { rv = TRUE; @@ -3334,7 +3340,7 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m) break; } - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); return (rv); } @@ -3353,11 +3359,11 @@ pmap_page_wired_mappings(vm_page_t m) count = 0; if ((m->flags & PG_FICTITIOUS) != 0) return (count); - vm_page_lock_queues(); + rw_wlock(&pvh_global_lock); TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) if ((pv->pv_flags & PVF_WIRED) != 0) count++; - vm_page_unlock_queues(); + rw_wunlock(&pvh_global_lock); return (count); } --------------060005020600030203000200--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?504BDC56.3060607>