PERFORCE change 31060 for review
Marcel Moolenaar
marcel at FreeBSD.org
Tue May 13 02:37:25 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=31060
Change 31060 by marcel at marcel_nfs on 2003/05/13 02:36:36
Make sure we purge the TLB when we update the VHPT by having
pmap_update_vhpt() do the purge. Remove purging the TLB from
the callers of pmap_update_vhpt(). This also affects callers
of pmap_set_pte().
Also make sure we purge the TLB when we remove a PTE from the
VHPT. Invalidate the PTE before we purge to avoid a race.
Remove pmap_clear_pte(). It's mostly redundant.
This further improves stability.
While here, sanitize the statistics. We now count the number
of insertions, deletions and updates.
Affected files ...
.. //depot/projects/ia64_epc/sys/ia64/ia64/pmap.c#13 edit
Differences ...
==== //depot/projects/ia64_epc/sys/ia64/ia64/pmap.c#13 (text+ko) ====
@@ -249,16 +249,16 @@
* VHPT instrumentation.
*/
static int pmap_vhpt_inserts;
-static int pmap_vhpt_collisions;
-static int pmap_vhpt_resident;
+static int pmap_vhpt_removals;
+static int pmap_vhpt_updates;
SYSCTL_DECL(_vm_stats);
SYSCTL_NODE(_vm_stats, OID_AUTO, vhpt, CTLFLAG_RD, 0, "");
SYSCTL_INT(_vm_stats_vhpt, OID_AUTO, inserts, CTLFLAG_RD,
- &pmap_vhpt_inserts, 0, "");
-SYSCTL_INT(_vm_stats_vhpt, OID_AUTO, collisions, CTLFLAG_RD,
- &pmap_vhpt_collisions, 0, "");
-SYSCTL_INT(_vm_stats_vhpt, OID_AUTO, resident, CTLFLAG_RD,
- &pmap_vhpt_resident, 0, "");
+ &pmap_vhpt_inserts, 0, "VHPT insertion counter");
+SYSCTL_INT(_vm_stats_vhpt, OID_AUTO, removals, CTLFLAG_RD,
+ &pmap_vhpt_removals, 0, "VHPT removal counter");
+SYSCTL_INT(_vm_stats_vhpt, OID_AUTO, updates, CTLFLAG_RD,
+ &pmap_vhpt_updates, 0, "VHPT update counter");
static PMAP_INLINE void free_pv_entry(pv_entry_t pv);
static pv_entry_t get_pv_entry(void);
@@ -952,13 +952,9 @@
struct ia64_lpte *vhpte;
pmap_vhpt_inserts++;
- pmap_vhpt_resident++;
- vhpte = (struct ia64_lpte *) ia64_thash(va);
+ vhpte = (struct ia64_lpte *)ia64_thash(va);
- if (vhpte->pte_chain)
- pmap_vhpt_collisions++;
-
pte->pte_chain = vhpte->pte_chain;
vhpte->pte_chain = ia64_tpa((vm_offset_t) pte);
@@ -976,11 +972,14 @@
{
struct ia64_lpte *vhpte;
- vhpte = (struct ia64_lpte *) ia64_thash(va);
+ pmap_vhpt_updates++;
+
+ vhpte = (struct ia64_lpte *)ia64_thash(va);
- if ((!vhpte->pte_p || vhpte->pte_tag == pte->pte_tag)
- && pte->pte_p)
+ if ((!vhpte->pte_p || vhpte->pte_tag == pte->pte_tag) && pte->pte_p)
pmap_install_pte(vhpte, pte);
+
+ ia64_ptc_g(va, pte->pte_ps << 2);
}
/*
@@ -1021,11 +1020,15 @@
}
}
- /*
- * Snip this pv_entry out of the collision chain.
- */
+ pmap_vhpt_removals++;
+
+ /* Snip this pv_entry out of the collision chain. */
lpte->pte_chain = pte->pte_chain;
+ /* Invalidate the entry and purge the TLB. */
+ pte->pte_p = 0;
+ ia64_ptc_g(va, pte->pte_ps << 2);
+
/*
* If the VHPTE matches as well, change it to map the first
* element from the chain if there is one.
@@ -1041,7 +1044,6 @@
}
}
- pmap_vhpt_resident--;
error = 0;
done:
return error;
@@ -1250,19 +1252,6 @@
}
/*
- * If a pte contains a valid mapping, clear it and update the VHPT.
- */
-static void
-pmap_clear_pte(struct ia64_lpte *pte, vm_offset_t va)
-{
- if (pte->pte_p) {
- pmap_remove_vhpt(va);
- ia64_ptc_g(va, PAGE_SHIFT << 2);
- pte->pte_p = 0;
- }
-}
-
-/*
* Remove the (possibly managed) mapping represented by pte from the
* given pmap.
*/
@@ -1283,11 +1272,6 @@
if (error)
return error;
- /*
- * Make sure pmap_set_pte() knows it isn't in the VHPT.
- */
- pte->pte_p = 0;
-
if (pte->pte_ig & PTE_IG_WIRED)
pmap->pm_stats.wired_count -= 1;
@@ -1357,13 +1341,9 @@
for (i = 0; i < count; i++) {
vm_offset_t tva = va + i * PAGE_SIZE;
- int wasvalid;
pte = pmap_find_kpte(tva);
- wasvalid = pte->pte_p;
- pmap_set_pte(pte, tva, VM_PAGE_TO_PHYS(m[i]),
- 0, PTE_PL_KERN, PTE_AR_RWX);
- if (wasvalid)
- ia64_ptc_g(tva, PAGE_SHIFT << 2);
+ pmap_set_pte(pte, tva, VM_PAGE_TO_PHYS(m[i]), 0, PTE_PL_KERN,
+ PTE_AR_RWX);
}
}
@@ -1379,8 +1359,9 @@
for (i = 0; i < count; i++) {
pte = pmap_find_kpte(va);
- pmap_clear_pte(pte, va);
- va += PAGE_SIZE;
+ if (pte->pte_p)
+ pmap_remove_vhpt(va);
+ va += PAGE_SIZE;
}
}
@@ -1391,13 +1372,9 @@
pmap_kenter(vm_offset_t va, vm_offset_t pa)
{
struct ia64_lpte *pte;
- int wasvalid;
pte = pmap_find_kpte(va);
- wasvalid = pte->pte_p;
pmap_set_pte(pte, va, pa, 0, PTE_PL_KERN, PTE_AR_RWX);
- if (wasvalid)
- ia64_ptc_g(va, PAGE_SHIFT << 2);
}
/*
@@ -1409,7 +1386,8 @@
struct ia64_lpte *pte;
pte = pmap_find_kpte(va);
- pmap_clear_pte(pte, va);
+ if (pte->pte_p)
+ pmap_remove_vhpt(va);
}
/*
@@ -1615,7 +1593,6 @@
}
pmap_pte_set_prot(pte, newprot);
pmap_update_vhpt(pte, sva);
- pmap_invalidate_page(pmap, sva);
}
sva += PAGE_SIZE;
@@ -1736,7 +1713,7 @@
* adds the pte to the VHPT if necessary.
*/
pmap_set_pte(pte, va, pa, managed | (wired ? PTE_IG_WIRED : 0),
- pte_prot_pl(pmap, prot), pte_prot_ar(pmap, prot));
+ pte_prot_pl(pmap, prot), pte_prot_ar(pmap, prot));
/*
* if the mapping or permission bits are different, we need
@@ -1784,9 +1761,8 @@
/*
* Initialise PTE with read-only protection and enter into VHPT.
*/
- pmap_set_pte(pte, va, VM_PAGE_TO_PHYS(m),
- PTE_IG_MANAGED,
- PTE_PL_USER, PTE_AR_R);
+ pmap_set_pte(pte, va, VM_PAGE_TO_PHYS(m), PTE_IG_MANAGED, PTE_PL_USER,
+ PTE_AR_R);
pmap_install(oldpmap);
}
@@ -2231,7 +2207,6 @@
pte = pmap_find_vhpt(pv->pv_va);
pmap_pte_set_prot(pte, newprot);
pmap_update_vhpt(pte, pv->pv_va);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
pmap_install(oldpmap);
}
vm_page_flag_clear(m, PG_WRITEABLE);
@@ -2269,7 +2244,6 @@
count++;
pte->pte_a = 0;
pmap_update_vhpt(pte, pv->pv_va);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
}
pmap_install(oldpmap);
}
@@ -2346,7 +2320,6 @@
if (pte->pte_d) {
pte->pte_d = 0;
pmap_update_vhpt(pte, pv->pv_va);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
}
pmap_install(oldpmap);
}
@@ -2371,7 +2344,6 @@
if (pte->pte_a) {
pte->pte_a = 0;
pmap_update_vhpt(pte, pv->pv_va);
- pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
}
pmap_install(oldpmap);
}
More information about the p4-projects
mailing list