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

概要

  • mm/memory.cにて定義
  • 引数で渡されたアドレスに対応するページテーブルエントリが存在するか調べ、存在しない場合は確保・設定し、それを返す

引数

  • mm--メモリディスクリプタ
  • pmd--ページミドルディレクトリ
  • address--仮想アドレス

実装

pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address) {

	if (!pmd_present(*pmd)) {
  • ページミドルディレクトリpmdがメモリ上に存在しない場合:
  • ページミドルディレクトリpmdがメモリ上に存在する場合は1を返す。そうでない場合は0を返す
		struct page *new;
		spin_unlock(&mm->page_table_lock);
  • スピンロックmm->page_table_lockの開放を行う。プリエンプション機能を有効にし、可能であれば自ら積極的にプリエンプション(実行権の移譲を行うこと)する
		new = pte_alloc_one(mm, address);
  • ページテーブルエントリ(PTE)の為にページを1つだけ確保・初期化して返す
		spin_lock(&mm->page_table_lock);
  • スピンロックmm->page_table_lockの取得を試みる
    • ロックの取得に失敗した場合は待ち状態に入る
    • 詳細はspin_lock()/linux2.6を参照
		if (!new)
			return NULL;
  • ページの取得に失敗した場合はNULLを返して終了
		/*
		 * Because we dropped the lock, we should re-check the
		 * entry, as somebody else could have populated it..
		 */
		if (pmd_present(*pmd)) {
  • 競合を防ぐために再度、pmdをチェック:
  • ページミドルディレクトリpmdがメモリ上に存在する場合は1を返す。そうでない場合は0を返す
			pte_free(new);
  • ページnewをCPU固有のページキャッシュ(hotキャッシュ)へ解放する
			goto out;
		}
		mm->nr_ptes++;
  • メモリディスクリプタ内の総ページテーブルエントリ数をインクリメントする
		inc_page_state(nr_page_table_pages);
		pmd_populate(mm, pmd, new);
	}

out:

	return pte_offset_map(pmd, address);

}

呼出元


履歴

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

コメント



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