PERFORCE change 93341 for review

Kip Macy kmacy at FreeBSD.org
Wed Mar 15 08:32:06 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=93341

Change 93341 by kmacy at kmacy_storage:sun4v_work on 2006/03/15 08:32:03

	don't zero cleanwin on context switch as it is handled in user_rtt
	add support for direct mapped physical address using large pages
	allocate early processes' hash tables out of block allocated in pmap_bootstrap
	implement pmap_copy to avoid unnecessary read faults

Affected files ...

.. //depot/projects/kmacy_sun4v/src/sys/sun4v/include/tte_hash.h#6 edit
.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#26 edit
.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/swtch.S#10 edit
.. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/tte_hash.c#9 edit

Differences ...

==== //depot/projects/kmacy_sun4v/src/sys/sun4v/include/tte_hash.h#6 (text+ko) ====

@@ -6,7 +6,7 @@
 struct tte_hash;
 typedef struct tte_hash *tte_hash_t;
 
-void tte_hash_init(void);
+void tte_hash_init(vm_paddr_t);
 
 tte_hash_t tte_hash_kernel_create(vm_offset_t, uint64_t);
 

==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/pmap.c#26 (text+ko) ====

@@ -103,6 +103,7 @@
 int sparc64_nmemreg;
 
 extern vm_paddr_t mmu_fault_status_area;
+vm_paddr_t proc0_mem;
 
 
 /*
@@ -130,13 +131,6 @@
  */
 struct pmap kernel_pmap_store;
 
-/*
- * pmap_copy_page vas NOT mp-safe
- */
-vm_offset_t pmap_copy_0, pmap_copy_1;
-
-
-
 hv_tsb_info_t kernel_td[MAX_TSB_INFO];
 
 /*
@@ -363,6 +357,8 @@
 	pmap->pm_active |= 1;
 #endif
 	pmap->pm_hashscratch = tte_hash_set_scratchpad_user(pmap->pm_hash);
+	printf("hashscratch=%lx\n", pmap->pm_hashscratch);
+
 	pmap->pm_tsbscratch = tsb_set_scratchpad_user(&pmap->pm_tsb);
 	PCPU_SET(curpmap, pmap);
 	critical_exit();
@@ -506,33 +502,19 @@
 
 	pmap_scrub_pages(kernel_td[TSB4M_INDEX].hvtsb_pa, tsb_4m_size);
 
-	/*
-	 * setup direct mappings
-	 * 
-	 */
-	for (pa = PAGE_SIZE_4M; pa < phys_avail[2]; pa += PAGE_SIZE_4M)
-		tsb_set_tte(&kernel_td[TSB4M_INDEX], TLB_PHYS_TO_DIRECT(pa), 
-			    pa | TTE_KERNEL | VTD_4M, 0);
 
 	/*
 	 * allocate MMU fault status areas for all CPUS
 	 */
 	mmu_fault_status_area = pmap_bootstrap_alloc(MMFSA_SIZE*MAXCPU);
 
+	proc0_mem = pmap_bootstrap_alloc(PAGE_SIZE*4*40);
 	/*
 	 * Allocate and map the message buffer.
 	 */
 	msgbuf_phys = pmap_bootstrap_alloc(MSGBUF_SIZE);
 	msgbufp = (struct msgbuf *)TLB_PHYS_TO_DIRECT(msgbuf_phys);
 
-#ifdef notyet
-	/* XXX this tries to map at a wacky address */
-	for (i = 0; i < (MSGBUF_SIZE / PAGE_SIZE); i++)
-		tsb_set_tte(&kernel_td[TSB8K_INDEX], 
-			    ((vm_offset_t)msgbufp) + i*PAGE_SIZE, 
-			    msgbuf_phys + i*PAGE_SIZE | TTE_KERNEL | VTD_8K, 0);
-#endif
-
 	/*
 	 * Allocate a kernel stack with guard page for thread0 and map it into
 	 * the kernel tsb.  
@@ -548,20 +530,20 @@
 		tsb_set_tte(&kernel_td[TSB8K_INDEX], va,
 			    pa | TTE_KERNEL | VTD_8K, 0);
 	}
-        /* short-term MP-unsafe hack for pmap_copy_page
-	 */
-	pmap_copy_0 = virtual_avail;
-	virtual_avail += PAGE_SIZE;
-	pmap_copy_1 = virtual_avail;
-	virtual_avail += PAGE_SIZE;
-
-
 	/*
 	 * Calculate the last available physical address.
 	 */
 	for (i = 0; phys_avail[i + 2] != 0; i += 2)
 		;
 	Maxmem = sparc64_btop(phys_avail[i + 1]);
+	/*
+	 * setup direct mappings
+	 * 
+	 */
+	for (pa = PAGE_SIZE_4M; pa < phys_avail[2]; pa += PAGE_SIZE_4M) {
+		tsb_set_tte(&kernel_td[TSB4M_INDEX], TLB_PHYS_TO_DIRECT(pa), 
+			    pa | TTE_KERNEL | VTD_4M, 0);
+	}
 
 	/*
 	 * Add the prom mappings to the kernel tsb.
@@ -713,22 +695,67 @@
 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr,
 	  vm_size_t len, vm_offset_t src_addr)
 {
-	IMPLEMENTME;
+	vm_offset_t addr, end_addr;
+
+	end_addr = src_addr + len;
+	
+	printf("pmap_copy(0x%lx, %ld, 0x%lx)\n", dst_addr, len, src_addr);
+	if (dst_addr != src_addr)
+		return;
+
+	/*
+	 * Don't let optional prefaulting of pages make us go
+	 * way below the low water mark of free pages or way
+	 * above high water mark of used pv entries.
+	 */
+	if (cnt.v_free_count < cnt.v_free_reserved ||
+	    pv_entry_count > pv_entry_high_water)
+		return;
+	
+	vm_page_lock_queues();
+	if (dst_pmap < src_pmap) {
+		PMAP_LOCK(dst_pmap);
+		PMAP_LOCK(src_pmap);
+	} else {
+		PMAP_LOCK(src_pmap);
+		PMAP_LOCK(dst_pmap);
+	}
+	sched_pin();
+	for (addr = src_addr; addr < end_addr; addr += PAGE_SIZE) {
+		tte_t *src_tte, *dst_tte, tte_data;
+		vm_page_t m;
+
+		src_tte = tte_hash_lookup(src_pmap->pm_hash, addr);
+		tte_data = src_tte ? *src_tte : 0;
+		if ((tte_data & VTD_MANAGED) != 0) {
+			if ((dst_tte = tte_hash_lookup(dst_pmap->pm_hash, addr)) == NULL) {
+				m = PHYS_TO_VM_PAGE(TTE_GET_PA(tte_data));
+				tte_hash_insert(dst_pmap->pm_hash, addr, tte_data & ~(VTD_W|VTD_REF));
+				dst_pmap->pm_stats.resident_count++;
+				pmap_insert_entry(dst_pmap, addr, m);
+			} 
+		}		
+		
+		
+	}
+	
+	sched_unpin();
+	vm_page_unlock_queues();
+	PMAP_UNLOCK(src_pmap);
+	PMAP_UNLOCK(dst_pmap);
+
 }
 
 void
 pmap_copy_page(vm_page_t src, vm_page_t dst)
 {
-	/* XXX NOT mp-safe */
-	tsb_set_tte(&kernel_pmap->pm_tsb, pmap_copy_0,
-		    VM_PAGE_TO_PHYS(src) | TTE_KERNEL | VTD_8K, 0);
-	tsb_set_tte(&kernel_pmap->pm_tsb, pmap_copy_1,
-		    VM_PAGE_TO_PHYS(dst) | TTE_KERNEL | VTD_8K, 0);
-	
-	bcopy((char *)pmap_copy_0, (char *)pmap_copy_1, PAGE_SIZE);
+	vm_paddr_t srcpa, dstpa;
+	srcpa = VM_PAGE_TO_PHYS(src);
+	dstpa = VM_PAGE_TO_PHYS(dst);
+
+	bcopy((char *)TLB_PHYS_TO_DIRECT(srcpa), (char *)TLB_PHYS_TO_DIRECT(dstpa), PAGE_SIZE);
+
 
-	pmap_invalidate_page(kernel_pmap, pmap_copy_0);
-	pmap_invalidate_page(kernel_pmap, pmap_copy_1);
 }
 
 /*
@@ -974,7 +1001,7 @@
 	pv_entry_high_water = 9 * (pv_entry_max / 10);
 	uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max);
 
-	tte_hash_init();
+	tte_hash_init(proc0_mem);
 
 }
 
@@ -1239,6 +1266,7 @@
 		("max context limit hit - need to implement context recycling"));
 
 	pmap->pm_hash = tte_hash_create(pmap->pm_context, &pmap->pm_hashscratch);
+	printf("hashscratch=%lx\n", pmap->pm_hashscratch);
 	pmap->pm_tsb_ra = tsb_init(&pmap->pm_tsb, &pmap->pm_tsbscratch);
 	pmap->pm_active = 0;
 	TAILQ_INIT(&pmap->pm_pvlist);

==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/swtch.S#10 (text+ko) ====

@@ -40,6 +40,7 @@
 
 #define	PCB_REG	%g6
 	
+#define MAGIC_EXIT	ta 0x71
 #define MAGIC_TRAP_ON	ta 0x77
 #define MAGIC_TRAP_OFF	ta 0x78
 /*
@@ -97,7 +98,6 @@
 	 * pointer and program counter.
 	 */
 2:	flushw
-	wrpr	%g0, 0, %cleanwin
 	stx	%fp, [PCB_REG + PCB_SP]
 	stx	%i7, [PCB_REG + PCB_PC]
 
@@ -184,7 +184,8 @@
 	cmp	%g0, %o0
 	be	%xcc, 4f
 	  nop
-	illtrap
+	MAGIC_TRAP_ON
+	MAGIC_EXIT
 	
 4:	/*
 	 * install the new secondary context number in the cpu.

==== //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/tte_hash.c#9 (text+ko) ====

@@ -49,6 +49,8 @@
 #include <machine/smp.h>
 #include <machine/mmu.h>
 #include <machine/tte.h>
+#include <machine/vmparam.h>
+#include <machine/tlb.h>
 #include <machine/tte_hash.h>
 
 #define HASH_SIZE        4
@@ -85,7 +87,7 @@
 };
 
 static struct tte_hash kernel_tte_hash;
-
+static vm_paddr_t proc0_mem;
 
 /*
  * Data for the tte_hash allocation mechanism
@@ -115,12 +117,13 @@
 }
 
 void 
-tte_hash_init(void)
+tte_hash_init(vm_paddr_t bootmem)
 {
 	thzone = uma_zcreate("TTE_HASH", sizeof(struct tte_hash), NULL, NULL, 
 	    NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
 	tte_hash_max = maxproc;
 	uma_zone_set_obj(thzone, &thzone_obj, tte_hash_max);
+	proc0_mem = bootmem;
 }
 
 
@@ -144,39 +147,46 @@
 tte_hash_create(uint64_t context, uint64_t *scratchval)
 {
 	tte_hash_t th;
-	vm_page_t m, hash_pages[HASH_SIZE];
+	vm_page_t m, tm;
 	int i;
-	static int color;
-
+	static int proc0_mem_allocated;
+	
 	th = get_tte_hash();
 	
 	th->th_size = HASH_SIZE;
 	th->th_entries = 0;
 	th->th_context = (uint16_t)context;
-	th->th_hashtable = (tte_hash_entry_t)kmem_alloc_nofault(kernel_map, 
-								PAGE_SIZE*HASH_SIZE);
+	m = NULL;
+
+
+	if (proc0_mem_allocated < 40) {
+
+		printf("skipping vm_page_alloc_contig\n");
+		proc0_mem_allocated++;
+		th->th_hashtable = (void *)TLB_PHYS_TO_DIRECT(proc0_mem);
+		proc0_mem += PAGE_SIZE*HASH_SIZE;
+		goto done;
+	}
 
-	printf("th->th_hashtable=%p ", th->th_hashtable);
-	for (i = 0; i < HASH_SIZE;) {
-		m = vm_page_alloc(NULL, color++,
-		    VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
-		    VM_ALLOC_ZERO);
-		printf("PHYS(m)=0x%010lx ", VM_PAGE_TO_PHYS(m));
+	printf("calling vm_page_alloc_contig\n");
+	while (m == NULL) {
+		m = vm_page_alloc_contig(HASH_SIZE, 2*PAGE_SIZE_4M, 
+					 (1UL<<28), 0, 0);
 		if (m == NULL)
 			VM_WAIT;
-		else {
-			hash_pages[i++] = m;
-		}
+	}
+	printf("PHYS(m)=0x%010lx ", VM_PAGE_TO_PHYS(m));
+	for (i = 0, tm = m; i < HASH_SIZE; i++, tm++) {
+		if (tm->flags & PG_ZERO)
+			pmap_zero_page(tm);
 	}
-	printf("entered\n");
-	pmap_qenter((vm_offset_t)th->th_hashtable, hash_pages, HASH_SIZE);
 
-	for (i = 0; i < HASH_SIZE; i++) {
-		if ((hash_pages[i]->flags & PG_ZERO) == 0)
-			pmap_zero_page(hash_pages[i]);
-	}
-	*scratchval = ((vm_offset_t)th->th_hashtable) | ((vm_offset_t)th->th_size);
+	th->th_hashtable = (void *)TLB_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(m));
+done:
+	printf("th->th_hashtable %p\n", th->th_hashtable);
+	*scratchval = (uint64_t)((vm_offset_t)th->th_hashtable) | ((vm_offset_t)th->th_size);
 
+	printf("hash_create done\n");
 	return (th);
 }
 
@@ -186,6 +196,7 @@
 	vm_page_t m, hash_pages[MAX_HASH_SIZE];
 	int i;
 	
+	panic("FIXME");
 	for (i = 0; i < th->th_size; i++)
 		hash_pages[i] = PHYS_TO_VM_PAGE(vtophys(((char *)th->th_hashtable) + i*PAGE_SIZE));
 
@@ -315,7 +326,7 @@
 	 */
 
 	hash_scratch = ((vm_offset_t)th->th_hashtable) | ((vm_offset_t)th->th_size);
-	
+	printf("hash_scratch=0x%lx\n", hash_scratch);
 	set_hash_user_scratchpad(hash_scratch);
 	
 	return hash_scratch;


More information about the p4-projects mailing list