svn commit: r209352 - projects/ppc64/sys/powerpc/aim
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sat Jun 19 19:45:09 UTC 2010
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);
More information about the svn-src-projects
mailing list