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

概要

  • mm/memory.cにて定義
  • ページフォルト処理
  • 引数で渡されたプロセスのメモリディスクリプタへ新しいページフレームを割り当てる
    • 割り当てに成功すると1または2を返す
      • 1:副ページフォルト--カレントプロセスがブロックされることなくページフォルト処理できたことを意味する
      • 2:主ページフォルト--ページフォルトがカレントプロセスを待ち状態(ディスクからデータを読み込むための時間)にする必要があることを表す
    • -1:メモリ不足
    • 0:その他のエラー

引数

  • mm--ページフォルト例外を起こしたプロセスのメモリディスクリプタ
  • vma--メモリリージョン
  • address--例外を発生した仮想アドレス
  • write_access--読み取り/書き込みアクセス
    • 1なら書き込みが行われた

実装

/*

* By the time we get here, we already hold the mm semaphore
*/

int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,

	unsigned long address, int write_access)

{

	pgd_t *pgd;
	pmd_t *pmd;
	__set_current_state(TASK_RUNNING);
	pgd = pgd_offset(mm, address);
  • addressに対応するページグローバルディレクトリを返す
	inc_page_state(pgfault);
	if (is_vm_hugetlb_page(vma))
		return VM_FAULT_SIGBUS;	/* mapping truncation does this. */
	/*
	 * We need the page table lock to synchronize with kswapd
	 * and the SMP-safe atomic PTE updates.
	 */
	spin_lock(&mm->page_table_lock);
  • スピンロックmm->page_table_lockの取得を試みる
    • ロックの取得に失敗した場合は待ち状態に入る
    • 詳細はspin_lock()/linux2.6を参照
	pmd = pmd_alloc(mm, pgd, address);
  • 仮想アドレスaddressに対応するページミドルディレクトリを返す
	if (pmd) {
		pte_t * pte = pte_alloc_map(mm, pmd, address);
  • addressに対応するページテーブルエントリが存在するか調べ、存在しない場合は確保・設定し、それを返す
		if (pte)
			return handle_pte_fault(mm, vma, address, write_access, pte, pmd);
  • addressに対応するページテーブルエントリ(PTE)を検査し、新しいページフレームの確保方法を決定する
	}
	spin_unlock(&mm->page_table_lock);
  • スピンロックmm->page_table_lockの開放を行う。プリエンプション機能を有効にし、可能であれば自ら積極的にプリエンプション(実行権の移譲を行うこと)する
	return VM_FAULT_OOM;
  • VM_FAULT_OOMはメモリ不足であったことを意味する

}

呼出元


履歴

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

コメント



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