PERFORCE change 97324 for review
Kip Macy
kmacy at FreeBSD.org
Wed May 17 06:16:00 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=97324
Change 97324 by kmacy at kmacy_storage:sun4v_rwbuf on 2006/05/17 06:15:38
simplify pmap_enter and pmap_map
work around broken calls to pmap_qremove
copious other cleanups
Affected files ...
.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#49 edit
Differences ...
==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#49 (text+ko) ====
@@ -429,7 +429,7 @@
struct pmap *pm;
vm_offset_t off, va;
vm_paddr_t pa, kernel_hash_pa;
- vm_size_t physsz, virtsz;
+ vm_size_t physsz, virtsz, kernel_hash_size;
ihandle_t pmem, vmem;
int i, sz, j;
uint64_t tsb_8k_size, tsb_4m_size, error;
@@ -559,7 +559,13 @@
* Allocate and map a 4MB page for the kernel hashtable
*
*/
- kernel_hash_pa = pmap_bootstrap_alloc(PAGE_SIZE_4M);
+#ifndef SIMULATOR
+ kernel_hash_size = PAGE_SIZE_4M*2;
+#else
+ kernel_hash_size = PAGE_SIZE_8K*64;
+#endif
+
+ kernel_hash_pa = pmap_bootstrap_alloc(kernel_hash_size);
if (kernel_hash_pa & PAGE_MASK_4M)
panic("pmap_bootstrap: hashtable pa unaligned\n");
/*
@@ -724,7 +730,7 @@
* This could happen earlier - but I put it here to avoid
* attempts to do updates until they're legal
*/
- pm->pm_hash = tte_hash_kernel_create(TLB_PHYS_TO_DIRECT(kernel_hash_pa), PAGE_SIZE_4M);
+ pm->pm_hash = tte_hash_kernel_create(TLB_PHYS_TO_DIRECT(kernel_hash_pa), kernel_hash_size);
pm->pm_hashscratch = tte_hash_set_scratchpad_kernel(pm->pm_hash);
for (i = 0; i < translations_size; i++) {
@@ -807,7 +813,7 @@
vm_offset_t addr, end_addr;
end_addr = src_addr + len;
-
+
/*
* Don't let optional prefaulting of pages make us go
* way below the low water mark of free pages or way
@@ -831,10 +837,10 @@
tte_t tte_data;
vm_page_t m;
- tte_data = tte_hash_lookup_nolock(src_pmap->pm_hash, addr);
+ tte_data = tte_hash_lookup(src_pmap->pm_hash, addr);
if ((tte_data & VTD_MANAGED) != 0) {
- if (tte_hash_lookup_nolock(dst_pmap->pm_hash, addr) == 0) {
+ if (tte_hash_lookup(dst_pmap->pm_hash, addr) == 0) {
m = PHYS_TO_VM_PAGE(TTE_GET_PA(tte_data));
tte_hash_insert(dst_pmap->pm_hash, addr, tte_data & ~(VTD_W|VTD_REF));
@@ -864,6 +870,19 @@
}
+static __inline void
+pmap_add_tte(pmap_t pmap, vm_offset_t va, vm_page_t m, tte_t *tte_data, int wired)
+{
+
+ if (wired)
+ pmap->pm_stats.wired_count++;
+
+ if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) {
+ pmap_insert_entry(pmap, va, m);
+ *tte_data |= VTD_MANAGED;
+ }
+}
+
/*
* Map the given physical page at the specified virtual address in the
* target pmap with the protection requested. If specified the page
@@ -889,20 +908,33 @@
sched_pin();
tte_data = pa = VM_PAGE_TO_PHYS(m);
- otte_data = tte_hash_lookup(pmap->pm_hash, va);
+ otte_data = tte_hash_delete(pmap->pm_hash, va);
opa = TTE_GET_PA(otte_data);
-#ifdef PMAP_DEBUG
- if (opa > (1 << 31))
- panic("opa out of range 0x%lx\n", opa);
- if ((vm_offset_t)PHYS_TO_VM_PAGE(opa) > ((1UL << 31) | VM_MIN_DIRECT_ADDRESS)) {
- DELAY(curcpu*5000);
- panic("om out of range %p\n", PHYS_TO_VM_PAGE(opa));
- }
-#endif
+
/*
* Mapping has not changed, must be protection or wiring change.
*/
- if (pa == opa) {
+
+ if (opa == 0) {
+ pmap->pm_stats.resident_count++;
+ pmap_add_tte(pmap, va, m, &tte_data, wired);
+
+ } else if (pa != opa) {
+ /*
+ * Mapping has changed, invalidate old range and fall through to
+ * handle validating new mapping.
+ */
+ if (otte_data & VTD_WIRED)
+ pmap->pm_stats.wired_count--;
+
+ if (otte_data & VTD_MANAGED) {
+ om = PHYS_TO_VM_PAGE(opa);
+ pmap_remove_entry(pmap, om, va);
+ }
+
+ pmap_add_tte(pmap, va, m, &tte_data, wired);
+
+ } else /* (pa == opa) */ {
/*
* Wiring change, just update stats. We don't worry about
* wiring PT pages as they remain resident as long as there
@@ -922,37 +954,9 @@
om = m;
tte_data |= VTD_MANAGED;
}
- goto validate;
+ }
- } else if (opa) {
- /*
- * Mapping has changed, invalidate old range and fall through to
- * handle validating new mapping.
- */
- if (otte_data & VTD_WIRED)
- pmap->pm_stats.wired_count--;
- if (otte_data & VTD_MANAGED) {
- om = PHYS_TO_VM_PAGE(opa);
- pmap_remove_entry(pmap, om, va);
- }
- } else
- pmap->pm_stats.resident_count++;
-
/*
- * Enter on the PV list if part of our managed memory.
- */
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) {
- pmap_insert_entry(pmap, va, m);
- tte_data |= VTD_MANAGED;
- }
- /*
- * Increment counters
- */
- if (wired)
- pmap->pm_stats.wired_count++;
-
-validate:
- /*
* Now validate mapping with desired protection/wiring.
*/
if ((prot & VM_PROT_WRITE) != 0)
@@ -965,7 +969,7 @@
tte_data |= TTE_KERNEL_MINFLAGS;
- otte_data = tte_hash_update(pmap->pm_hash, va, tte_data | TTE_MINFLAGS);
+ tte_hash_insert(pmap->pm_hash, va, tte_data | TTE_MINFLAGS);
tsb_set_tte(&pmap->pm_tsb, va, tte_data|TTE_MINFLAGS, pmap->pm_context);
invlva = FALSE;
@@ -1075,7 +1079,7 @@
vm_page_lock_queues();
PMAP_LOCK(pmap);
sched_pin();
- tte_data = tte_hash_lookup_nolock(pmap->pm_hash, va);
+ tte_data = tte_hash_lookup(pmap->pm_hash, va);
if (tte_data != 0 &&
((tte_data & VTD_SW_W) || (prot & VM_PROT_WRITE) == 0)) {
m = PHYS_TO_VM_PAGE(TTE_GET_PA(tte_data));
@@ -1181,7 +1185,6 @@
else
active = PCPU_GET(other_cpus);
-#if 1
for (cpu_count = 0, i = 0, ackexpect = 0, cpus = active; i < 32 && cpus;) {
@@ -1195,23 +1198,12 @@
cpulist[cpu_count] = (uint16_t)i;
cpu_count++;
ackexpect |= (1 << i);
-#if 0
- inext = ((i & ~0x3) + 4);
- cpus = (cpus >> (inext - i));
- i = inext;
-#else
inext = i++;
cpus = cpus >> 1;
-#endif
}
-#else
- inext = i = cpus = 0;
- cpulist[0] = curcpu ? 0 : 1;
- cpu_count = 1;
- ackexpect = curcpu ? 1 : 2;
-#endif
+
if (cpu_count == 0)
return;
@@ -1257,20 +1249,39 @@
char *func;
#endif
+
+ if ((eva - sva) == PAGE_SIZE) {
+ pmap_invalidate_page(pmap, sva, cleartsb);
+ return;
+ }
+
+ if (sva >= eva)
+ panic("invalidating negative or zero range sva=0x%lx eva=0x%lx", sva, eva);
+
+
spinlock_enter();
if (cleartsb == TRUE) {
+#if 0
if ((((eva - sva) >> PAGE_SHIFT) < MAX_TSB_CLEARS) ||
(pmap->pm_context == 0))
+#endif
tsb_clear_range(&pmap->pm_tsb, sva, eva);
+#if 0
else
tsb_clear(&pmap->pm_tsb);
+#endif
}
- /* XXX */
+ /* XXX - this is needed to make sure that the first page of a process' text
+ * is flushed from the TLB - there aren't any exisiting pmap implementation's
+ * that show how to flush just the page in question - on x86 the TLB is flushed
+ * every time cr3 is changed
+ */
+#if 0
invltlb();
-
- if ((((eva - sva) >> PAGE_SHIFT) < MAX_INVALIDATES)) {
+#endif
+ if ((sva - eva) < PAGE_SIZE*32 ) {
for (tva = sva; tva < eva; tva += PAGE_SIZE_8K)
invlpg(tva, pmap->pm_context);
} else if (pmap->pm_context)
@@ -1395,19 +1406,7 @@
vm_offset_t
pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
{
- vm_offset_t va, sva;
-
- va = sva = *virt;
- while (start < end) {
- pmap_kenter(va, start);
- va += PAGE_SIZE;
- start += PAGE_SIZE;
- }
-
- pmap_invalidate_range(kernel_pmap, sva, va, FALSE);
-
- *virt = va;
- return (sva);
+ return TLB_PHYS_TO_DIRECT(start);
}
int
@@ -1542,17 +1541,13 @@
sched_pin();
for (tva = sva; tva < eva; tva += PAGE_SIZE) {
- uint64_t otte_data, tte_data;
+ uint64_t otte_data;
vm_page_t m;
- if ((tte_data = tte_hash_lookup(pmap->pm_hash, tva)) == 0)
+ if ((otte_data = tte_hash_clear_bits(pmap->pm_hash, tva, (VTD_SW_W | VTD_W | VTD_REF))) == 0)
continue;
- tte_data &= ~(VTD_SW_W | VTD_W | VTD_REF);
-
- otte_data = tte_hash_update(pmap->pm_hash, tva, tte_data);
-
- if (tte_data != otte_data)
+ if (otte_data & (VTD_SW_W | VTD_W | VTD_REF))
anychanged = 1;
if (otte_data & VTD_MANAGED) {
@@ -1593,6 +1588,7 @@
va += PAGE_SIZE;
m++;
}
+
pmap_invalidate_range(kernel_pmap, sva, va, FALSE);
}
@@ -1606,10 +1602,16 @@
vm_offset_t va;
va = sva;
+
+#ifndef NFS_NOT_BROKEN
+ if (count == 0)
+ count = 1;
+#endif
while (count-- > 0) {
pmap_kremove(va);
va += PAGE_SIZE;
}
+
pmap_invalidate_range(kernel_pmap, sva, va, TRUE);
}
@@ -1769,10 +1771,15 @@
tte_data = tte_hash_delete(pmap->pm_hash, pv->pv_va);
if (tte_data == 0) {
- printf("TTE IS ZERO @ VA %016lx\n", pv->pv_va);
- panic("bad tte");
+ membar(Sync);
+ DELAY(100);
+ membar(Sync);
+ tte_data = tte_hash_delete(pmap->pm_hash, pv->pv_va);
+ if (tte_data == 0) {
+ printf("TTE IS ZERO @ VA %016lx\n", pv->pv_va);
+ panic("bad tte");
+ }
}
-
/*
* We cannot remove wired pages from a
* process' mapping at this time
More information about the p4-projects
mailing list