Date: Sat, 19 Jun 2010 19:45:09 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r209352 - projects/ppc64/sys/powerpc/aim Message-ID: <201006191945.o5JJj99T077114@svn.freebsd.org>
index | next in thread | raw e-mail
Author: nwhitehorn Date: Sat Jun 19 19:45:08 2010 New Revision: 209352 URL: http://svn.freebsd.org/changeset/base/209352 Log: The VM tells us which pages are wired, we don't need to wire the whole kernel against PTE spills. Suggested by: mdf Modified: projects/ppc64/sys/powerpc/aim/mmu_oea64.c Modified: projects/ppc64/sys/powerpc/aim/mmu_oea64.c ============================================================================== --- projects/ppc64/sys/powerpc/aim/mmu_oea64.c Sat Jun 19 19:09:08 2010 (r209351) +++ projects/ppc64/sys/powerpc/aim/mmu_oea64.c Sat Jun 19 19:45:08 2010 (r209352) @@ -1312,20 +1312,52 @@ void moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired) { struct pvo_entry *pvo; + struct lpte *pt; + uint64_t vsid; + int i, ptegidx; PMAP_LOCK(pm); pvo = moea64_pvo_find_va(pm, va & ~ADDR_POFF, NULL); if (pvo != NULL) { + LOCK_TABLE(); + pt = moea64_pvo_to_pte(pvo, -1); + if (pt != NULL) + moea64_pte_synch(pt, &pvo->pvo_pte.lpte); + if (wired) { if ((pvo->pvo_vaddr & PVO_WIRED) == 0) pm->pm_stats.wired_count++; pvo->pvo_vaddr |= PVO_WIRED; + pvo->pvo_pte.lpte.pte_hi |= LPTE_WIRED; } else { if ((pvo->pvo_vaddr & PVO_WIRED) != 0) pm->pm_stats.wired_count--; pvo->pvo_vaddr &= ~PVO_WIRED; + pvo->pvo_pte.lpte.pte_hi &= ~LPTE_WIRED; } + + if (pt != NULL) { + /* Update wiring flag in page table. */ + moea64_pte_change(pt, &pvo->pvo_pte.lpte, + pvo->pvo_vpn); + } else if (wired) { + /* + * If we are wiring the page, and it wasn't in the + * page table before, add it. + */ + vsid = PVO_VSID(pvo); + ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo), + pvo->pvo_vaddr & PVO_LARGE); + + i = moea64_pte_insert(ptegidx, &pvo->pvo_pte.lpte); + if (i >= 0) { + PVO_PTEGIDX_CLR(pvo); + PVO_PTEGIDX_SET(pvo, i); + } + } + + UNLOCK_TABLE(); } PMAP_UNLOCK(pm); } @@ -2410,6 +2442,13 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t z if ((pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) == pa && (pvo->pvo_pte.lpte.pte_lo & LPTE_PP) == (pte_lo & LPTE_PP)) { + if (!(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) { + /* Re-insert if spilled */ + i = moea64_pte_insert(ptegidx, + &pvo->pvo_pte.lpte); + if (i >= 0) + PVO_PTEGIDX_SET(pvo, i); + } UNLOCK_TABLE(); return (0); } @@ -2479,8 +2518,10 @@ moea64_pvo_enter(pmap_t pm, uma_zone_t z first = 1; LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink); - if (pvo->pvo_vaddr & PVO_WIRED) + if (pvo->pvo_vaddr & PVO_WIRED) { + pvo->pvo_pte.lpte.pte_hi |= LPTE_WIRED; pm->pm_stats.wired_count++; + } pm->pm_stats.resident_count++; /* @@ -2627,8 +2668,6 @@ moea64_pvo_to_pte(const struct pvo_entry { struct lpte *pt; - ASSERT_TABLE_LOCK(); - /* * If we haven't been supplied the ptegidx, calculate it. */ @@ -2642,8 +2681,6 @@ moea64_pvo_to_pte(const struct pvo_entry pteidx = moea64_pvo_pte_index(pvo, ptegidx); } - pt = &moea64_pteg_table[pteidx >> 3].pt[pteidx & 7]; - if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) { panic("moea64_pvo_to_pte: pvo %p has valid pte in pvo but no " @@ -2660,6 +2697,8 @@ moea64_pvo_to_pte(const struct pvo_entry if (!PVO_PTEGIDX_ISSET(pvo)) return (NULL); + ASSERT_TABLE_LOCK(); + pt = &moea64_pteg_table[pteidx >> 3].pt[pteidx & 7]; if ((pt->pte_hi ^ (pvo->pvo_pte.lpte.pte_hi & ~LPTE_VALID)) == LPTE_VALID) { if ((pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0) { @@ -2675,7 +2714,6 @@ moea64_pvo_to_pte(const struct pvo_entry (uint32_t)(pt->pte_lo ^ pvo->pvo_pte.lpte.pte_lo)); } - ASSERT_TABLE_LOCK(); return (pt); } @@ -2698,18 +2736,8 @@ moea64_pte_spillable_ident(u_int ptegidx k = -1; for (j = 0; j < 8; j++) { pt = &moea64_pteg_table[ptegidx].pt[(i + j) % 8]; - if (pt->pte_hi & LPTE_LOCKED) - continue; - - /* Don't spill kernel mappings */ - #ifdef __powerpc64__ - if ((pt->pte_hi >> LPTE_VSID_SHIFT) & KERNEL_VSID_BIT) - continue; - #else - if (((pt->pte_hi >> LPTE_VSID_SHIFT) & EMPTY_SEGMENT) == - EMPTY_SEGMENT) + if (pt->pte_hi & (LPTE_LOCKED | LPTE_WIRED)) continue; - #endif /* This is a candidate, so remember it */ k = (i + j) % 8; @@ -2786,6 +2814,8 @@ moea64_pte_insert(u_int ptegidx, struct LIST_FOREACH(pvo, &moea64_pvo_table[pteg_bktidx], pvo_olink) { if (pvo->pvo_pte.lpte.pte_hi == pt->pte_hi) { + if (!(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) + continue; moea64_pte_unset(pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn); PVO_PTEGIDX_CLR(pvo); moea64_pte_overflow++; @@ -2797,6 +2827,8 @@ moea64_pte_insert(u_int ptegidx, struct /* It could have landed in the secondary PTEG */ pteg_bktidx ^= moea64_pteg_mask; LIST_FOREACH(pvo, &moea64_pvo_table[pteg_bktidx], pvo_olink) { + if (!(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) + continue; if (pvo->pvo_pte.lpte.pte_hi == pt->pte_hi) { moea64_pte_unset(pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn);help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006191945.o5JJj99T077114>
