linux2.2 on x86 での メモリ管理機構

40
Linux2.2 on x86 でで ででででででで Dec 2001 でで でで

Upload: elisha

Post on 02-Feb-2016

76 views

Category:

Documents


0 download

DESCRIPTION

Linux2.2 on x86 での メモリ管理機構. Dec 2001 安田 泰勲. 目次. x86 アーキテクチャにおけるメモリ管理 セグメンテーションとページング アドレッシング Linux におけるメモリ管理 Linux のメモリ管理の用語 アドレス空間モデルとデータ構造 ページングの流れ ページング処理 (demand paging, copy on write…) メモリ領域管理 (buddy system, slab allocator). x86 アーキテクチャの メモリ管理機構. x86 アーキテクチャでは二種類のメモリ管理機構が利用可能 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Linux2.2 on x86  での メモリ管理機構

Linux2.2 on x86 でのメモリ管理機構

Dec 2001安田 泰勲

Page 2: Linux2.2 on x86  での メモリ管理機構

目次

• x86 アーキテクチャにおけるメモリ管理– セグメンテーションとページング– アドレッシング

• Linux におけるメモリ管理– Linux のメモリ管理の用語– アドレス空間モデルとデータ構造– ページングの流れ– ページング処理 (demand paging, copy on write…)– メモリ領域管理 (buddy system, slab allocator)

Page 3: Linux2.2 on x86  での メモリ管理機構

x86 アーキテクチャのメモリ管理機構

• x86 アーキテクチャでは二種類のメモリ管理機構が利用可能– セグメンテーション機構

• 複数のタスク ( プロセス ) が相互に干渉しないで同じプロセッサ上で実行できる様にコード、データ、スタックを分離する機構 (required)

– プロセス (= セグメント ) 毎に異なるリニアアドレス空間を利用

– ページング機構• 従来のデマンドページの仮想記憶システム ( プログラム

の実行環境のページが必要に応じて物理メモリにマップされる ) を使用するための機構 (optional)

– プロセス毎に同じリニアアドレス空間を利用

Page 4: Linux2.2 on x86  での メモリ管理機構

メモリアドレッシング• x86 アーキテクチャでのメモリアドレス

– Physical address( 物理アドレス )• プロセッサがアドレスバス上で指定できるアドレス空間。フ

ラット ( セグメント化されていない ) であり、連続領域 (0x0 -0xFFFFFFFFh) 4G(2^32) バイトの物理アドレス空間が利用可能。

– Linear address( リニアアドレス )• 32bit で表現されるリニアアドレス空間内のページング機構

でのアドレス。物理アドレスと同様にフラットでセグメント化されていない。プロセッサは論理アドレスをリニアアドレスに変換してからメモリにアクセスする。

– Logical address( 論理アドレス )• 16bit のセグメントセレクタと 32bit のオフセットで構成され

るセグメント機構でのアドレス

Segmentation Unit Paging Unit物理アドレスリニアアドレス論理アドレス

Page 5: Linux2.2 on x86  での メモリ管理機構

セグメンテーションとページング

Segmentselector

offset

SegmentDescriptor

LinearAddress

GlobalDescriptorTable

LinearAddressSpace

Directory offsetTable

PageDirectory

Entry

PageTableEntry

Physicaladdress

PageDirectory

Linear addressLogical address

PageTable

Page

CR3

Segmentation Paging

Page 6: Linux2.2 on x86  での メモリ管理機構

x86 用語• 基本フラットモデル

– OS およびアプリケーションは連続したセグメント化されていないアドレス空間を利用する。コードセグメントおよびデータセグメントが1 つの同じリニア アドレス空間にマップされる。

• ページディレクトリ– 4K バイトページに入っている 32bit の PDE( ページディレクトリエ

ントリ ) の配列。 1024 個までの PDE を保持可能。• ページテーブル

– 4K バイトページに入っている 32bit の PTE( ページテーブルエントリ ) の配列。 1024 個までの PTE を保持可能。

• ページ– 4K バイト , 2M バイト , もしくは 4M バイトのフラットなアドレス

空間。メモリはページ単位で扱う。• TLB (Translation Lookaside Buffer)

– PDE, PTE 用のオンチップのキャッシュ。

Page 7: Linux2.2 on x86  での メモリ管理機構

Linux でのセグメンテーションとページングの利用

• Linux ではセグメント機構はほとんど利用せず、ページング機構を利用– セグメント機構とページング機構を両方利用することは冗長– 同じリニアアドレス空間を利用することによってメモリ管理

機構をシンプルにできる– 他のアーキテクチャへの移植性を保つため

• RISC チップには限定的なセグメント機構しか持たない者もある

1 つの大きなセグメント内にプロセス毎に同じ仮想アドレス空間というモデル

Page 8: Linux2.2 on x86  での メモリ管理機構

Linux でのメモリ管理の特徴• 仮想アドレス空間のサポート

– 抽象化したメモリモデルを用いた広大な仮想アドレス空間が利用可能にする

• デマンドページング/コピーオンライト– フリーページを実際のアクセス時に仮想アドレス空間に割り当

てることによって使用効率/パフォーマンスを向上する技術• スワッピング

– フリーページが足りない場合、使用中のページを一時的にスワップ領域に退避し、フリーページを確保することによって実際の物理メモリより多くのメモリを利用可能にする

• 多様なキャッシュのサポート– フリーページを多様なキャッシュに利用することによってパ

フォーマンスを向上する

Page 9: Linux2.2 on x86  での メモリ管理機構

Linux で実装されているキャッシュ

• バッファキャッシュ (buffer cache)– ブロックデバイスから読み書きするデータ用のキャッシュ。

全てのブロックデバイスはバッファキャッシュを経由してデータを取得する。ブロック単位で扱う。デバイス ID とブロック番 号でアクセス。

• ページキャッシュ (page cache)– ディスク上のイメージやデータを読み書きを高速化する (mm

ap した file へのアクセス等 ) 時に利用されるキャッシュ。ページ単位で扱う。ファイル名とオフセットでアクセス。

• スワップキャッシュ (swap cache)– スワップインされてから変更されていないページのページ

テーブルエントリとフラグ ( ページとスワップファイルの情報 ) のキャッシュ。ページ単位で扱う。スワップファイルへの書出しを効率化するために用いる。

Page 10: Linux2.2 on x86  での メモリ管理機構

メモリマップとページテーブル

• ページテーブル– Linux では 64bit アドレス空間に対応できるように 3 段のペー

ジテーブル (PGD, PMD,PTE) を持っている• alpha は 3 段であるためそのまま利用• x86 は 2 段であるため、 PMD は何もしない仮想的なテーブルに

なっている ( メモリ上に存在しない ) 。 x86 ではページテーブルはページング対象外であり、物理メモリ上にマップされたカーネル空間に常に存在する

• メモリマップ– 物理メモリは PAGE_OFFSET(0xC0000000h) 以降にマップ– カーネルは 全てのプロセスの仮想アドレス空間の PAGE_OFFS

ET からストレートマップされる• セグメントのプロテクション機能などの対象外• 1GB 以上の物理メモリを利用する場合には PAGE_OFFSET をずらす

Page 11: Linux2.2 on x86  での メモリ管理機構

Linux のメモリマップ (32bit)プロセス毎の仮想アドレス空間

0x00000000

0x40000000

0xc0000000

heap

stack

*.so mapped

datatext

bss kernel

heap

stack

*.so mapped

datatext

bss

heap

stack

*.so mapped

datatext

bss

物理メモリ

ディスク

FileSystem

Swap

High mem

stackstack

kernel

vmalloc space

stackstack

0xc0000000

0xffffffff

Page 12: Linux2.2 on x86  での メモリ管理機構

2 レベルページング (x86)

Directory OffsetTable

Linear Address

CR3

PageDirectory

Page Table Page

31 22 21 12 11 0

Page 13: Linux2.2 on x86  での メモリ管理機構

3 レベルページング (Linux)

Global Dir OffsetMiddle Dir Table

Linear Address

CR3

Page GlobalDirectory

Page MiddleDirectory

Page Table

Page

※x86 Linux では PMD はメモリ上に存在しない (PGD からのアクセスはスルーして PT にいく )

Page 14: Linux2.2 on x86  での メモリ管理機構

アドレス空間モデル

task_struct

mm

vm_area_structmm_structmmap vm_next

vm_filevm_startvm_end

vm_area_structvm_nextvm_filevm_startvm_end

Physical memory

virtual address space

NULL

NULL

Page cache Swap cache

File system Swap device

PGD

PTE

PTE

pgd

PMD

Page 15: Linux2.2 on x86  での メモリ管理機構

アドレス空間を管理するデータ構造

• struct task_struct – プロセスの情報を保持するデータ

• 伝統的 UNIX での u 構造体を含むすべてのデータ– プロセス毎に一つ

• struct mm_struct– プロセスの仮想アドレス空間を管理するデータ– プロセス毎に一つ

• task_struct からポイントされる

• struct vm_area_struct– プロセスの仮想アドレス空間内のある連続領域を管理するデータ– 仮想アドレス空間毎に複数存在し、それぞれの領域 (vm_area_stru

ct) が線形リスト/ AVL ツリーで連結されている• 先頭のデータは mm_struct からポイントされる

Page 16: Linux2.2 on x86  での メモリ管理機構

アドレス空間の複製

• fork(2) 時に複製– init 以外はすべてこれを利用

• 複製処理の流れ (kernel/fork.c)– 1) 新規に mm_struct{} を確保し、内容は親プロセスのもの

をコピー (copy_ mm())– 2) 親プロセスのもつメモリを全てコピーオンライトで

マップし直す (dup_mmap())• PTE において全てのページを ReadOnly 属性にする

– Read 時 : 問題無し– Write 時 : Page Fault 発生。コピーオンライト処理を実施

Page 17: Linux2.2 on x86  での メモリ管理機構

アドレス空間の生成と解放• execve(2) 時に生成• 生成処理の流れ (fs/exec.c)

– 1) 古い mm_struct の内容を破棄し、初期化する (exec_mmap())

– 2) プログラムをロードし、新しく生成したアドレス空間にmmap する

• vm_area_struct は mmap 処理内 (do_mmap()) で生成される• それ以外の領域についてはデマンドページングで処理される

( ページは割り当てられない )

• exit(2) 時に解放• 解放処理の流れ (kernel/exit.c)

– 1) mm_struct の解放 (exit_mm())

Page 18: Linux2.2 on x86  での メモリ管理機構

ページングの流れPage fault のハンドリング

Does the addressbelong to the processaddress space?

Does the access typematch the memoryregion access right?

Did the exceptionoccur in User Mode?

Legal access:Allocate a newPage frame

Illegal access:Send a SIGSEGVsignal

Kernel bug:Kill the process

YES NO

YES NO YES NO

handle_mm_fault()

Page 19: Linux2.2 on x86  での メモリ管理機構

In interrupt or kernel thread

Address inMemory region

Address couldBelong to userMode stackWrite access

Page is presentRegion iswritable

In user mode

Address is awrong systemcall parameter

Region isreadable orexecutable

Page fault

YES NO

NO YES

YES NO

NOYES

YES NO

YES NO

YESNO

YES NONO YES

Copy on write

DemandPaging

SendSIGSEGV

Kernel processAnd kernel“Oops”

“Fixup code”(typically sendSIGSEGV)

Page 20: Linux2.2 on x86  での メモリ管理機構

ページングの流れページ割り当て (1)

Have a file alreadymapped?

YES

NO

invokedo_swap_page()

invokedo_no_page()

NO

invokedo_anonymous_page()

Write access?

invokevma->vm_ops->no_page()

※2

Allocate a page & 0 clear & Set PTE as writable

YES

Mapped ZERO_PAGE& Set PTE as ReadOnly

NO ※1

Demandpaging

Is the PTE empty?

Is the PTE present?NO

※3

YES

Page 21: Linux2.2 on x86  での メモリ管理機構

ページングの流れページ割り当て (2)

Found the page in page cache?

YES

NO

invokepage_cache_read()

Demandpaging

※1

Allocate a page & Set PTE &load the file

Is the cache valid?NO

load the file Is the page to be shared?

YES

YESNO

Allocate a page & Set PTE &load the file

Set PTE as shared page

Page 22: Linux2.2 on x86  での メモリ管理機構

ページングの流れページ割り当て (3)

Is present vm_ops->swapin?

YES

NO

invokeswap_in()

※2

Set PTE withWritable&dirty

Is swap cache present?

NO

YES

Is read access or shared?

Set PTE

YESNO

Make a swapcache

Demandpaging

Page 23: Linux2.2 on x86  での メモリ管理機構

ページングの流れページ割り当て (4)

Is write access?NO

※3

Do nothing

YES

Copy on write

Is writable page?NO YES

Set PTE withdirty flag

Set PTE & aging

invokedo_wp_page()

※4

Page 24: Linux2.2 on x86  での メモリ管理機構

Copy on write

ページングの流れページ割り当て (5)

Set PTE as writable &dirty (copy no page)

Allocate a page &Set PTE as writable &Copy data from old page

NO YESDoes multiple Processes refer the page?

※4

Page 25: Linux2.2 on x86  での メモリ管理機構

デマンドページング(Demand Paging)

• 仮想アドレス空間の生成時、実際にアクセスがあるまで物理ページの割り当てを遅らせるメモリ割り当て手法– メリット

• 仮想空間生成時の CPU のオーバヘッドが少ない• 物理メモリの利用効率向上

– デメリット• Page fault 時の CPU のオーバヘッドが重い

– 採用理由• ローカリティの原理から page fault はレアなイベントである• プロセスは少ないアドレス空間のみ利用する

– Linux では仮想アドレス空間生成時には PTE 作成するがページは NULL を指す

• 実際のアクセス時に page fault が発生

Page 26: Linux2.2 on x86  での メモリ管理機構

コピーオンライト(Copy on Write)

• 仮想アドレス空間の複製時、実際に書き込みアクセスがあるまでページのコピーを遅らせるメモリ割り当て手法– メリット

• 仮想空間複製時の CPU のオーバヘッドが少ない• 物理メモリの利用効率向上

– デメリット• Page fault 時の CPU のオーバヘッドが重い

– 採用理由• 読み込みのみのページは永続的に共有可能• 仮想空間複製直後に破棄されることが多い

– Linux では仮想アドレス空間複製時、当該空間にマップされているページを全て ReadOnly で両方の空間からマップし直す

• 書き込み時に page fault が発生 -> Copy on Write 処理へ

Page 27: Linux2.2 on x86  での メモリ管理機構

スワップ処理(Swapping)

• 空き物理ページが少なくなった時に、使用中の物理ページを二次記憶に退避し、利用可能な物理ページを確保する技術– メリット

• プロセスが実際に利用可能なアドレス空間を拡張できる• プロセス実行時に割り当て可能な物理メモリを増やすことができ

る– デメリット

• スワッピング処理の CPU のオーバヘッドが大きい– 物理メモリが極端に少ない場合にスラッシングが発生し、システムの

応答性が極端に下がる– 採用理由

• 大きな/多くのプロセスが動かせるメリットが大きい– Linux ではプロセスレベルではなくページレベルのスワッピン

グを実現• CPU のページング機構を利用して実装

Page 28: Linux2.2 on x86  での メモリ管理機構

犠牲ページの決定アルゴリズム

• 基本は LRU (Least Recently Used) ベース– ただし厳密な LRU ではない

• x86 ではチップのサポートが不十分 ( アクセスビットのみ )– Linux x86 ではアクセスビット を利用した aging で実現

• 当該ページにアクセスすると、チップがページテーブルのアクセスビットをたてる

• スワップ用のフリーページの検索時、アクセスビットが立っていればビットは落とされる ( その時はページは解放されない )

• スワップ用のフリーページの検索時、アクセスビットが立っていなければ犠牲ページ候補となる

– 優先度毎にも最も利用物理ページ数が多いプロセスから犠牲ページの決定を実施

Page 29: Linux2.2 on x86  での メモリ管理機構

スワップ処理の流れ

do_swap_page()

swap_in()

swapin_readahead()

read_swap_cache_async()

swap_out()

swap_out_process()

swap_out_vma()

swap_out_pgd()

swap_out_pmd()

try_to_swap_out()

rw_swap_page()

brw_page()

The page fault handler must swap in a page

A page must be swapped out

Low-level swapping function

Block device driver function

Page 30: Linux2.2 on x86  での メモリ管理機構

フリーページの取得処理(1)

• do_try_to_free_pages() – try_to_free_pages() -> do_try_to_free_pages()– 物理ページ割り当て処理部や kswapd から呼ばれる

for (priority = 6;priority; priority--) { while (shrink_mmap(priority,gfp_mask)) { /* ページキャッシュの解放 */ if ( 空きページが十分 ) return; } while (shm_swap(priority ,gfp_mask)) { /* 共有メモリの解放 */ if ( 空きページが十分 ) return; } while (swap_out(priority,gfp_mask)) { /* スワップアウトによる解放 */ if ( 空きページが十分 ) return; } shrink_dcache_memory();/* ディレクトリエントリの解放*/}

Page 31: Linux2.2 on x86  での メモリ管理機構

フリーページの取得処理(2)

• swap_out()

for (counter=nr_tasks/(priority+1);counter;counter--) { int max_cnt=0; struct task_struct *pbest; for (init 以外のすべてのプロセス ) { if ( 最近スワップアウトされていない && 使用物理ページ数 > max_cnt) { max_cnt = 使用物理ページ数 ; pbest = 当該プロセス ; } } swap_out_process(pbest,gfp_mask);}

Page 32: Linux2.2 on x86  での メモリ管理機構

フリーページの取得処理(3)

• try_to_swap_out()– swap_out_process() → … → try_to_swap_out()

if ( 有効なページがない || 予約/ロックされたページ ) { return;}if ( 最近アクセスがあった ) { PTE のアクセスビットをクリア ; page 構造体の参照ビットをたてる ; return;}if ( スワップキャッシュ上にある ) { スワップキャッシュの参照数をあげる ; PTE の設定 ; __free_page (); return;}if ( 書き込みされていない ) { PTE の設定 ; __free_page (); return;}if ( 独自 swapout 関数がある ) { PTE クリア ; swapout 関数を呼び出す ; __free_page(); return;}空きスワップの検索 ; PTE の設定 ; ページの内容をメモリに書き出す ; __free_page();return;

Page 33: Linux2.2 on x86  での メモリ管理機構

kswapd• 空きページを作る処理を行う、永続的に動作するカーネルスレッド

– 定期的 (1 回/秒 ) に起動あるいは物理ページ割り当て処理部から起動される

• 空きページ判定の閾値は最大 256*3 ページ– 最大物理メモリ量に関係

while (1) { while ( 空きページが十分でない ) { if (do_try_to_free_pages(GFP_KSWAPD) { if ( スケジュール必要 ) { schedule(); } } schedule_timeout(10*HZ); }}

Page 34: Linux2.2 on x86  での メモリ管理機構

メモリ領域管理機構(1) Buddy system

• 空きページを複数種類のページ数 *2 のべき乗の単位で管理する方式– 領域の split, coalescing が簡単にできるため、要求された

メモリサイズにあわせて柔軟な割り当てが可能• 要求サイズはページサイズ*2 のべき乗に切り上げて割り当て• 必要なサイズのエリアが足りない時は 1 つ上のサイズのリス

トからもらう (split)• あるサイズのフリーなエリアの量が過剰な時は 1 つ上のサイズのリストに二個一化にして渡す (coalescing)

– External Fragmentation を解決する一つの方式• ページ単位でのメモリフラグメンテーションを解決

– Linux x86 では 2^0 から 2^9 ページサイズの 10 種類

Page 35: Linux2.2 on x86  での メモリ管理機構

メモリ領域管理機構(1) Buddy system

n= 2^0

Free area list(n *page/block)

n= 2^1

n= 2^2

n= 2^3

1page 1page

2page 2page

4page 4page

8page 8page

Buddy system

10 kbytes のメモリの要求

2^2page*1 のメモリの割り当て

pager

split

merge

Page 36: Linux2.2 on x86  での メモリ管理機構

メモリ領域管理機構(2) Slab allocator

• カーネル内で利用するメモリをオブジェクト単位で扱い、再利用に最適化したメモリ管理方式– 再利用による管理オーバヘッドの低下

• ページ単位の管理よりも小さいメモリ領域も扱える– ハードウェアキャッシュの効率向上

• キャッシュラインを乱さないようなメモリ割り当てを行える– Internal Fragmentation を解決する一つの方式

• ページより小さいサイズのメモリフラグメントを解決– e.g.) /etc/slabinfo 参照

• i-node cache, socket buffer, …

Page 37: Linux2.2 on x86  での メモリ管理機構

メモリ領域管理機構(2) Slab allocator

vnodecache

proccache

filecache

Page-level allocator (buddy system)

Slab allocator

activevnodes

activeprocs

activefiles

back end

front end

unusedcoloring area

free active free active active

Slab data

NULL

Linked list

N page

Page 38: Linux2.2 on x86  での メモリ管理機構

メモリ領域管理機構(2) Slab allocator

• Linux で使われている slab の種類– カーネル内で利用される各 structure 用のブロック

• slabinfo,kmem_cache, tcp_tw_bucket, tcp_bind_bucket, tcp_open_request, inet_peer_cache, ip_fib_hash, ip_dst_cache, arp_cache, uhci_urb_priv, blkdev_requests, nfs_read_data, nfs_inode_cache, nfs_write_data, nfs_page, journal_head, revoke_table, revoke_record, dnotify, file, fasync, uid_cache, skbuff_head_cache, sock, sigqueue, kiobuf, cdev_cache, bdev_cache, mnt_cache, inode_cache, dentry_cache, filp, names_cache, buffer_head, mm_struct, vm_area_struct, fs_cache, files_cache

– 2^{5,6,7,8,9,10,11,12,13,14,15,16,17}bytes のブロック• 通常/ DMA 用

– ※ /proc/slabinfo で確認可能

Page 39: Linux2.2 on x86  での メモリ管理機構

参考文献

• Understanding Linux Kernel– Daniel P. Bovet & Marco Cesati, O’reilly, 2001

• UNIX Internals: The New Frontiers– Uresh Vahalia, Prentice Hall, 1996

• Intel Architecture Developers Manual Vol1,2,3– Intel Corp., 1999

Page 40: Linux2.2 on x86  での メモリ管理機構

ブート時のメモリ管理• 起動ステップ 1 (real mode)

– 4MB のアドレススペース用のページテーブルをコンパイル時に初期化 (pg0, arch/kernel/head.S で実施 )• 固定値 (static な配列 )• 範囲 [PAGE_OFFSET, PAGE_PFFSET+0x3fffff]

– ※ ページングは使えない状態– ※起動ステップ 2 に移行後は使用しない

• 起動ステップ 2 (protect mode)– paging_init() ルーチンで初期化 (swapper_pg_dir[], arch/mm/init.c)

• ページテーブルに PAGE_OFFSET 以降の仮想アドレスに対応する物理アドレスを書き込む

• 0x0 をアンマップする (NULL Pointer access 用の領域となる )– ※Pentium 以降では 4MB ページテーブルも利用可能