[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: UVM (Re: MNN)



<199806031650.BAA17424@ruri.iri.co.jp>の記事において
1998年06月04日01時50分頃、tsubai@iri.co.jpさんは書きました。

 > うごかしてみました。カーネルのコンパイルぐらいはできるようです。

良かった。

 > 問題が出ないようなら、今晩から uvm で生活してみます。

とりあえず、UVMと、tsubaiさんのMACHINE_NEW_NONCONTIG、kcopy、pmap bug fixを
まとめてpowerpcにcommitしてしまってよろしいでしょうか?
currentへのpatchを最後に付けます。

# UVM support(include MACHINE_NEW_NONCONTIG,kcopy,pmap bug fix by Tsubai-san)
# てな感じで。


 > ># 速くなったようななっていないような...
 > 
 > 604e@200MHz ではほとんど誤差範囲ですね。ハードディスク上で GENERIC を
 > それぞれ何度かコンパイルしてみましたが、±5秒程度しか差が出ません。
 > 
 > メモリー64MBで 64MB の mfs をとって、そこに sys.tar.gz を広げて同様に
 > やってみるとちょっとだけ uvm が速いようですが、有意な差かどうかは
 > もっとやってみないとはっきりしません。

実メモリより大きいメモリを使うときに有意な差が現れるのですね。


 > # こういう時、メモリーが多すぎて困る。:-)

メモリーを抜きませう :-)

sakamoto@cec.co.jp

Index: powerpc/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/pmap.c,v
retrieving revision 1.5
diff -r1.5 pmap.c
32a33,34
> #include "opt_uvm.h"
> 
184a187,220
> #if defined(MACHINE_NEW_NONCONTIG)
> static __inline struct pv_entry *
> pa_to_pv(pa)
> 	vm_offset_t pa;
> {
> 	int bank, pg;
> 
> 	bank = vm_physseg_find(atop(pa), &pg);
> 	if (bank == -1) {
> #ifdef DIAGNOSTIC
> 		panic("pa_to_pv (pa = 0x%x)", pa);
> #endif
> 		return NULL;
> 	}
> 	return &vm_physmem[bank].pmseg.pvent[pg];
> }
> 
> static __inline char *
> pa_to_attr(pa)
> 	vm_offset_t pa;
> {
> 	int bank, pg;
> 
> 	bank = vm_physseg_find(atop(pa), &pg);
> 	if (bank == -1) {
> #ifdef DIAGNOSTIC
> 		panic("pa_to_attrib (pa = 0x%x)", pa);
> #endif
> 		return NULL;
> 	}
> 	return &vm_physmem[bank].pmseg.attrs[pg];
> }
> #endif
> 
456a493,503
> #if defined(MACHINE_NEW_NONCONTIG)
> 	for (mp = avail; mp->size; mp++)
> #if defined(UVM)
> 		uvm_page_physload(atop(mp->start), atop(mp->start + mp->size),
> 			atop(mp->start), atop(mp->start + mp->size));
> #else
> 		vm_page_physload(atop(mp->start), atop(mp->start + mp->size),
> 			atop(mp->start), atop(mp->start + mp->size));
> #endif
> #endif
> 
476,481d522
< 
< #if defined(MACHINE_NEW_NONCONTIG)
< 	for (mp = avail; mp->size; mp++)
< 		vm_page_physload(atop(mp->start), atop(mp->start + mp->size),
< 				 atop(mp->start), atop(mp->start + mp->size));
< #endif
520c561,565
< 	
---
> #if defined(MACHINE_NEW_NONCONTIG)
> 	int bank;
> 	char *attr;
> #endif
> 
522a568,572
> #if defined(UVM)
> 	/* XXXCDC: ABSOLUTELY WRONG!   uvm_km_alloc() _CAN_
> 		return 0 if out of VM */
> 	addr = (vm_offset_t)uvm_km_alloc(kernel_map, sz);
> #else
523a574
> #endif
530a582,594
> 
> #if defined(MACHINE_NEW_NONCONTIG)
> 	pv = pv_table;
> 	attr = pmap_attrib;
> 	for (bank = 0; bank < vm_nphysseg; bank++) {
> 		sz = vm_physmem[bank].end - vm_physmem[bank].start;
> 		vm_physmem[bank].pmseg.pvent = pv;
> 		vm_physmem[bank].pmseg.attrs = attr;
> 		pv += sz;
> 		attr += sz;
> 	}
> #endif
> 
537a602
> #if !defined(MACHINE_NEW_NONCONTIG)
553a619
> #endif
568a635
> #if !defined(MACHINE_NEW_NONCONTIG)
599a667
> #endif
761a830,833
> #if defined(UVM)
> 		if (!(pvp = (struct pv_page *)uvm_km_alloc(kernel_map, NBPG)))
> 			panic("pmap_alloc_pv: uvm_km_alloc() failed");
> #else
763a836
> #endif
801a875,877
> #if defined(UVM)
> 		uvm_km_free(kernel_map, (vm_offset_t)pvp, NBPG);
> #else
802a879
> #endif
826a904,906
> #if defined(UVM)
> 		mem = uvm_pagealloc(NULL, NULL, NULL);
> #else
827a908
> #endif
862a944,946
> #if defined(UVM)
> 		uvm_pagefree(pop->pop_pgi.pgi_page);
> #else
863a948
> #endif
878c963
< pmap_enter_pv(pteidx, va, pind)
---
> pmap_enter_pv(pteidx, va, pa)
880,881c965
< 	vm_offset_t va;
< 	u_int pind;
---
> 	vm_offset_t va, pa;
891c975
< 	pv = &pv_table[pind];
---
> 	pv = pa_to_pv(pa);
915c999
< pmap_remove_pv(pteidx, va, pind, pte)
---
> pmap_remove_pv(pteidx, va, pa, pte)
917,918c1001
< 	vm_offset_t va;
< 	int pind;
---
> 	vm_offset_t va, pa;
922,924c1005
< 
< 	if (pind < 0)
< 		return;
---
> 	char *attr;
929c1010,1013
< 	pmap_attrib[pind] |= (pte->pte_lo & (PTE_REF | PTE_CHG)) >> ATTRSHFT;
---
> 	attr = pa_to_attr(pa);
> 	if (attr == NULL)
> 		return;
> 	*attr |= (pte->pte_lo & (PTE_REF | PTE_CHG)) >> ATTRSHFT;
934c1018
< 	pv = &pv_table[pind];
---
> 	pv = pa_to_pv(pa);
978c1062
< 	struct mem_region *mp;
---
> 	int bank;
983c1067
< 	pmap_remove(pm, va, va + NBPG - 1);
---
> 	pmap_remove(pm, va, va + NBPG);
997,1002c1081,1085
< 	for (mp = mem; mp->size; mp++) {
< 		if (pa >= mp->start && pa < mp->start + mp->size) {
< 			pte.pte_lo &= ~(PTE_I | PTE_G);
< 			break;
< 		}
< 	}
---
> 
> 	bank = vm_physseg_find(atop(pa), NULL);
> 	if (bank != -1)
> 		pte.pte_lo &= ~(PTE_I | PTE_G);
> 
1011,1012c1094,1095
< 	if (pmap_initialized && (i = pmap_page_index(pa)) != -1)
< 		if (pmap_enter_pv(idx, va, i)) {
---
> 	if (pmap_initialized && bank != -1)
> 		if (pmap_enter_pv(idx, va, pa)) {
1057c1140
< 				pmap_remove_pv(idx, va, pmap_page_index(ptp->pte_lo), ptp);
---
> 				pmap_remove_pv(idx, va, ptp->pte_lo, ptp);
1065c1148
< 				pmap_remove_pv(idx, va, pmap_page_index(ptp->pte_lo), ptp);
---
> 				pmap_remove_pv(idx, va, ptp->pte_lo, ptp);
1074c1157
< 				pmap_remove_pv(idx, va, pmap_page_index(po->po_pte.pte_lo),
---
> 				pmap_remove_pv(idx, va, po->po_pte.pte_lo,
1176,1179c1259
< 	
< 	i = pmap_page_index(pa);
< 	if (i < 0)
< 		return;
---
> 	char *attr;
1184,1185c1264,1269
< 	pmap_attrib[i] &= ~mask >> ATTRSHFT;
< 	pmap_attrib[i] |= val >> ATTRSHFT;
---
> 	attr = pa_to_attr(pa);
> 	if (attr == NULL)
> 		return;
> 
> 	*attr &= ~mask >> ATTRSHFT;
> 	*attr |= val >> ATTRSHFT;
1187c1271
< 	pv = pv_table + i;
---
> 	pv = pa_to_pv(pa);
1235,1238c1319
< 
< 	i = pmap_page_index(pa);
< 	if (i < 0)
< 		return 0;
---
> 	char *attr;
1243c1324,1327
< 	bits |= (pmap_attrib[i] << ATTRSHFT) & bit;
---
> 	attr = pa_to_attr(pa);
> 	if (attr == NULL)
> 		return 0;
> 	bits |= (*attr << ATTRSHFT) & bit;
1247c1331
< 	pv = pv_table + i;
---
> 	pv = pa_to_pv(pa);
1298,1299c1382,1384
< 	int i, s, pind, idx;
< 	
---
> 	int i, s, idx;
> 	struct pv_entry *pv;
> 
1306,1307c1391,1392
< 	pind = pmap_page_index(pa);
< 	if (pind < 0)
---
> 	pv = pa_to_pv(pa);
> 	if (pv == NULL)
1311,1313c1396,1398
< 	while (pv_table[pind].pv_idx >= 0) {
< 		idx = pv_table[pind].pv_idx;
< 		va = pv_table[pind].pv_va;
---
> 	while (pv->pv_idx >= 0) {
> 		idx = pv->pv_idx;
> 		va = pv->pv_va;
1317c1402
< 				pmap_remove_pv(idx, va, pind, ptp);
---
> 				pmap_remove_pv(idx, va, pa, ptp);
1327c1412
< 				pmap_remove_pv(idx, va, pind, ptp);
---
> 				pmap_remove_pv(idx, va, pa, ptp);
1337c1422
< 				pmap_remove_pv(idx, va, pind, &po->po_pte);
---
> 				pmap_remove_pv(idx, va, pa, &po->po_pte);
Index: powerpc/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/trap.c,v
retrieving revision 1.5
diff -r1.5 trap.c
32a33,34
> #include "opt_uvm.h"
> 
97a100,104
> #if defined(UVM)
> 			if (uvm_fault(map, trunc_page(va), FALSE, ftype)
> 			    == KERN_SUCCESS)
> 				break;
> #else
100a108
> #endif
105c113,114
< 				bcopy(&(*fb)[3], &frame->fixreg[13], 19);
---
> 				bcopy(&(*fb)[3], &frame->fixreg[13],
> 				      19 * sizeof(register_t));
118a128,133
> #if defined(UVM)
> 			if (uvm_fault(&p->p_vmspace->vm_map,
> 				     trunc_page(frame->dar), FALSE, ftype)
> 			    == KERN_SUCCESS)
> 				break;
> #else
122a138
> #endif
130a147,152
> #if defined(UVM)
> 			if (uvm_fault(&p->p_vmspace->vm_map,
> 				     trunc_page(frame->srr0), FALSE, ftype)
> 			    == KERN_SUCCESS)
> 				break;
> #else
134a157
> #endif
146a170,172
> #if defined(UVM)
> 			uvmexp.syscalls++;
> #else
147a174
> #endif
273a301,303
> #if defined(UVM)
> 	uvmexp.softs++;
> #else
274a305
> #endif
402a434,462
> 	curpcb->pcb_onfault = 0;
> 	return 0;
> }
> 
> /*
>  * kcopy(const void *src, void *dst, size_t len);
>  *
>  * Copy len bytes from src to dst, aborting if we encounter a fatal
>  * page fault.
>  *
>  * kcopy() _must_ save and restore the old fault handler since it is
>  * called by uiomove(), which may be in the path of servicing a non-fatal
>  * page fault.
>  */
> int
> kcopy(src, dst, len)
> 	const void *src;
> 	void *dst;
> 	size_t len;
> {
> 	faultbuf env;
> 
> 	if (setfault(env)) {
> 		curpcb->pcb_onfault = 0;
> 		return EFAULT;
> 	}
> 
> 	bcopy(src, dst, len);
> 
Index: powerpc/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/vm_machdep.c,v
retrieving revision 1.2
diff -r1.2 vm_machdep.c
32a33,34
> #include "opt_uvm.h"
> 
161a164,166
> #if defined(UVM)
> 	uvmspace_free(p->p_vmspace);
> #else
162a168
> #endif
223a230,232
> #if defined(UVM)
> 	taddr = uvm_km_valloc_wait(phys_map, len);
> #else
224a234
> #endif
251a262,264
> #if defined(UVM)
> 	uvm_km_free_wakeup(phys_map, addr, len);
> #else
252a266
> #endif