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