このページを編集する際は、編集に関する方針に従ってください。

概要

  • mm/rmap.cにて定義
  • anonymousメモリ(無名メモリ)の準備を行う
    • 引数で渡されたメモリリージョンにマッピングされたanonymousメモリが無い場合は確保し、anonymousメモリのリストに追加する
    • 問題が発生しなかった場合は0を返し、問題が発生した場合はエラーコードを返す
    • anonymousメモリ(無名メモリ)とはファイルと直接関連づけられていないページ(ページ群)を指す
      • プロセスのヒープ領域、スタック、Copy-On-Writeページに対して使用される
      • Copy-On-Writeページ:ゼロページを割り当てておいて、実際に使用する際に例外を発生させ、ページの割り当てを遅延する

引数

実装

/* This must be called under the mmap_sem. */

int anon_vma_prepare(struct vm_area_struct *vma) {

	struct anon_vma *anon_vma = vma->anon_vma;
  • vmaのanon_vmaを取得しanon_vmaに設定
  • anonymousメモリ(無名メモリ)
    • anonymousメモリ(無名メモリ)とはファイルと直接関連づけられていないページ(ページ群)を指す
      • プロセスのヒープ領域、スタック、Copy-On-Writeページに対して使用される
      • Copy-On-Writeページ:ゼロページを割り当てておいて、実際に使用する際に例外を発生させ、ページの割り当てを遅延する
    • 詳細はanon_vma/linux2.6を参照
	might_sleep();
	if (unlikely(!anon_vma)) {
  • vmaからanon_vmaが取得できなかった場合:
		struct mm_struct *mm = vma->vm_mm;
  • vmaのメモリディスクリプタを取得しmmに設定
		struct anon_vma *allocated, *locked;
  • anonymousメモリ(無名メモリ)
    • anonymousメモリ(無名メモリ)とはファイルと直接関連づけられていないページ(ページ群)を指す
      • プロセスのヒープ領域、スタック、Copy-On-Writeページに対して使用される
      • Copy-On-Writeページ:ゼロページを割り当てておいて、実際に使用する際に例外を発生させ、ページの割り当てを遅延する
    • 詳細はanon_vma/linux2.6を参照
		anon_vma = find_mergeable_anon_vma(vma);
  • vmaのリストからanon_vmaを探す
  • vmaに連結できるメモリリージョンのanon_vmaを見つけ、そのポインタを返す
		if (anon_vma) {
  • anon_vmaが見つかった場合:
			allocated = NULL;
			locked = anon_vma;
			spin_lock(&locked->lock);
  • スピンロックlocked->lockの取得を試みる
    • ロックの取得に失敗した場合は待ち状態に入る
    • 詳細はspin_lock()/linux2.6を参照
		} else {
  • anon_vmaが見つからなかった場合:
			anon_vma = anon_vma_alloc();
  • スラブアロケータのキャッシュanon_vma_cachepからメモリ領域を確保する
			if (unlikely(!anon_vma))
				return -ENOMEM;
  • メモリ領域を確保できなかった場合、-ENOMEMを返して終了
			allocated = anon_vma;
			locked = NULL;
		}
		/* page_table_lock to protect against threads */
		spin_lock(&mm->page_table_lock);
  • スピンロックmm->page_table_lockの取得を試みる
    • ロックの取得に失敗した場合は待ち状態に入る
    • 詳細はspin_lock()/linux2.6を参照
		if (likely(!vma->anon_vma)) {
  • vma->anon_vmaが空である場合:
			vma->anon_vma = anon_vma;
  • 取得したanon_vmaをvma->anon_vmaに設定する
			list_add(&vma->anon_vma_node, &anon_vma->head);
  • リストanon_vma->headの前にエントリvma->anon_vma_nodeを追加する
			allocated = NULL;
		}
		spin_unlock(&mm->page_table_lock);
  • スピンロックmm->page_table_lockの開放を行う。プリエンプション機能を有効にし、可能であれば自ら積極的にプリエンプション(実行権の移譲を行うこと)する。
		if (locked)
			spin_unlock(&locked->lock);
  • スピンロックlocked->lockの開放を行う。プリエンプション機能を有効にし、可能であれば自ら積極的にプリエンプション(実行権の移譲を行うこと)する。
		if (unlikely(allocated))
			anon_vma_free(allocated);
  • allocatedがNULLではない場合、allocatedをスラブアロケータへ解放する
	}
	return 0;

}

呼出元


履歴

  • 作者:ひら
  • 日付:2005/8/27
  • 対象:2.6.10
    更新日更新者更新内容

コメント



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-11-24 (火) 07:11:02 (2861d)