Show page source of internal24-185-空間の複製 #24207

[[PageNavi(internal24-navi)]]

{{{ comment
h2w-title:空間の複製
}}}

 

= 空間の複製 = #SECTION04340000000000000000

仮想空間の複製はdup_mmap関数にて行う. 
この関数はforkシステムコールでのみ利用される.

この関数では、仮想空間の複製のみを行うが、物理メモリの複製は行わず
二つの空間で共有させる。物理メモリの複製はどちらかの仮想空間に対し、
書きこみがあるまで遅延させる。

その実現のため、二つの仮想空間のPTEにおいて書きこみ禁止モード
(コピーオンライトモード)にしておく。
書きこみ禁止であっても、この空間に対する読み込み処理は可能である。

{{{
dup_mmap(メモリ管理構造体mm_struct)
{
        for (カレントプロセスのmm_structに登録されている全ての仮想空間管理構造体vm_area_structに対して) {
                新しい仮想空間管理構造体vm_area_structを確保
                カレントの仮想空間管理構造体vm_area_structの情報を、
                  新しい仮想空間管理構造体vm_area_structにコピー
                新しい仮想空間管理構造体vm_area_structを、引数で渡された
                  メモリ管理構造体mm_structに登録
                if(ファイルマップされた仮想空間域なら) {
                        一つのファイルを共有しているしていることを管理する
             ため、仮想空間管理構造体をvm_area_struct相互にリンクしておく
                }
                PGD,PTEをコピー(copy_page_range関数)。
        }
}
}}}

この関数ではPTEのみのコピーのみをおこない、ページの実体コピーは行わない。
空間が個別マップで、かつ書きこみ可能ならコピーオンライトモードでマップする.

{{{
copy_page_range(コピー先メモリ管理構造体vm_area_struct、
                コピー元メモリ管理構造体vm_area_struct、 仮想空間管理構造体)
{
        コピー元の先頭PGDを求める(pgd_offset関数)
        コピー先の先頭PGDを求める(pgd_offset関数)
        for(仮想空間のある間、全てのコピー元PGDに対し) {
                if (コピー元のPGDが空)continue
                if (コピー先のPGDが空)
                        PMDテーブルを確保、登録(pmd_alloc関数)
                コピー元のPGDが指す先頭PMDを求める(pmd_offset関数)
                コピー先のPGDが指すPMDを求める(pmd_offset関数)
                for(コピー元PGD内の全てのPMDに対し) {
                        if (コピー元のPMDが空)continue
                        if (コピー先のPMDが空)
                                PTEテーブルを確保、登録(pte_alloc関数)
                        コピー元のPMDが指す先頭PTEを求める(pte_offset関数)
                        コピー先のPMDが指すPTEを求める(pte_offset関数)
                        for(コピー元PGD内の全てのPTEに対し) {
                                if (コピー元のPTEが空)continue
                                if (PTEが有効でない(!pte_present関数) ) {
                                        スワップ参照数を1増やす
                     (swap_duplicate関数)
                                        コピー元のPTEの内容をコピー先のPTEに
                     複製(set_pte関数)
                                        contnue
                                }
                                if (個別マップ、かつ書きこみ可能の空間) {
                                        コピー元のPTEの書き込み可のビットを
                     落とし(pte_wrprotect関数)、コピー元の
                     PTEに下記戻しておく(set_pte関数)
                                }
                                if (共有モードでの複製なら) {
                                        PTEからdirtyビットを落とす(pte_mkclean関数)
                                }
                                PTEにアクセスビットを立てる(pte_mkclean関数)
                                コピー先のPTEにコピー(set_pte関数)
                        }
                }
        }

}
}}}

下図のように、書き込み可能なページをマップするPTEも全て、
書き込み不可(Wビットオフ)としてマップし直す。

 [[Embed(internal24-images:img71.gif)]]
 

----

''(NIS)HirokazuTakahashi [[BR]]
2000年12月09日 (土) 23時55分06秒 JST''1

[[PageNavi(internal24-navi)]]