Linuxの備忘録とか・・・(目次へ)Linuxの備忘録とか・・・(目次へ)コピーオンライトforkで親が子を作成すると、親の複製として子が作成される。通常execで新規のプロセスと差し替えられる(正確にはプロセスは同じだが中身が異なる。)わけで、一見無駄に思える処理の流れだが、親の複製を作成して動作させるシステムもあるわけで、この流れの延長線上にexecでの新規プロセス作成があるものと認識している。親の複製を低負荷にする手法がコピーオンライトまたはCOWと呼ばれるものである。(COWってカウって呼ぶのかな?それともC,O,Wかな?)forkで子プロセスを作成すると、子は独自のページテーブルおよびmm_struct等の構造体を確保する。中身は親の内容を複写する。これだけで子は親と同じメモリー空間を共有することになる。親の複製と言われる所以である。通常、親/子はメモリに書き込んだ値は、互いに影響してはならない独自のプロセスである。コピーオンライトは、親のmm_area_structにおいて書込みメモリー空間を、ページテーブルでは書込み不可とする。子もこのメモリー空間は親と同じように認識することになる。どちらかのプロセスが書き込みを行うと、ページフォルトが発生し、そのページの参照カウンターが複数の場合(共有している。)、COWとして認識する。新規にページを確保し、元ページの内容を確保したページに複写し、そこに書き込み処理を行う。元ページの参照カウンタをデクリメントし、もう一つのプロセスがこのページを書き込みをおこなうと、参照カウントから自分しか参照していないことになると、そのページを書込み可とし、そのページに書き込み処理を行うという具合である。do_page_fault関数にハンドルされる。そこからユーザプロセスかカーネルプロセスのエラーか?とかカーネル空間でのエラーか、ユーザ区間でのエラーか?とかのチェックが行われ、かかる処理はhandle_pte_fault関数へと渡ってくる。ここではまずページテーブルエントリーのページが実メモリ上に存在するかチェックする。新規にallocされたメモリー空間とかスワップアウトされたケースがこれにあたる。なければ、そのページは実メモリ上にあるということだ。write_accessで書き込みで、しかもページテーブルが書き込み不可故にページフォルトが発生したわけだ。do_wp_page関数がコールされる。0;}do_wp_page関数でCOWが行われる。ここでは無名ページとメモリーマップのページについてCOWの処理がなされていて、(メモリーマップかかる処理は今ひとつ・・・。)無名ページについて。問題のページを取得する。(この関数ではページ有るということでの処理であって、そのあとのページが取得できなければのif文のチェックの意味が今ひとつ分かりません。カーネルにはそのようなエラーチェックが沢山ありますが・・・、でたぶんページフォルトの処理では、スワップインとかメモリーマップとかで、ファイル読み込みが発生するわけで、その時にプロセスが切り替わるための処理だと勝手に解釈することにしています。)PageAnon関数で無名ページかのチェックを行う。これはpage->mappingにPAGE_MAPPING_ANONビットがたっているかどうかで判断する。無名ページだとcan_share_swap_page関数をコールし、ここで上で述べたようなCOWを行うかどうかのチェックを行う。can_share_swap_page関数ではpage->_mapcountをチェックするが、can_share_swap_pageのshare_swapと名が示すようにswap処理のキャッシュを考慮する必要がある。スワップ処理ではスワップスラッシングを防ぐため、スワップアウト処理ではいきなりファイルに書き込まず、ページをいったんスワップキャッシュ状態に置くため、それを足しこんだものでチェックしているよう。それらが1つしか無い0をそれ以外なら-1をreuseにセットするようになっている。reuseが0でないなら、そのページに書き込むことになる。そのページテーブルにアクセスフラグ、ダーティフラグ、書き込みフラグを設定している。reuseが0の場合、COWとなる。新しいページを確保して、cow_user_page関数で元ページの内容を新しいページに複写し、そのページの書き込み可等のフラグを設定し、新しいページをvm_area_structのリストに繋いだり、また反対に古いページはそのリストから削除したりとしている。ノースAdsense広告情報が設定されていません。