Recommended
PDF
PDF
PDF
PPTX
PDF
PDF
PDF
PEZY-SC2上における倍々精度Rgemmの実装と評価
PDF
PDF
Synthesijer fpgax 20150201
PDF
PDF
PDF
PDF
(JP) GPGPUがPostgreSQLを加速する
PDF
PDF
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
PDF
PDF
AutoDock_Raccoon_japanese_ver.1.0
PDF
SDN Lab環境でのRobotFramework実践活用
PDF
httpd.conf line 1 to 7, 24
PDF
PostgreSQL v9.5の新機能~CustomScan/Join Interface
PDF
PDF
PDF
PPTX
PDF
Varnish 4.0 Release Party in Tokyo発表資料
PPTX
Osc2012 tokyo fall_home_san_nayamaguti
PDF
Postgre sql9.3 newlockmode_and_etc
PDF
C16 45分でわかるPostgreSQLの仕組み by 山田努
PDF
PPTX
x86-64/Linuxに独自メモリ空間を勝手増設
More Related Content
PDF
PDF
PDF
PPTX
PDF
PDF
PDF
PEZY-SC2上における倍々精度Rgemmの実装と評価
PDF
What's hot
PDF
Synthesijer fpgax 20150201
PDF
PDF
PDF
PDF
(JP) GPGPUがPostgreSQLを加速する
PDF
PDF
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
PDF
PDF
AutoDock_Raccoon_japanese_ver.1.0
PDF
SDN Lab環境でのRobotFramework実践活用
PDF
httpd.conf line 1 to 7, 24
PDF
PostgreSQL v9.5の新機能~CustomScan/Join Interface
PDF
PDF
PDF
PPTX
PDF
Varnish 4.0 Release Party in Tokyo発表資料
PPTX
Osc2012 tokyo fall_home_san_nayamaguti
PDF
Postgre sql9.3 newlockmode_and_etc
PDF
C16 45分でわかるPostgreSQLの仕組み by 山田努
Similar to 仮想記憶入門 BSD-4.3を例題に
PDF
PPTX
x86-64/Linuxに独自メモリ空間を勝手増設
PPTX
x86-64/Linuxに独自メモリ空間を勝手増設
PDF
PDF
Basic of virtual memory of Linux
PDF
0章 Linuxカーネルを読む前に最低限知っておくべきこと
PDF
PDF
2011.06.11 v7から始めるunix まとめ
PDF
PDF
2011.09.18 v7から始めるunix まとめ
PDF
【学習メモ#3rd】12ステップで作る組込みOS自作入門
PDF
PDF
PDF
PPTX
PDF
PPTX
PDF
PPT
PDF
More from magoroku Yamamoto
PDF
PDF
PDF
自動並列化コンパイラをAndroidに適用してみた
PDF
Oscar compiler for power reduction
PDF
PDF
PDF
PDF
PDF
PDF
Android builders summit slide tour
PDF
PPTX
PDF
KEY
PDF
PDF
PDF
PDF
PDF
PPT
仮想記憶入門 BSD-4.3を例題に 1. 2. 今日の内容
• 過去:UNIX v6, 未来:4.4BSDとの関連
• 仮想記憶の空間構成
• スワッピングとページング
• 4.3BSDを例にした仮想記憶管理の解析
• 参考資料
– Freebsd-53-kernel-mm.pptx 七誌さん
3. 4. 5. 6. 7. 8. 9. 4.3BSDを理解する意味
• UNIXの系譜では第2世代の最後
– 第一世代 UNIX v{6|7} 切り替え型
– 第二世代 UNIX 32v~4.3BSD 常駐型
– 第三世代 Mach, 4.4BSD他 +広義の単一レベル記憶
• 仮想空間にvnode,offsetで表現可能なファイルをマップ可能になる
• 次の事項の理解に有用
– MMUの仕組み
– ページングの原理と実装
– 実メモリ管理
• UNIX v{6|7}の構成の変化は少なく連続性がある
– ファイル構成・関数構成
10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. スワッピング
• スワップアウト
– 最も優先度の低いプログラムを選択し
– プログラムをスケジュールの対象から外す
– プログラムのメモリ全体をスワップデバイスに退避(write)
• スワップイン
– 実行するプロセスがスワップアウトさせていたら
– メモリを確保-不足したら他のプロセスをスワップアウト
– スワップデバイスに退避してあるメモリイメージをメモリに復元
(read)
– プログラムをスケジュールの対象に含める
• スワッピングとページングは明確に区別せずに使われる
場合があるので注意
21. 22. ページング
• ページアウト
1. メモリが不足
2. 最近使われていない物理メモリ(ページ)を特定
3. 物理メモリが仮想メモリとして利用されていたら変換対象から
外す
4. 物理メモリをページングデバイスに退避
• ページイン
1. 割り当て済の仮想メモリをプログラムが参照
2. アドレス変換例外で割り込みが発生しOSに制御が移る
3. OSが該当プロセス+アドレスから退避済の物理メモリ(ページ)
を特定する
4. 物理メモリを読み込んで仮想メモリから変換可能とする
5. 割り込みから復帰
23. ページングの特徴
• 一般的な運用では
– 仮想空間の総量 > 物理メモリ
– 物理メモリの奪い合い
– メモリ参照に局所性が有る場合
• ゆっくり奪い合う→変換例外とその対応のコストは無視できる
– メモリ参照に局所性が無い場合
• はげしく奪い合う→変換例外とその対応コストが無視できない
• 局所的な参照を前提として使われていないメモリの特
定が必要
– 最近利用されていないメモリは将来も利用されない可能
性が高い
– どうやって?
24. LRU - Least Recently Used
• 「最近使われていないメモリは、将来も使わ
れない可能性が高い」事を前提とする
• メモリの参照頻度を記録して、最近使われて
いないメモリを予想する
– 近年のCPUは参照の有無をアドレス変換表にHW
が記録する
• X86, ARMなど (除くVAX-11)
• 多くは1bit(参照の有無)のみを記録
25. 26. 27. 4.3BSD VAX-11の空間構成
• 32bit = 4Gbyteの空間を4分割(4セグメント)
unused
kernel
User stack
User Text
User Data
0x4000.000
0x0000.000
0x8000.000
0xC000.000
0xFFFF.FFFF
P0
P1
System
Reserved
• P0,P1 にUserプログラム
• P1にはKernel Stack・Uも配置
• System リージョンにカーネルを配置
• copy{in|out}は同一空間の転送
1142 /*
1143 * Copy specified amount of data from user space into the kernel
1144 * Copyin(from, to, len)
1145 * r1 == from (user source address)
1146 * r3 == to (kernel destination address)
1147 * r5 == length
1148 */
1149 .align 1
1150 JSBENTRY(Copyin, R1|R3|R5)
1151 cmpl r5,$(NBPG*CLSIZE) # probing one page or less ?
1152 bgtru 1f # no
1153 prober $3,r5,(r1) # bytes accessible ?
1154 beql ersb # no
1155 movc3 r5,(r1),(r3)
1156 /* clrl r0 # redundant */
1157 rsb
28. 29. 30. セグメント用のレジスタ
• root/machine/mtpr.h
18 #define P0BR 0x8 /* p0 base register */
19 #define P0LR 0x9 /* p0 length register */
20 #define P1BR 0xa /* p1 base register */
21 #define P1LR 0xb /* p1 length register */
22 #define SBR 0xc /* system segment base register */
23 #define SLR 0xd /* system segment length register */
unused
kernel
User stack
Kernal stack
User Text
User Data
P0BR
P1BR
SBR
P0LR
P1LR
SLR
31. セグメントレジスタの設定
• root/GENERIC/sys/vmmac.h
88 #define setp0br(x) (u.u_pcb.pcb_p0br = (x), mtpr(P0BR, x))
89 #define setp0lr(x) (u.u_pcb.pcb_p0lr = ¥
90 (x) | (u.u_pcb.pcb_p0lr & AST_CLR), ¥
91 mtpr(P0LR, x))
92 #define setp1br(x) (u.u_pcb.pcb_p1br = (x), mtpr(P1BR, x))
93 #define setp1lr(x) (u.u_pcb.pcb_p1lr = (x), mtpr(P1LR, x))
94 #define initp1br(x) ((x) - P1PAGES)
UNIX v6がuにアドレス変換レジスタの内容を持っていたのと同じ
32. 33. 構造:cmap
• h/cmap.h
27 struct cmap
28 {
29 unsigned short c_next, /* index of next free list entry */
30 c_prev, /* index of previous free list entry */
31 c_hlink; /* hash link for <blkno,mdev> */
32 unsigned short c_ndx; /* index of owner proc or text */
33 unsigned int c_page:21, /* virtual page number in segment */
34 c_lock:1, /* locked for raw i/o or pagein */
35 c_want:1, /* wanted */
36 c_intrans:1, /* intransit bit */
37 c_free:1, /* on the free list */
38 c_gone:1, /* associated page has been released */
39 c_type:2, /* type CSYS or CTEXT or CSTACK or CDATA */
40 :4, /* to longword boundary */
41 c_blkno:24, /* disk block this is a copy of */
42 c_mdev:8; /* which mounted dev this is from */
43 };
34. Cmapの初期化
• root/vax/machdep.c
105 v = (caddr_t)(0x80000000 | (firstaddr * NBPG));
106 #define valloc(name, type, num) ¥
107 (name) = (type *)v; v = (caddr_t)((name)+(num))
108 #define valloclim(name, type, num, lim) ¥
109 (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
110 valloclim(inode, struct inode, ninode, inodeNINODE);
111 valloclim(file, struct file, nfile, fileNFILE);
112 valloclim(proc, struct proc, nproc, procNPROC);
113 valloclim(text, struct text, ntext, textNTEXT);
114 valloc(cfree, struct cblock, nclist);
115 valloc(callout, struct callout, ncallout);
116 valloc(swapmap, struct map, nswapmap = nproc * 2);
117 valloc(argmap, struct map, ARGMAPSIZE);
118 valloc(kernelmap, struct map, nproc);
119 valloc(mbmap, struct map, nmbclusters/4);
120 valloc(namecache, struct namecache, nchsize);
177 ncmap = (maxmem*NBPG - ((int)(v + bufpages*CLBYTES) &~ 0x80000000)) /
178 (CLBYTES + sizeof(struct cmap)) + 2;
179 valloclim(cmap, struct cmap, ncmap, ecmap);
パラメタを参照して各構造を
割り当て(v6では配列だった)
現在のvからmaxmemまでの
アドレスに応じたcmapを確保
35. ページの割り当て:memall()
• sys/vm_mem.c
159 /*
160 * Allocate memory -
161 *
162 * The free list appears as a doubly linked list
163 * in the core map with cmap[0] serving as a header.
164 */
165 memall(pte, size, p, type)
/* */
166 register struct pte *pte;
167 int size;
168 struct proc *p;
169 {
186 for (i = size; i > 0; i -= CLSIZE) {
210 case CDATA:
211 rpte = dptopte(rp, c->c_page);
212 break;
213
222 switch (type) {
233 case CDATA:
234 c->c_page = vtodp(p, ptetov(p, pte));
235 c->c_ndx = p->p_ndx;
236 break;
272 pf = cmtopg(curpos);
273 for (j = 0; j < CLSIZE; j++)
274 *(int *)pte++ = pf++;
275 c->c_free = 0;
276 c->c_gone = 0;
277 if (c->c_intrans || c->c_want)
278 panic("memall intrans|want");
279 c->c_lock = 1;
280 c->c_type = type;
281 }
282 splx(s);
283 return (size);
284 }
36. 37. 構造:pte
• vax/pte.h
20 struct pte
21 {
22 unsigned int pg_pfnum:21, /* core page frame number or 0 */
23 :2,
24 pg_vreadm:1, /* modified since vread (or with _m) */
25 pg_swapm:1, /* have to write back to swap */
26 pg_fod:1, /* is fill on demand (=0) */
27 pg_m:1, /* hardware maintained modified bit */
28 pg_prot:4, /* access control */
29 pg_v:1; /* valid bit */
30 };
pfnumV prot M 0 soft
59 #define PG_NOACC 0
60 #define PG_KW 0x10000000
61 #define PG_KR 0x18000000
62 #define PG_UW 0x20000000
63 #define PG_URKW 0x70000000
64 #define PG_URKR 0x78000000
38. 処理:pageout()
• sys/vm_page.c +696
696 loop:
705 (void) splbio();
706 if (bclnlist != NULL) {
707 (void) spl0();
708 cleanup();
709 goto loop;
710 }
711 sleep((caddr_t)&proc[2], PSWP+1);
712 (void) spl0();
713 count = 0;
714 pushes = 0;
715 while (nscan < desscan && freemem < lotsfree) {
720 if (checkpage(fronthand, FRONT))
721 count = 0;
722 if (checkpage(backhand, BACK))
723 count = 0;
724 cnt.v_scan++;
725 nscan++;
726 if (++fronthand >= maxhand) {
727 fronthand = 0;
728 cnt.v_rev++;
729 if (count > 2) {
735 goto loop;
736 }
737 count++;
738 }
739 if (++backhand >= maxhand)
740 backhand = 0;
741 }
742 goto loop;
proc[2]はpager,メモリが不足すると
wakeupされる
Fronthand.backhandを++しながら一
定のpageをスキャンする
fronthand
backhand
maxhand/0
39. cmap[hand]がcheckの対象
処理:checkpage()
• sys/vm_page.c +774
774 c = &cmap[hand];
775 if (c->c_lock || c->c_free)
776 return (0);
777 switch (c->c_type) {
779 case CSYS:
780 return (0);
782 case CTEXT:
783 xp = &text[c->c_ndx];
784 rp = xp->x_caddr;
785 v = tptov(rp, c->c_page);
786 pte = tptopte(rp, c->c_page);
787 break;
789 case CDATA:
790 case CSTACK:
791 rp = &proc[c->c_ndx];
792 while (rp->p_flag & SNOVM)
793 rp = rp->p_xlink;
794 xp = rp->p_textp;
795 if (c->c_type == CDATA) {
796 v = dptov(rp, c->c_page);
797 pte = dptopte(rp, c->c_page);
798 } else {
799 v = sptov(rp, c->c_page);
800 pte = sptopte(rp, c->c_page);
801 }
802 break;
803 }
cmapのc_typeに用途が記録
実メモリcmap[hand]が参照している
pteを特定
40. 41. 処理:checkpage()
• sys/vm_page.c +813
813 if (pte->pg_v) {
814 if (whichhand == BACK)
815 return(0);
816 pte->pg_v = 0;
817 if (anycl(pte, pg_m))
818 pte->pg_m = 1;
819 distcl(pte);
820 if (c->c_type == CTEXT)
821 distpte(xp, (unsigned)vtotp(rp, v), pte);
822 if ((rp->p_flag & (SSEQL|SUANOM)) == 0 &&
823 rp->p_rssize <= rp->p_maxrss)
824 return (0);
825 }
42. 処理:checkpage()
• sys/vm_page.c +850
850 if (dirtycl(pte)) {
856 if (rp->p_flag & (SLOCK|SWEXIT))
857 return (0);
858 /*
859 * Limit pushes to avoid saturating
860 * pageout device.
861 */
862 if (pushes > maxpgio / RATETOSCHEDPAGING)
863 return (0);
864 pushes++;
882 loop2:
883 (void) splbio();
884 if (bclnlist != NULL) {
885 (void) spl0();
886 cleanup();
887 goto loop2;
888 }
889 if (bswlist.av_forw == NULL) {
890 bswlist.b_flags |= B_WANTED;
891 sleep((caddr_t)&proc[2], PSWP+2);
892 (void) spl0();
900 goto top;
901 }
902 (void) spl0();
904 MLOCK(c);
905 uaccess(rp, Pushmap, &pushutl);
909 pte->pg_m = 0;
910 distcl(pte);
911 if (c->c_type == CTEXT) {
912 xp->x_poip++;
913 distpte(xp, (unsigned)vtotp(rp, v), pte);
914 } else
915 rp->p_poip++;
916 v = kluster(rp, v, pte, B_WRITE, &klsize, klout,
(daddr_t)0);
917 if (klsize == 0)
918 panic("pageout klsize");
919 daddr = vtod(rp, v, &pushutl.u_dmap,
&pushutl.u_smap);
920 (void)swap(rp, daddr, ptob(v), klsize * ctob(CLSIZE),
921 B_WRITE, B_DIRTY, swapdev, pte->pg_pfnum);
929 return (1); /* well, it'll be free soon */
930
931 }
43. アドレス変換例外
• machine/trap.c
58 trap(sp, type, code, pc, psl)
59 int sp, type;
60 unsigned code;
61 int pc, psl;
73 switch (type) {
75 default:
76 printf("trap type %d, code = %x, pc = %x¥n", type, code, pc);
77 type &= ~USER;
78 if ((unsigned)type < TRAP_TYPES)
79 panic(trap_type[type]);
80 panic("trap");
82 case T_PROTFLT+USER: /* protection fault */
83 i = SIGBUS;
84 break;
119
120 case T_PAGEFLT: /* allow page faults in kernel mode */
121 case T_PAGEFLT+USER: /* page fault */
122 i = u.u_error;
123 pagein(code, 0);
124 u.u_error = i;
125 if (type == T_PAGEFLT)
126 return;
127 goto out;
44. 処理:pagein()
• sys/vm_page.c
68 pagein(virtaddr, dlyu)
100 vsave = v = clbase(btop(virtaddr));
101 p = u.u_procp;
108 pte = vtopte(p, v);
198 bnswap = bncache = bn = vtod(p, v, &u.u_dmap,
&u.u_smap);
199 dev = swapdev;
219 opte = *pte;
311 pte->pg_prot = opte.pg_prot;
314 distcl(pte);
377 /*
378 * Fill from swap area. Try to find adjacent
379 * pages to bring in also.
380 */
381 v = kluster(p, v, pte, B_READ, &klsize,
382 (type == CTEXT) ? kltxt :
383 ((p->p_flag & SSEQL) ? klseql : klin), bn);
384 splx(sk);
385 /* THIS COULD BE COMPUTED INCREMENTALLY... */
386 bncache = bn = vtod(p, v, &u.u_dmap, &u.u_smap);
387 }
388
389 distcl(pte);
390 swerror = swap(p, bn, ptob(v), klsize * ctob(CLSIZE),
391 B_READ, B_PGIN, dev, 0);
!NOTICE!
45. 第三世代UNIX
• Mach由来の仮想記憶に置き換え
– 仮想記憶は
• f(vnode, offset) → (p, vaddr)
• f(p, vaddr) → (vnode,offset)
– 広範囲に影響
• 共用テキスト
• 共有メモリ
• バッファキャッシュ
• Demand loading
• ForkのCopy On Write化
• Linux,Solaris,BSDで実装は異なるが、考え方は同じ