From owner-p4-projects@FreeBSD.ORG Mon Oct 31 21:40:27 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4CE1316A44F; Mon, 31 Oct 2005 21:40:26 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0743916A446 for ; Mon, 31 Oct 2005 21:40:26 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id B0F6543D45 for ; Mon, 31 Oct 2005 21:40:25 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j9VLePi5087975 for ; Mon, 31 Oct 2005 21:40:25 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j9VLePbh087971 for perforce@freebsd.org; Mon, 31 Oct 2005 21:40:25 GMT (envelope-from jhb@freebsd.org) Date: Mon, 31 Oct 2005 21:40:25 GMT Message-Id: <200510312140.j9VLePbh087971@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 86139 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Oct 2005 21:40:27 -0000 http://perforce.freebsd.org/chv.cgi?CH=86139 Change 86139 by jhb@jhb_slimer on 2005/10/31 21:40:01 IFC @86136. Affected files ... .. //depot/projects/smpng/sys/amd64/amd64/pmap.c#48 integrate .. //depot/projects/smpng/sys/boot/i386/loader/loader.rc#4 branch .. //depot/projects/smpng/sys/i386/i386/pmap.c#88 integrate Differences ... ==== //depot/projects/smpng/sys/amd64/amd64/pmap.c#48 (text+ko) ==== @@ -77,7 +77,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.530 2005/10/30 20:47:42 alc Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.531 2005/10/31 21:25:33 alc Exp $"); /* * Manages physical address maps. @@ -203,6 +203,7 @@ static PMAP_INLINE void free_pv_entry(pv_entry_t pv); static pv_entry_t get_pv_entry(void); +static pv_entry_t pv_entry_reclaim(pmap_t locked_pmap); static void pmap_clear_ptes(vm_page_t m, long bit); static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, @@ -1450,6 +1451,57 @@ return uma_zalloc(pvzone, M_NOWAIT); } +/* + * Reclaim a pv entry by removing a mapping to an inactive page. + */ +static pv_entry_t +pv_entry_reclaim(pmap_t locked_pmap) +{ + pd_entry_t ptepde; + pmap_t pmap; + pt_entry_t *pte, tpte; + pv_entry_t pv; + vm_offset_t va; + vm_page_t m; + + PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + TAILQ_FOREACH(m, &vm_page_queues[PQ_INACTIVE].pl, pageq) { + if (m->hold_count || m->busy || (m->flags & PG_BUSY)) + continue; + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + va = pv->pv_va; + pmap = pv->pv_pmap; + if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap)) + continue; + pmap->pm_stats.resident_count--; + pte = pmap_pte_pde(pmap, va, &ptepde); + tpte = pte_load_clear(pte); + KASSERT((tpte & PG_W) == 0, + ("pv_entry_reclaim: wired pte %#lx", tpte)); + if (tpte & PG_A) + vm_page_flag_set(m, PG_REFERENCED); + if (tpte & PG_M) { + KASSERT((tpte & PG_RW), + ("pv_entry_reclaim: modified page not writable: va: %#lx, pte: %#lx", + va, tpte)); + if (pmap_track_modified(va)) + vm_page_dirty(m); + } + pmap_invalidate_page(pmap, va); + TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist); + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + if (TAILQ_EMPTY(&m->md.pv_list)) + vm_page_flag_clear(m, PG_WRITEABLE); + m->md.pv_list_count--; + pmap_unuse_pt(pmap, va, ptepde); + if (pmap != locked_pmap) + PMAP_UNLOCK(pmap); + return (pv); + } + } + panic("pv_entry_reclaim: increase vm.pmap.shpgperproc"); +} static void pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va) @@ -1488,8 +1540,10 @@ pv_entry_t pv; pv = get_pv_entry(); - if (pv == NULL) - panic("no pv entries: increase vm.pmap.shpgperproc"); + if (pv == NULL) { + pv_entry_count--; + pv = pv_entry_reclaim(pmap); + } pv->pv_va = va; pv->pv_pmap = pmap; @@ -1524,7 +1578,7 @@ m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME); if (oldpte & PG_M) { KASSERT((oldpte & PG_RW), - ("pmap_remove_pte: modified page not writable: va: 0x%lx, pte: 0x%lx", + ("pmap_remove_pte: modified page not writable: va: %#lx, pte: %#lx", va, oldpte)); if (pmap_track_modified(va)) vm_page_dirty(m); @@ -1705,7 +1759,7 @@ */ if (tpte & PG_M) { KASSERT((tpte & PG_RW), - ("pmap_remove_all: modified page not writable: va: 0x%lx, pte: 0x%lx", + ("pmap_remove_all: modified page not writable: va: %#lx, pte: %#lx", pv->pv_va, tpte)); if (pmap_track_modified(pv->pv_va)) vm_page_dirty(m); @@ -1993,7 +2047,7 @@ } if (origpte & PG_M) { KASSERT((origpte & PG_RW), - ("pmap_enter: modified page not writable: va: 0x%lx, pte: 0x%lx", + ("pmap_enter: modified page not writable: va: %#lx, pte: %#lx", va, origpte)); if ((origpte & PG_MANAGED) && pmap_track_modified(va)) ==== //depot/projects/smpng/sys/i386/i386/pmap.c#88 (text+ko) ==== @@ -75,7 +75,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/i386/i386/pmap.c,v 1.534 2005/10/30 20:47:42 alc Exp $"); +__FBSDID("$FreeBSD: src/sys/i386/i386/pmap.c,v 1.535 2005/10/31 21:25:33 alc Exp $"); /* * Manages physical address maps. @@ -253,6 +253,7 @@ static PMAP_INLINE void free_pv_entry(pv_entry_t pv); static pv_entry_t get_pv_entry(void); +static pv_entry_t pv_entry_reclaim(pmap_t locked_pmap); static void pmap_clear_ptes(vm_page_t m, int bit); static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva); @@ -1454,7 +1455,61 @@ return uma_zalloc(pvzone, M_NOWAIT); } +/* + * Reclaim a pv entry by removing a mapping to an inactive page. + */ +static pv_entry_t +pv_entry_reclaim(pmap_t locked_pmap) +{ + pmap_t pmap; + pt_entry_t *pte, tpte; + pv_entry_t pv; + vm_offset_t va; + vm_page_t m; + PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + sched_pin(); + TAILQ_FOREACH(m, &vm_page_queues[PQ_INACTIVE].pl, pageq) { + if (m->hold_count || m->busy || (m->flags & PG_BUSY)) + continue; + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + va = pv->pv_va; + pmap = pv->pv_pmap; + if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap)) + continue; + pmap->pm_stats.resident_count--; + pte = pmap_pte_quick(pmap, va); + tpte = pte_load_clear(pte); + KASSERT((tpte & PG_W) == 0, + ("pv_entry_reclaim: wired pte %#jx", + (uintmax_t)tpte)); + if (tpte & PG_A) + vm_page_flag_set(m, PG_REFERENCED); + if (tpte & PG_M) { + KASSERT((tpte & PG_RW), + ("pv_entry_reclaim: modified page not writable: va: %#x, pte: %#jx", + va, (uintmax_t)tpte)); + if (pmap_track_modified(va)) + vm_page_dirty(m); + } + pmap_invalidate_page(pmap, va); + TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist); + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + if (TAILQ_EMPTY(&m->md.pv_list)) + vm_page_flag_clear(m, PG_WRITEABLE); + m->md.pv_list_count--; + pmap_unuse_pt(pmap, va); + if (pmap != locked_pmap) + PMAP_UNLOCK(pmap); + sched_unpin(); + return (pv); + } + } + sched_unpin(); + panic("pv_entry_reclaim: increase vm.pmap.shpgperproc"); +} + static void pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va) { @@ -1492,8 +1547,10 @@ pv_entry_t pv; pv = get_pv_entry(); - if (pv == NULL) - panic("no pv entries: increase vm.pmap.shpgperproc"); + if (pv == NULL) { + pv_entry_count--; + pv = pv_entry_reclaim(pmap); + } pv->pv_va = va; pv->pv_pmap = pmap; @@ -1529,8 +1586,8 @@ m = PHYS_TO_VM_PAGE(oldpte); if (oldpte & PG_M) { KASSERT((oldpte & PG_RW), - ("pmap_remove_pte: modified page not writable: va: 0x%x, pte: 0x%x", - va, oldpte)); + ("pmap_remove_pte: modified page not writable: va: %#x, pte: %#jx", + va, (uintmax_t)oldpte)); if (pmap_track_modified(va)) vm_page_dirty(m); } @@ -1695,8 +1752,8 @@ */ if (tpte & PG_M) { KASSERT((tpte & PG_RW), - ("pmap_remove_all: modified page not writable: va: 0x%x, pte: 0x%x", - pv->pv_va, tpte)); + ("pmap_remove_all: modified page not writable: va: %#x, pte: %#jx", + pv->pv_va, (uintmax_t)tpte)); if (pmap_track_modified(pv->pv_va)) vm_page_dirty(m); } @@ -1985,8 +2042,8 @@ } if (origpte & PG_M) { KASSERT((origpte & PG_RW), - ("pmap_enter: modified page not writable: va: 0x%x, pte: 0x%x", - va, origpte)); + ("pmap_enter: modified page not writable: va: %#x, pte: %#jx", + va, (uintmax_t)origpte)); if ((origpte & PG_MANAGED) && pmap_track_modified(va)) vm_page_dirty(om);