仮想記憶入門 BSD-4.3を例題に

1,932 views

Published on

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,932
On SlideShare
0
From Embeds
0
Number of Embeds
56
Actions
Shares
0
Downloads
26
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

仮想記憶入門 BSD-4.3を例題に

  1. 1. UNIX V6 セミナー (4)@magoroku152013/5/11
  2. 2. 今日の内容• 過去:UNIX v6, 未来:4.4BSDとの関連• 仮想記憶の空間構成• スワッピングとページング• 4.3BSDを例にした仮想記憶管理の解析• 参考資料– Freebsd-53-kernel-mm.pptx 七誌さん
  3. 3. 過去:UNIX V6, 未来:4.4BSDとの関連4.3BSD
  4. 4. カーネルのメモリ構成※アドレスは上を0としたため、本とは上下反転カーネルユーザー04GB1. 常駐型FreeBSDなどカーネルユーザー2. 切替型UNIX V6などhttp://sdrv.ms/160BJhK より
  5. 5. 常駐型カーネルプロセスA04GB永続マップカーネルプロセスB• カーネルが同じアドレスに常駐するタスクスイッチで入替http://sdrv.ms/160BJhK より
  6. 6. 切替型04GBカーネルプロセスA• 広いメモリ空間を使うことができるプロセスBhttp://sdrv.ms/160BJhK より
  7. 7. データの受け渡しカーネルユーザー04GB1. 常駐型直接参照(高速)2. 切替型特殊命令でコピー(遅い)カーネルユーザー※カーネルは自由にユーザーのメモリを読めるが、逆は不可http://sdrv.ms/160BJhK より
  8. 8. メモリ管理から見た4.3BSDの特徴• UNIX v{6|7}の空間を切り替え型から常駐型に変更• On demand paging– clock algorithm• One handからTwo handへの変更• 共有メモリはtextのみ– COW, shm, 動的なbufなどは存在しない• 限定的なカーネルメモリアロケータ– mbufのみ• VAX-11依存の実装– PTEにOSの管理情報を置く– 参照ビットのエミュレーション
  9. 9. 4.3BSDを理解する意味• UNIXの系譜では第2世代の最後– 第一世代 UNIX v{6|7} 切り替え型– 第二世代 UNIX 32v~4.3BSD 常駐型– 第三世代 Mach, 4.4BSD他 +広義の単一レベル記憶• 仮想空間にvnode,offsetで表現可能なファイルをマップ可能になる• 次の事項の理解に有用– MMUの仕組み– ページングの原理と実装– 実メモリ管理• UNIX v{6|7}の構成の変化は少なく連続性がある– ファイル構成・関数構成
  10. 10. 仮想記憶の空間構成
  11. 11. 空間の構成• 単一仮想空間– 一枚の空間を仮想化する– 一枚の空間に複数のプロセスが同居– メモリの拡張が主な目的• 多重仮想空間– 複数の空間を仮想化する– 一枚の空間に1個のプロセスを配置– システムの保護
  12. 12. 空間構成多重仮想空間単一仮想空間
  13. 13. 多重仮想空間の管理構造ユーザ物理メモリ管理構造仮想-物理アドレス変換表カーネル
  14. 14. アドレス変換機構• アドレスの変換単位はページ– 数Kbyte程度– Aligned• アドレスの変換表をOSが用意してCPU(MMU)に通知• MMUが仮想アドレスを実アドレスに変換変換表CR
  15. 15. アドレス変換表
  16. 16. アドレスと変換表の関係
  17. 17. 2レベル変換表
  18. 18. 仮想空間の利点• 複数の独立したアドレス空間– アドレス空間の間でメモリの書き換え・参照ができない– プログラムAのバグがプログラムBに影響を与えない– プログラムAのメモリをプログラムBから参照できない• 全てのプログラムが同じアドレスを利用可能– リロケータブルである必要がない– コンパイラ・リンカの負担が少ない
  19. 19. スワッピングとページング
  20. 20. スワッピング• スワップアウト– 最も優先度の低いプログラムを選択し– プログラムをスケジュールの対象から外す– プログラムのメモリ全体をスワップデバイスに退避(write)• スワップイン– 実行するプロセスがスワップアウトさせていたら– メモリを確保-不足したら他のプロセスをスワップアウト– スワップデバイスに退避してあるメモリイメージをメモリに復元(read)– プログラムをスケジュールの対象に含める• スワッピングとページングは明確に区別せずに使われる場合があるので注意
  21. 21. スワッピングの特徴• プログラム全体を退避・復元– アドレス空間の拡張に伴ってI/O量が増加– 大きなコストを払ってスワップインしても、その後の挙動は予想できない• メモリ・フラグメンテーションの解消手段– UNIX v6等の実装• ページングと比較してハードウェアの負担が少ない
  22. 22. ページング• ページアウト1. メモリが不足2. 最近使われていない物理メモリ(ページ)を特定3. 物理メモリが仮想メモリとして利用されていたら変換対象から外す4. 物理メモリをページングデバイスに退避• ページイン1. 割り当て済の仮想メモリをプログラムが参照2. アドレス変換例外で割り込みが発生しOSに制御が移る3. OSが該当プロセス+アドレスから退避済の物理メモリ(ページ)を特定する4. 物理メモリを読み込んで仮想メモリから変換可能とする5. 割り込みから復帰
  23. 23. ページングの特徴• 一般的な運用では– 仮想空間の総量 > 物理メモリ– 物理メモリの奪い合い– メモリ参照に局所性が有る場合• ゆっくり奪い合う→変換例外とその対応のコストは無視できる– メモリ参照に局所性が無い場合• はげしく奪い合う→変換例外とその対応コストが無視できない• 局所的な参照を前提として使われていないメモリの特定が必要– 最近利用されていないメモリは将来も利用されない可能性が高い– どうやって?
  24. 24. LRU - Least Recently Used• 「最近使われていないメモリは、将来も使われない可能性が高い」事を前提とする• メモリの参照頻度を記録して、最近使われていないメモリを予想する– 近年のCPUは参照の有無をアドレス変換表にHWが記録する• X86, ARMなど (除くVAX-11)• 多くは1bit(参照の有無)のみを記録
  25. 25. 仮想記憶の構成4.3BSDを例に
  26. 26. 解析の対象• 4.3BSD– 1986年、カルフォルニア大学バークレー校で開発・配布された近代UNIX– 仮想記憶・TCP/IP・拡張ファイルシステムが特徴– ソースの入手にはAT&T UNIXのライセンスが必要– 今回は以下を利用http://www.tamacom.com/tour-j.html
  27. 27. 4.3BSD VAX-11の空間構成• 32bit = 4Gbyteの空間を4分割(4セグメント)unusedkernelUser stackUser TextUser Data0x4000.0000x0000.0000x8000.0000xC000.0000xFFFF.FFFFP0P1SystemReserved• P0,P1 にUserプログラム• P1にはKernel Stack・Uも配置• System リージョンにカーネルを配置• copy{in|out}は同一空間の転送1142 /*1143 * Copy specified amount of data from user space into the kernel1144 * Copyin(from, to, len)1145 * r1 == from (user source address)1146 * r3 == to (kernel destination address)1147 * r5 == length1148 */1149 .align 11150 JSBENTRY(Copyin, R1|R3|R5)1151 cmpl r5,$(NBPG*CLSIZE) # probing one page or less ?1152 bgtru 1f # no1153 prober $3,r5,(r1) # bytes accessible ?1154 beql ersb # no1155 movc3 r5,(r1),(r3)1156 /* clrl r0 # redundant */1157 rsb
  28. 28. VAX-11の仮想記憶• 512byte/1ページ 9bit• 32bitのアドレス幅上位2bitがリージョン– P0=00,P1=01,S=1032bitPage offset9bitSegmant2bitVirtual Page Number21bit
  29. 29. セグメントとページテーブル• 各セグメントはPTEの配列=ページテーブルとして表現– セグメントベースレジスタ:SEGBR– セグメントリミットレジスタ:SEGLR• 各リージョンは2^21個のページを持つ– 1リージョン8MBのページテーブルが必要– P0,P1,Sで24Mbyte/プロセス必要– P0,P1のページテーブルはSのカーネル仮想に配置
  30. 30. セグメント用のレジスタ• root/machine/mtpr.h18 #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 */unusedkernelUser stackKernal stackUser TextUser DataP0BRP1BRSBRP0LRP1LRSLR
  31. 31. セグメントレジスタの設定• root/GENERIC/sys/vmmac.h88 #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. 32. 実メモリ(ページ)管理4.3BSDを例に
  33. 33. 構造:cmap• h/cmap.h27 struct cmap28 {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. 34. Cmapの初期化• root/vax/machdep.c105 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. 35. ページの割り当て:memall()• sys/vm_mem.c159 /*160 * Allocate memory -161 *162 * The free list appears as a doubly linked list163 * 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;213222 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. 36. ページング
  37. 37. 構造:pte• vax/pte.h20 struct pte21 {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 soft59 #define PG_NOACC 060 #define PG_KW 0x1000000061 #define PG_KR 0x1800000062 #define PG_UW 0x2000000063 #define PG_URKW 0x7000000064 #define PG_URKR 0x78000000
  38. 38. 処理:pageout()• sys/vm_page.c +696696 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をスキャンするfronthandbackhandmaxhand/0
  39. 39. cmap[hand]がcheckの対象処理:checkpage()• sys/vm_page.c +774774 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. 40. プロセス空間と物理メモリの関連cmap[] 物理メモリproc []c_ndxc_ndxp_tsizep_p0brc_pagecmap[n]proc[m]User stackUser TextUser Data0x4000.0000x0000.0000x8000.000P0P1#define dptov(p, i) ((unsigned)(stoc(ctos((p)->p_tsize)) + (i)))#define dptopte(p, i) ((p)->p_p0br + ((p)->p_tsize + (i)))pte[]
  41. 41. 処理:checkpage()• sys/vm_page.c +813813 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. 42. 処理:checkpage()• sys/vm_page.c +850850 if (dirtycl(pte)) {856 if (rp->p_flag & (SLOCK|SWEXIT))857 return (0);858 /*859 * Limit pushes to avoid saturating860 * 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 } else915 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, itll be free soon */930931 }
  43. 43. アドレス変換例外• machine/trap.c58 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;119120 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. 44. 処理:pagein()• sys/vm_page.c68 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 adjacent379 * 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 }388389 distcl(pte);390 swerror = swap(p, bn, ptob(v), klsize * ctob(CLSIZE),391 B_READ, B_PGIN, dev, 0);!NOTICE!
  45. 45. 第三世代UNIX• Mach由来の仮想記憶に置き換え– 仮想記憶は• f(vnode, offset) → (p, vaddr)• f(p, vaddr) → (vnode,offset)– 広範囲に影響• 共用テキスト• 共有メモリ• バッファキャッシュ• Demand loading• ForkのCopy On Write化• Linux,Solaris,BSDで実装は異なるが、考え方は同じ

×