2.6系カーネルに対するLinux Super Pageの実装と性能

東海大学 大学院 2007 年度 修士論文
2.6 系カーネルに対する Linux Super Page
の実装と性能評価
指導
清水 尚彦
教授
東海大学 大学院
工学研究科
情報通信制御システム工学専攻
木下 修平
目次
第 1 章 はじめに
6
第 2 章 研究背景
7
7
2.1
Super Page とは
2.2
2.3
従来技術 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
研究目的 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
第 3 章 Linux のメモリ管理
3.1
仮想記憶 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2
3.3
ページング
3.4
3.5
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
仮想メモリ管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1
仮想アドレス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.2
3.3.3
アドレス変換テーブル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
IA-32 アーキテクチャにおけるアドレス変換 . . . . . . . . . . . . . . . . . . . . . .
物理メモリ管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
メモリ割り当て . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
第 4 章 Linux Super Page の設計
4.1
4.2
設計方針 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3
実装方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
設計概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
8
9
9
9
10
10
11
12
14
15
16
16
18
4.3.1
TLB 用 PGD と SW 用 PGD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
20
4.3.2
4.3.3
4.3.4
Super Page 予約 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Super Page 割り当て . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Super Page 返却 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
27
30
4.3.5
4.3.6
ダウングレード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
33
カーネルインタフェース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
第 5 章 性能評価
5.1
行列転置プログラム
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
34
5.2
5.1.1 実行結果 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SPEC CPU2000 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2.1 実行結果 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
39
39
5.3
姫野ベンチマーク . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
41
5.3.1
実行結果 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
第 6 章 今後の課題
6.1
Super Page 返却の実装 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2
6.3
6.4
最新 Linux カーネルへの対応 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
他プロセッサアーキテクチャへの対応 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
性能評価 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
42
42
42
42
42
第 7 章 おわりに
43
謝辞
44
業績
45
参考文献
47
付 録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
48
2
図目次
2.1
HugeTLB ファイルシステムの概念図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.2
HugeTLB 利用時におけるプログラム追加部分 . . . . . . . . . . . . . . . . . . . . . . . . .
8
3.1
仮想記憶の概念図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.2
3.3
3.4
Linux における仮想メモリ管理方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.6.11 以前の Linux におけるページ変換テーブルモデル . . . . . . . . . . . . . . . . . . . .
2.6.11 以降の Linux におけるページ変換テーブルモデル . . . . . . . . . . . . . . . . . . . .
10
11
11
3.5
3.6
4KB ページサイズにおける IA-32 の仮想アドレス変換 . . . . . . . . . . . . . . . . . . . .
4KB ページサイズにおける PGD エントリフォーマット . . . . . . . . . . . . . . . . . . . .
12
12
3.7
3.8
3.9
4KB ページサイズにおける PT エントリフォーマット . . . . . . . . . . . . . . . . . . . . .
4KB ページサイズにおける IA-32 の仮想アドレス変換 . . . . . . . . . . . . . . . . . . . .
4MB ページサイズにおける PGD エントリフォーマット . . . . . . . . . . . . . . . . . . .
12
13
14
3.10 バデ ィシステムを用いた空きページ管理方法 . . . . . . . . . . . . . . . . . . . . . . . . . .
3.11 Linux におけるメモリ割り当ての流れ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
15
4.1
4.2
Super Page ダウングレード の概念図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
従来 Linux Super Page におけるアプリケーション実行時の Super Page 保有数の推移 . . .
16
17
4.3
4.4
4.5
端数増大における性能調査方法の概念図 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Super Page 機構実装後のメモリ割り当ての流れ . . . . . . . . . . . . . . . . . . . . . . . .
18
18
19
4.6
4.7
TLB 用 PGD を用いたアドレス変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 つ分の PGD 領域を取得するコード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
20
4.8 2 つ分の PGD 領域を初期化するコード . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.9 TLB 用 PGD と SW 用 PGD に値を設定するコード . . . . . . . . . . . . . . . . . . . . . .
4.10 cr3 制御レジスタのページテーブル設定時の変更コード . . . . . . . . . . . . . . . . . . . .
21
22
22
4.11 cr3 制御レジスタのページテーブル取得時の変更コード . . . . . . . . . . . . . . . . . . . .
4.12 Super Page 予約の概念図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
23
4.13 動的な Super Page 境界合わせを行うコード . . . . . . . . . . . . . . . . . . . . . . . . . .
4.14 動的な Super Page 境界合わせによる効果 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.15 動的な Super Page 境界合わせ実装前後の性能推移 . . . . . . . . . . . . . . . . . . . . . . .
23
23
24
4.16 Super Page 予約のための mmap region 関数と do brk 関数への変更 . . . . . . . . . . . . .
4.17 Super Page 予約を行う make ptes present 関数 . . . . . . . . . . . . . . . . . . . . . . . .
24
25
4.18 Super Page 予約フラグの設定を行う set sp range 関数 . . . . . . . . . . . . . . . . . . . .
4.19 ページフォルト発生時の関数呼び出しの流れ . . . . . . . . . . . . . . . . . . . . . . . . . .
4.20 do anonymous page 関数内の Super Page 割り当てを行うコード . . . . . . . . . . . . . . .
26
27
28
4.21 TLB 用 PGD の設定を行う super page populate 関数 . . . . . . . . . . . . . . . . . . . . .
4.22 ダウングレード の必要な関数への挿入コード . . . . . . . . . . . . . . . . . . . . . . . . . .
29
30
4.23 ページサイズのダウングレード を行う adj sp range 関数 . . . . . . . . . . . . . . . . . . . .
4.24 adj sp pte 関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.25 down pte sp 関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
31
32
従来 Linux Super Page におけるアプリケーション実行時の端数増大における性能推移 . . .
3
4.26 clear pmd sp マクロ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
4.27 Super Page パラメータの設定と読み出し実行時のターミナル画面 . . . . . . . . . . . . . .
33
5.1
行列転置ベンチマークプログラム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
5.2
5.3
5.4
Athlon マシンにおける Load Stride 方式転送性能 . . . . . . . . . . . . . . . . . . . . . . .
Athlon マシンにおける Store Stride 方式転送性能 . . . . . . . . . . . . . . . . . . . . . . .
Athlon マシンにおけるオリジナル対 Super Page カーネル性能比 . . . . . . . . . . . . . . .
35
35
35
5.5
5.6
Celeron マシンにおける Load Stride 方式転送性能 . . . . . . . . . . . . . . . . . . . . . . .
Celeron マシンにおける Store Stride 方式転送性能 . . . . . . . . . . . . . . . . . . . . . . .
36
36
5.7
5.8
5.9
Celeron マシンにおけるオリジナル対 Super Page カーネル性能比 . . . . . . . . . . . . . .
Pentium 4 マシンにおける Load Stride 方式転送性能 . . . . . . . . . . . . . . . . . . . . .
Pentium 4 マシンにおける Store Stride 方式転送性能 . . . . . . . . . . . . . . . . . . . . .
36
37
37
5.10 Pentium 4 マシンにおけるオリジナル対 Super Page カーネル性能比 . . . . . . . . . . . . .
5.11 Athlon マシンにおける SPEC CPU2000 実行結果 . . . . . . . . . . . . . . . . . . . . . . .
37
40
5.12 Celeron マシンにおける SPEC CPU2000 実行結果 . . . . . . . . . . . . . . . . . . . . . . .
5.13 Pentium 4 マシンにおける SPEC CPU2000 実行結果 . . . . . . . . . . . . . . . . . . . . .
5.14 Athlon マシンにおける姫野ベンチマーク実行結果 . . . . . . . . . . . . . . . . . . . . . . .
40
40
41
5.15 Celeron マシンにおける姫野ベンチマーク実行結果 . . . . . . . . . . . . . . . . . . . . . . .
5.16 Pentium 4 マシンにおける姫野ベンチマーク実行結果 . . . . . . . . . . . . . . . . . . . . .
41
41
A.1 make menuconfig 実行時のターミナル画面 . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
4
表目次
1.1
ページサイズ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
4.1
4.2
実装ターゲット . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
< /proc/super page > で読み出し可能なパラメータ . . . . . . . . . . . . . . . . . . . . . .
18
33
4.3
< /proc/sys/super page > で設定可能なパラメータ
. . . . . . . . . . . . . . . . . . . . .
33
5.1
使用プロセッサ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
5.2
5.3
行列転置ベンチマーク性能比 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
39
SPEC CPU2000 オプション一覧表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
第 1 章 はじめに
今日、半導体の集積度が向上し 、ビット単価の低減が進んでいる。このため、我々は安価に大量のメモリを
コンピュータに搭載することが可能となった。
「仕事の量は、完成のために与えられた時間をすべて満たす
まで膨張する」とパーキンソンの法則にあるが、コンピュータ分野においてはこれを「データ量は与えられ
た記憶装置をすべて満たすまで膨張する」と置き換えることができる。つまり、我々がコンピュータに大量
のメモリを搭載すれば 、それを満たすようにメモリ使用量は増加するということを意味する。実際、コン
ピュータのメモリ使用量はムーアの法則に基づき増加してしており、従来より増して大量のメモリを使用す
るアプ リケーションが増加していると言える。このような大量のメモリを使用するアプ リケーションでは
TLB ミスが性能低下を引き起こす原因として考えられている1)2)3) 。TLB(Translation Lookaside Buffer)
とは仮想アドレスとメモリにあるアドレス変換テーブルを用いて算出した物理アドレスを蓄えておき、次
回からのアドレス変換を高速に行うためのバッファである。仮想アドレスに対する適切な物理アドレスが
TLB のエントリにないことを TLB ミスと呼び 、TLB ミスが生じるとアドレス変換を行うために物理メモ
リを参照しなくてはならず、余分な処理サイクルが発生する。OS(Operating System) はメモリをページと
呼ばれるある一定の大きさに区切り管理を行っており、従来の OS はプロセッサがサポートするページサ
イズの最小ページサイズを固定ページサイズとして採用しているものが多い。表 1.1にプロセッサのサポー
トするページサイズと TLB のエントリ数、そしてページサイズが最小、最大の場合の TLB の有効範囲の
例を示す。表 1.1より、最小ページサイズ利用時における TLB の有効範囲は最大ページサイズ利用時と比
べて狭いことが分かる。このため、最小ページサイズ利用時では TLB ミスが多発する可能性が高いと言え
る。つまり、従来の OS によるメモリ管理下で大量のメモリを使用するアプリケーションを実行した場合、
TLB のマッピング不足が原因となり TLB ミスが多発すると考えることができる。
表 1.1: ページサイズ
CPU
Page Size
Number of Entries
Coverage
(Minimum Page size)
Coverage
(Maximum Page Size)
Alpha
8K, 64K, 512K, 4MB
64
512KB
256MB
Sparc64
8K, 64K, 512K, 4MB
64
512KB
256MB
IA-32
4K, 4MB
64
256KB
256MB
近年では複数のページサイズをサポートする OS が開発されており、これらの OS では最小ページサイズ
より大きなページサイズでメモリ管理を行うため、TLB の有効範囲が従来の OS より広い。つまり、今日
の大規模なアプリケーションや莫大な量のストライドデータを用いる科学技術計算などの実行時において、
従来の OS より TLB ミスが削減でき、性能向上が期待できる。しかし 、ユーザがページサイズを指定する
必要があったり、1 プロセスに 1 つのページサイズしか指定できないといった使いやすさや効率的なメモリ
利用の面などに問題がある。本研究ではこれらの問題を解決した Super Page 機構を Linux に実装し 、その
性能評価を行った。
6
第 2 章 研究背景
2.1
Super Page とは
近年のプロセッサは TLB の有効範囲を広げるために複数のページサイズをサポートしている。従来の
OS ではその中でも最も小さなページサイズを固定ページサイズとして利用している場合が多い。本稿では、
OS が固定サイズとして利用しているページサイズをベースページ、ベースページより大きなページサイズ
の全てを総称して Super Page と述べる。また、Super Page を利用する仕組みを Super Page 機構と述べ
る。Super Page の利用は固定ページサイズ利用時に比べコード の複雑化を招く。しかし 、可変ページサイ
ズによるメモリ管理によって TLB ミスを削減できるため、大量のメモリを使用するアプリケーションや莫
大な量のストライドデータを用いる HPC(High Performance Computing) 分野の科学技術計算において性
能向上が期待できる。
2.2
従来技術
OS のベースページによるメモリ管理では、大量のメモリを使用するアプリケーションにおいて TLB ミ
スが多発し性能の低下を招く。このため、近年では Super Page 機構を持つ OS が開発されている13)14)15) 。
以下に Super Page 機構を持つ商用の OS の例を示す。
• IRIX (Silicon Graphics, Inc.)
• HP − U X (Hewlett Packard)
• Solaris (Sun Microsystems)
これらの OS にはユーザが環境変数もしくはコマンドによって適切なページサイズを指定しなくてはならな
かったり、1 プロセスに 1 つのページサイズのみをサポートするためページサイズをあまり大きくすると余
分なワーキングセットを与えてしまうといった、使いやすさと効率的なメモリ利用の面で問題がある1)2)3) 。
無償の OS である Linux においても 2.5 系カーネルから HugeTLB 機能が追加され 、Super Page 機構が
導入された。HugeTLB 機能は、疑似ファイルシステムである hugetlbfs を介してプロセスが メモリを要求
した際、ユーザアプ リケーションは Super Page を利用することができる。Super Page として利用するメ
モリ領域は、Linux がシステム起動時に HugeTLB ファイルシステム用に確保した専用メモリ領域であり、
このメモリ領域はフリーリストで管理される。図 2.1に HugeTLB ファイルシステムの概念図を示す。
vm_area_struct
vm_start;
vm_end;
Virtual Memory Address
use area
allocated area
Large Page Free List
Large Page[0]
Large Page[1]
Large Page Size
Large Page[2]
Large Page[3]
図 2.1: HugeTLB ファイルシステムの概念図
7
第 2 章 研究背景
2.3 研究目的
HugeTLB ファイルシステムの導入により、Linux においても大量のメモリを用いるアプリケーションの
性能向上が期待できるが 、以下に示す問題が存在する。
• 問題点
– スワップ対象外
HugeTLB ファイルシステム上のメモリは常に物理メモリに配置され 、スワップ対象外となる。
このため、システムが確保した Super Page 用のメモリを使い果たした場合、プロセスはアプリ
ケーションの実行を終了させる。
– 移植性のないプログラム
特殊な hugetlbfs をマップする必要があり、HugeTLB 用に記述されたプログラム以外は利用す
ることができない。このため HugeTLB ファイルシステムを利用する場合はプログラムを書き直
す必要がある。図 2.2に HugeTLB ファイルシステム利用時のプログラムの追加部分を示す。図
2.2より ”/mnt/hugetlbf s/” をメモリマップしなければならないことが分かる。
/∗ Only
#i f d e f
#define
#define
#e l s e
#define
#define
#endif
i a 6 4 r e q u i r e s t h i s ∗/
ia64
ADDR ( void ∗ ) ( 0 x8000000000000000UL )
FLAGS (MAP SHARED | MAP FIXED)
ADDR ( void ∗ ) ( 0 x0UL )
FLAGS (MAP SHARED)
i n t main ( void )
{
void ∗ addr ;
int fd ;
/∗ ” / mnt/ h u g e p a g e f i l e ” を オ ー プ ン す る ∗/
f d = open ( ” /mnt/ h u g e p a g e f i l e ” , O CREAT | O RDWR, 0 7 5 5 ) ;
i f ( fd < 0) {
p e r r o r ( ”Open f a i l e d ” ) ;
exit (1);
}
/∗ ” / mnt/ h u g e p a g e f i l e ” を メ モ リ に マ ッ プ す る ∗/
addr = mmap(ADDR, ( 2 5 6 UL∗ 1 0 2 4 ∗ 1 0 2 4 ) , (PROT READ | PROT WRITE) , FLAGS, fd , 0 ) ;
i f ( addr == MAP FAILED ) {
p e r r o r ( ”mmap” ) ;
u n l i n k ( ” /mnt/ h u g e p a g e f i l e ” ) ;
exit (1);
}
図 2.2: HugeTLB 利用時におけるプログラム追加部分
2.3
研究目的
従来技術において Super Page 機構を提供する OS はいくつかあるが、使いやすさ、効率的なメモリ利用、
そしてアプ リケーションの移植の面などに問題があった。このため、本研究ではこれらの問題を解決した
Super Page 機構を Linux に実装し 、TLB ミスの削減によるアプリケーション性能の向上を図る。
8
第3章
3.1
Linux のメモリ管理
仮想記憶
近年の多くの OS では仮想記憶 (Virtual Memory) と呼ばれる仕組みを提供している。仮想記憶はソフト
ウェアのメモリ要求とハード ウェアのメモリ管理との間の論理的な層としての役割を持ち、以下に示す目的
と利点がある5) 。
• 複数プロセスの同時実行を可能にする
• 利用可能な物理メモリより多くのメモリを要求するアプリケーションの動作を可能にする
• プログラムを物理メモリ内のどこにでも置くことが可能である
• プログラマは物理メモリ構成を考慮する必要はなく、マシン非依存のコード を記述できる
仮想記憶を利用する場合、プロセスが参照するアドレスは仮想アドレス (Virtual Address) となる。仮想ア
ドレスは物理的なメモリアドレス (物理アドレス:Physical Address) とは異なり、システムが提供する仮想
空間のアドレスを示す。プロセスが仮想アドレスを使用すると、カーネルと MMU(Memory Management
Unit) が連携し物理アドレスを算出する。仮想アドレスと物理アドレスの対応はメモリにあるアドレス変換
テーブルを用いて行うため、メモリ割り当ては単純な作業で行うことができる。図 3.1に仮想記憶の概念図
を示す。
Virtual Address
Space
Physical Address
Space
HDD
図 3.1: 仮想記憶の概念図
3.2
ページング
仮想記憶を利用する場合、仮想メモリと物理メモリのマッピングを行わなければならない。このマッピン
グ方式には主にページング方式とセグ メント方式の 2 つがあり、Linux では以下の理由からページング方式
を利用している5) 。
9
第 3 章 Linux のメモリ管理
3.3 仮想メモリ管理
• 全てのプロセスで同値のセグ メントレジスタを使用し 、同じ仮想アドレス空間を共有する場合メモリ
管理が簡単であるため
• 広範囲のアーキテクチャへの移植性を考慮するため
ページング方式は記憶装置をある一定の大きさに分け、メモリ管理を行う方式である。つまり、物理メモリ
空間と仮想メモリ空間をある一定のページと呼ばれる大きさに分割し管理する。ページング方式の利用に
より、プログラムに割り当てるメモリは連続である必要はなく、メモリの断片化を防ぐことができる。ペー
ジング方式は必要に応じてページをディスクに書き込んだり、読み込んだりすることができるため仮想記憶
の概念を実現することに適している。
仮想メモリ管理
3.3
3.3.1
仮想アドレス
各プロセスが管理する仮想アドレスは以下の 2 つの構造体を用いて行う。
• mm struct 構造体
プロセス空間を管理するための情報を保持する構造体である。Linux ではすべてのユーザプロセス
がそれぞれ独立した仮想空間を mm struct 構造体で管理する。1 つのプロセスは必ずこの構造体を
1 つ持ち、1 つの仮想空間を操作することが可能となる。ユーザプロセスが要求するメモリ領域は
vm area struxt 構造体によって管理され、リスト化されている。mm struct 構造体のメンバ変数であ
る mmap がこのリストの先頭アドレスを指す。また、メンバ変数である pgd はアドレス変換を行う最
初のページデ ィレクトリの参照先を指し 、仮想アドレスを物理アドレスに変換する際に用いられる。
• vm area struct 構造体
テキスト領域、データ領域、ヒープ領域、スタック領域といった論理的な領域において確保された個々
のメモリとその保護情報を保持する構造体である。プロセス上でメモリを要求すると、vm area struct
構造体が生成され、管理情報として使用される。メンバ変数である vm start と vm end がそれぞれ確
保された領域の始点と終点+1 の仮想アドレスである。1 つのプロセスが持つ全ての vm area struct
構造体はアドレス順にリンクされたリンクリストとなっており、メンバ変数である vm next が次の
vm area struct 構造体の先頭アドレスを指す。
図 3.2にこの 2 つの構造体を用いた仮想メモリ管理の管理方法を示す。プロセスは自身の持つ mm struct 構
造体のメンバ変数 mmap から vm area struct 構造体を用いて仮想アドレスを参照する。管理している仮想
アドレス領域に対してアクセスがある場合は、mm struct 構造体のメンバ変数 pgd とアクセスする仮想ア
ドレスを用いてアドレス変換を行い、物理アドレスを算出する。
mm_struct
vm_area_struct *mmap;
pgd_t *pgd;
vm_area_struct
vm_next;
vm_file;
vm_start;
vm_end;
vm_area_struct
vm_next;
vm_file;
vm_start;
vm_end;
Virtual Memory
Page Directory
Page Table * 1024
Physical Memory
Page(4KB)
Page(4KB)
図 3.2: Linux における仮想メモリ管理方法
10
第 3 章 Linux のメモリ管理
3.3.2
3.3 仮想メモリ管理
アドレス変換テーブル
Linux ではバージョン 2.6.11 以前においては図 3.3で示すページ変換テーブルを用いて仮想アドレスから
物理アドレスの変換を行っていた。しかし 、バージョン 2.6.11 以降は図 3.4で示すページ変換テーブルを用
いている。本研究で使用する Linux カーネルはバージョン 2.6.23 であるため、ページ変換テーブルはバー
ジョン 2.6.11 以降のものを説明する。
Virtual address
Page
Global
Directory
Page
Middle
Directory
Page
Table
Physical
Page
図 3.3: 2.6.11 以前の Linux におけるページ変換テーブルモデル
Virtual address
Page
Global
Directory
Page
Upper
Directory
Page
Middle
Directory
Page
Table
Physical
Page
図 3.4: 2.6.11 以降の Linux におけるページ変換テーブルモデル
変換テーブルは最上位から PGD(Page Global Directory) 、PUD(Page Upper Directory) 、PMD(Page
Middle Directory) 、PT(Page Table) と呼び 、これら 4 段階の変換テーブルを参照しアドレス変換を行う。
仮想アドレスはそれぞれの変換テーブルのオフセットと物理ページのオフセットの 5 つの部位に分けるこ
とができる。アドレスの変換手順を以下に示す。
1. 仮想アドレスを 5 つの部位に分ける。
2. PGD の各エントリは PUD の先頭アドレスである。仮想アドレスの最上位の部位を PGD の先頭アド
レスからのオフセットと見なし 、これらを足すことで PUD の先頭アドレスを求める。
3. PUD の各エントリは PMD の先頭アドレスである。仮想アドレスの最上位から 2 番目の部位を PUD
の先頭アドレスからのオフセットと見なし 、これらを足すことで PMD の先頭アドレスを求める。
4. PMD の各エントリは PT の先頭アドレスである。仮想アドレスの最上位から 3 番目の部位を PUD の
先頭アドレスからのオフセットと見なし 、これらを足すことで PT の先頭アドレスを求める。
5. PT の各エントリは物理ページの先頭アドレスである。仮想アドレスの最上位から 4 番目の部位を PT
の先頭アドレスからのオフセットと見なし 、これらを足すことで物理ページの先頭アドレスを求める。
6. 仮想アドレスの最下位の部位を物理ページの先頭アドレスからのオフセットと見なし 、これらを足す
ことで物理アドレスを求める。
11
第 3 章 Linux のメモリ管理
3.3.3
3.3 仮想メモリ管理
IA-32 アーキテクチャにおけるアドレス変換
4KB ページサイズ利用時のアドレス変換
IA-32 アーキテクチャでは PGD と PT の 2 段階のアドレス変換を行う。このため、カーネルのソースコー
ドでは仮想的な PUD 、PMD を設けて、4 段階のアドレス変換におけるアーキテクチャの相違を吸収してい
る。図 3.5に 4KB ページサイズ利用時のアドレス変換の様子を示す。また、図 3.6に 4KB ページサイズ利
用時の PGD のエントリフォーマット、図 3.7に PT のエントリフォーマットを示す。
Virtual Address(32bit)
PGD offset(10bit) PTE offset(10bit)
mm_struct{pgd_t *pgd}(32bit)
PGD base address(20bit)
PAGE offset(12bit)
000000000000
PGD
address
PGD base address(20bit)
data
PTE base address(20bit)
PGD offset(10bit)
00
PGD flags(12bit)
PT
address
data
PTE base address(20bit)
PTE offset(10bit)
PAGE base address(20bit)
00
PTE flags(12bit)
PAGE base address(20bit)
PAGE offset(12bit)
Physical Address(32bit)
図 3.5: 4KB ページサイズにおける IA-32 の仮想アドレス変換
31
12
Avail G P 0 A P P U R p
S
C W / /
D T S W
Page Table Base Address
Available for system programmer’use
Global page(Ignored)
Page size(0 indicates 4KByte)
Reserved(set to 0)
Accessed
Cache disabled
Write-through
User/Supervisor
Read/Write
Present
図 3.6: 4KB ページサイズにおける PGD エントリフォーマット
31
12
Avail G 0 D A P P U R p
C W / /
D T S W
Page Base Address
Available for system programmer’use
Global page
Reserved(set to 0)
Dirty
Accessed
Cache disabled
Write-through
User/Supervisor
Read/Write
Present
図 3.7: 4KB ページサイズにおける PT エントリフォーマット
2 段階のアドレス変換を行うため、仮想アドレスはそれぞれの変換テーブルのオフセットと物理ページの
オフセットの 3 つの部位に分けることができる。アドレスの変換手順を以下に示す。
12
第 3 章 Linux のメモリ管理
3.3 仮想メモリ管理
1. 仮想アドレスを 3 つの部位に分ける。
2. プロセスの持つ mm struct 構造体のメンバ変数の pgd は PGD の先頭アドレスである。仮想アドレス
の最上位の部位を PGD の先頭アドレスからのオフセットと見なし 、これらを足すことで PT の先頭
アドレスを求める。
3. 仮想アドレスの最上位から 2 番目の部位を PT の先頭アドレスからのオフセットと見なし 、先に求め
た PT の先頭アドレスと 2 番目の部位を足すことで物理ページの先頭アドレスを求める。
4. 仮想アドレスの最下位の部位を物理ページの先頭アドレスからのオフセットと見なし 、先に求めた物
理ページの先頭アドレスと最下位の部位を足すことで物理アドレスを求める。
4MB ページサイズ利用時のアドレス変換
IA-32 アーキテクチャには以下のアドレス拡張機能がある。
• PAE(Physical Address Extension)
4GB 以上の物理メモリを利用可能にする機能である。仮想アドレスから物理アドレスの変換テーブル
を 2 段から 3 段に増やしプロセッサがアクセス可能な物理アドレスを拡張する。つまり PAE 利用時
には PGD 、PMD 、PT の 3 つの変換テーブルによるアドレス変換を行う。物理アドレス線が 36 ビッ
トである PentiumPro 以降のプロセッサでサポートしている。
• PSE(Page Size Extension)
ページサイズの拡張機能である。通常 4KB のページサイズを 4MB に拡張する。PentiumPro 以降の
プロセッサでサポートしている。
Super Page 機構を実装するためには PSE の拡張機能を利用し 、プロセッサがサポートする 4KB と 4MB
のページサイズの混在を可能にする。つまり、プロセッサの制御レジスタである CR4 レジスタの PSE フラ
グに 1 を設定し Super Page の利用を可能とする。図 3.8に 4MB ページサイズ利用時におけるアドレス変
換の様子を示す。図 3.9に 4MB ページサイズ利用時の PGD のエントリフォーマットを示す。PGD エント
リのビット 7 はページサイズ (PS) フラグであり、4MB ページサイズ利用時にはこの PS フラグに 1 を設定
する必要がある。
Virtual Address(32bit)
PGD offset(10bit)
mm_struct{pgd_t *pgd}(32bit)
PGD base address(20bit)
PGD
address
PAGE offset(22bit)
000000000000
PGD base address(20bit)
PGD offset(10bit)
data PTE base address(10bit)
00
PGD flags(12bit)
PAGE base address(10bit)
PAGE offset(22bit)
Physical Address(32bit)
図 3.8: 4KB ページサイズにおける IA-32 の仮想アドレス変換
4MB のページサイズ利用時のアドレス変換には PT が不要となり、1 段階のアドレス変換を行うため、仮
想アドレスはそれぞれ変換テーブルのオフセットと物理ページのオフセットの 2 つの部位に分けることが
できる。つまり、仮想アドレスの上位 10 ビットを PGD のオフセット、残りの下位 22 ビットを 4MB の物
理ページのオフセットと見なし変換を行う。また、物理メモリの管理方法上、4MB ページサイズ利用時に
は物理メモリ、仮想メモリともに先頭アドレスを 4MB 境界に合わせる必要がある。アドレスの変換手順を
以下に示す。
13
第 3 章 Linux のメモリ管理
3.4 物理メモリ管理
31
12
22
Page Base
Address
Reserved
Avail G P D A P P U R p
S
C W / /
D T S W
Available for system programmer’use
Global page(Ignored)
Page size(1 indicates 4MByte)
Dirty
Accessed
Cache disabled
Write-through
User/Supervisor
Read/Write
Present
図 3.9: 4MB ページサイズにおける PGD エントリフォーマット
1. 仮想アドレスを 2 つの部位に分ける。
2. プロセスの持つ mm struct 構造体のメンバ変数の pgd は PGD の先頭アドレスである。仮想アドレス
の最上位の部位を PGD の先頭アドレスからのオフセットと見なし 、これらを足すことで 4MB の物
理ページの先頭アドレスを求める。
3. 仮想アドレスの最下位の部位を 4MB の物理ページの先頭アドレスからのオフセットと見なし 、先に
求めた 4MB の物理ページの先頭アドレスと最下位の部位を足すことで物理アドレスを求める。
3.4
物理メモリ管理
Linux ではバディシステムと呼ばれる管理方式を用いて利用可能な物理ページを管理する。バディシステ
ムは空きページを 2 のべき乗単位 (オーダー) で管理するが 、各オーダーの空きページは各オーダーのペー
ジ境界になければならない。図 3.10にバデ ィシステムによるページ管理の概要を示す。
page flame
empty flame
order:0
order:1
order:2
order:3
order:4
used
unused
empty page
図 3.10: バデ ィシステムを用いた空きページ管理方法
ページの要求は alloc pages 関数、 get pages 関数を用いて行い、引数に要求ページのオーダーを渡す。例
えばバディシステムに 16 ページ分の連続した空きページを要求するためには、引数のオーダーを 4(24 =16)
として上記関数を呼び出す。この時、バデ ィシステムはオーダー 4 のグループに未割り当ての空きページ
がないか探しにいく。空きページがあれば 、その先頭ページのアドレスを返し 、ない場合はオーダー 5 の
グループから 32 ページの空きページを探す。もしオーダー 5 のグループに 32 ページの空きページがあれ
ば 、これを 2 つの連続した 16 ページに分割し 、片方の先頭アドレスを返し 、もう片方の 16 ページ分をオー
ダー 4 のグループで管理する。もしオーダー 5 のグループに未割り当てページがない場合は順にオーダー
の大きいグループへ探しにいく仕組みとなっている。
14
第 3 章 Linux のメモリ管理
3.5
3.5 メモリ割り当て
メモリ割り当て
ユーザプロセスからのメモリ領域の確保要求が発生するとカーネルは vm area struct 構造体を生成し 、
これを mm struct 構造体のリンクに追加することでメモリ領域の確保を行う。Linux では不要な物理メモ
リの使用を防ぐ 仕組みを持つため、実際に要求されたメモリ領域に対してアクセスがあるまでは物理ペー
ジの確保を行わない。このため、アプリケーションが確保要求したメモリ領域へ実際にアクセスするとペー
ジフォルト割り込みが発生し 、割り込み処理の中で物理ページの確保を行う。メモリの開放の際は、メモリ
領域を表す vm area struct 構造体を mm struct 構造体のリンクから削除し 、そのアドレスに対応する PT
エントリをクリアする。そして、割り当てられていたページが他のプロセスから参照されていなければペー
ジを未割り当てリストに追加する。図 3.11に Linux におけるメモリ割り当ての流れを示す。
Application
bss,mmap,
brk
Memory Request
Kernel
page
access
Page Fault
Exit
process
termination
fixed page size
register to
vm_struct
allocate
real page
zap virtual
space
図 3.11: Linux におけるメモリ割り当ての流れ
15
第4章
4.1
Linux Super Page の設計
設計方針
Linux Super Page プロジェクトは以前より本研究室で行われており、シンプルで実用的な Super Page
カーネルの設計を目的とした以下の設計方針がある8) 。
1. バイナリ互換性を持つ
日常的に使用するアプリケーションや他の環境でコンパイルしたアプリケーションを変更することな
しに Super Page を利用できるようにする。これは従来技術における移植性の問題を解決する。
2. アクセス時に物理ページを割り当てる
従来の Linux カーネルの設計方針に従い、アプリケーションによる無駄なメモリ割り当てを防止する
ための”allocate at the access”ポリシーを守る。
3. 過度のワーキングセットを持たせない
アプ リケーションの要求サイズ分の仮想アドレス空間のみを割り当てる。そして、Super Page の割
り当ては Super Page 境界にある場合にのみ自動で割り当てる。これは従来技術における使いやすさ
と効率的なメモリ利用の面の問題を解決する。
4. ページサイズの動的アップグレード をサポートしない
メモリフットプリントの大きなアプリケーションのみが Super Page から利益を受けるため、アップ
グレードは性能を向上させる手助けとならない。日常的に使用するアプリケーションの効率を考慮し 、
動的アップグレード をサポートしない。
5. ページサイズの動的ダウングレード をサポートする
アップグレードとは異なり、OS が Super Page の一部の属性を変更する可能性があるため、ダウング
レード をサポートする (図 4.1)。
base page
Level 1 Super Page
Level 2 Super Page
Change
Attribute
Request
Requested page is downgraded
from Super Page to base page.
downgrade
downgrade
図 4.1: Super Page ダウングレード の概念図
16
第 4 章 Linux Super Page の設計
4.1 設計方針
上記の設計方針に基づき実装した Super Page カーネルに対して、第 5 章の性能評価で用いる行列転置プ
ログラムを実行し性能面における改善点を調査した。調査結果より、Linux Super Page の利用効率を向上
させるための設計方針を新たに 2 つ追加した。以下にそれらの設計方針を示す。
• 物理ページ返却時に Super Page ブロック単位で返却を行う
従来の Super Page カーネルでは Super Page を開放する際に一度ページサイズをベースページにまで
ダウングレード させ、その後バディシステムにベースページ単位での返却を行っていた。この返却方
法では、返却途中に他のプロセスに Super Page 領域の一部を割り当てられる可能性がある。もし返
却途中の Super Page の一部が他のプロセスにより利用された場合、バディシステムの保有する Super
Page 数が減少し 、返却中の Super Page を次回の Super Page 割り当てに利用することができなくな
る。実際に Super Page の割り当てと開放を繰り返した場合のバディシステムが保有する Super Page
数を調査した (図 4.2)。図 4.2の縦軸はシステムが保有する Super Page 数、横軸は割り当てと開放を
繰り返した回数である。
図 4.2: 従来 Linux Super Page におけるアプリケーション実行時の Super Page 保有数の推移
調査結果より、割り当てと開放の繰り返し回数の増加が Super Page 保有数の減少を招くことが明ら
かとなった。このため、Super Page ブロックをまとめてバディシステムに返却し Super Page の再利
用性を高める。
• Super Page 境界へ積極的にメモリを割り当てる
Super Page を利用するためにはバディシステムとの関係上、要求メモリが Super Page 境界にある必
要がある。要求メモリサイズが Super Page 分のサイズを有していても、要求メモリの境界が Super
Page 境界にない場合は Super Page を割り当てることのできない端数が生じる。Super Page カーネ
ルにおいて 4MB ページ境界から 4KB 単位で 0 から 1023 までの端数を発生させ、端数増加による性
能への影響を調査した。4MB ページ境界からのメモリに対しては Super Page によるアクセスが可能
であり、4MB ページ境界からあふれた端数に対してはベースページによるアクセスとなる。図 4.3に
本調査方法の概念図を示す。図 4.4は調査結果であり、左の縦軸は転送性能 [MB/s] 、右の縦軸は扱う
データ中の端数割合 [%] 、横軸は端数の数である。
Store Stride の場合では、Stride アクセスする領域から端数となるため、端数の増加が性能低下に直
接結び付く。また、Load Stride の場合では、Stride アクセスする領域が利用メモリの後半部分にあ
るため端数の割合が 80[%] 付近で性能が低下する。調査結果より、端数の増大が性能の低下を招くこ
とが明らかとなった。このため、要求アドレスを動的に Super Page 境界に合わせる機能を実装する
ことで Super Page の効率的利用を図る。
17
第 4 章 Linux Super Page の設計
4.2 設計概要
4MB
4KB access
4MB
4MB access
mmap area
use area
4KB
mmap area
use area
4KB
mmap area
use area
Fraction(0~1023)
mmap area
use area
図 4.3: 端数増大における性能調査方法の概念図
225
230
Load Stirde
Ratio of Fraction
220
Store Stirde
Ratio of Fraction
100
100
220
215
195
40
190
185
Performance[MB/s]
60
200
The Ratio of the Fraction[%]
Performance[MB/s]
205
20
0
200
400
600
The Number of the Fraction
800
1000
200
60
190
40
180
20
170
180
175
80
210
0
160
The Ratio of the Fraction[%]
80
210
0
(a)Load Stride
200
400
600
The Number of the Fraction
800
1000
0
(b)Store Stride
図 4.4: 従来 Linux Super Page におけるアプリケーション実行時の端数増大における性能推移
4.2
設計概要
表 4.1に我々がターゲットとする LinuxOS のバージョン 、CPU のアーキテクチャ、サポートページサイ
ズを示す。CPU アーキテクチャとして IA-32 をサポートするため、OS が利用できるページサイズは 4KB 、
4MB の 2 つである。ただしアドレス拡張機能である PAE モード を有効にした場合は 4MB ではなく 2MB
のサポートとなる。
表 4.1: 実装ターゲット
OS
Kernel Version
CPU Architecture
Page Size
Linux
2.6.23
IA-32
4KB, 4MB(PAE モード では 2MB)
Super Page 利用時のページサイズは 4MB となり、第 3章で述べた通り、PGD から物理アドレスを直接
参照することが可能となる。このため、Super Page 利用時には PT を必要としない。しかし 、Linux のメ
モリ管理においてソフトウェアから PT を参照する場合があるため、Super Page 利用時においても PT が
必要となる。このため、我々はソフトウェアが使用する用と TLB が使用する用の 2 つの PGD を用意する。
本稿ではソフトウェアの使用する PGD を SW 用 PGD 、TLB の使用する PGD を TLB 用 PGD と述べる。
TLB 用 PGD はプロセスに 1 つだけであるため、メモリ使用量はわずかとなる。
従来の Linux カーネルのメモリ割り当ての流れは第 3章の図 3.11で示した通りであり、メモリ範囲の予
約、物理ページ割り当て、メモリ開放の大きく 3 つの仕事に分けることができる。Super Page 機構の実装
は主にこの 3 つの仕事にに対し 、以下に示す Super Page 機構用の仕事を追加することで行う。
18
第 4 章 Linux Super Page の設計
4.3 実装方法
• メモリ範囲の予約 + Super Page 予約
アプリケーションから mmap などを用いてメモリが要求された場合、カーネルは mm struct 構造体の
登録によるメモリ範囲の予約を行う。同時に要求メモリが Super Page 境界にあり、Super Page 割り
当てが可能であるかど うかを調べ、Super Page 割り当てが可能である場合はその領域の PT に Super
Page 利用のヒントを与える。本稿ではこれを Super Page 予約と述べる。また、Super Page 予約を
行う前にアプリケーションからの要求ページのページ境界を 4MB ページ境界に合わせる処理を行い、
可能な限り Super Page 予約を行えるようにする。
• 物理ページ割り当て + Super Page 割り当て
アプ リケーションから要求ページへ実際にアクセスが発生するとページフォルトが発生し 、従来の
カーネルであるならベースページサイズでの割り当てを行う。しかし 、我々はアクセス領域に Super
Page 予約がされている場合はバディシステムに対し Super Page を要求し 、取得可能であるなら Super
Page での割り当てを行う。本稿ではこれを Super Page 割り当てと述べる。もし取得不可能であれば 、
Super Page 予約をクリアし 、ベースページでの割り当てを行う。
• メモリ開放 + Super Page 返却
アプリケーションが終了するとメモリが開放されるが 、この時開放するメモリに Super Page 予約が
されている場合、Super Page ブロック単位で物理ページの開放を行う。本稿ではこれを Super Page
返却と述べる。
図 4.5に Super Page 機構実装後のメモリ割り当ての流れを示す。
Application
bss,mmap,
brk
Memory Request
page
access
Page Fault
Exit
process
termination
Kernel
register to
vm_struct
allocate
real page
zap virtual
space
Super Page Reservation
Super Page Allocation
Super Page Return
図 4.5: Super Page 機構実装後のメモリ割り当ての流れ
そして、設計方針に基づき OS が Super Page の一部の属性を変更する場合は Super Page をベースペー
ジへとダウングレード する。また Super Page 用のチューニングパラメータを用意し 、Super Page 情報の
取得や Super Page の ON/OFF の切り替えなどを可能にすることで、本 Super Page 機構の利便性を向上
させる。
4.3
実装方法
本稿ではバージョン 2.6.23 の Linux カーネルのディレクトリをカレントディレクトリとして、以降のソー
スコード の説明を行う。
19
第 4 章 Linux Super Page の設計
4.3.1
4.3 実装方法
TLB 用 PGD と SW 用 PGD
Super Page 利用時におけるソフトウェアとの互換性を保つため、TLB 用 PGD と SW 用 PGD の 2 つの
PGD を用意する。2 つの PGD を用いたメモリ管理について、図 4.6に TLB 用 PGD を用いた 4MB ページ
4KB
CPU
CR3
SW PGD
4KB
PT
4MB
4KB
4KB
4MB
mm_struct
pgd_t *pgd
TLB PGD
PT
SW PGD
CPU
CR3
TLB PGD
のアドレス変換と 4KB ページのアドレス変換の概念図を示す。
mm_struct
pgd_t *pgd
4KB
Physical
Memory
(a)4MB ページのアドレス変換
4KB
Physical
Memory
(b)4KB ページのアドレス変換
図 4.6: TLB 用 PGD を用いたアドレス変換
ソースコードでは < arch/i386/mm/pgtable.c > の pgd alloc 関数を用いて PGD 領域の確保を行ってい
るため、ここで連続する通常の 2 倍の PGD 領域の確保を行う (図 4.7)。SW 用 PGD は取得した先頭アドレ
スから 1024 エントリ分の領域を持ち、TLB 用 PGD は SW 用 PGD の最終エントリ後のアドレスから 1024
エントリ分の領域を持つ。ソースコード 上では PGD のエントリ数は PTRS PER PGD として定義されて
おり、これは 1024 を示す。このため”pgd + sizeof(pgd t)*PTRS PER PGD”と記述することで 、SW 用
PGD のアドレスに対応する TLB 用 PGD のアドレスを参照することができる。確保した領域は pgd ctor
関数内の memset 関数を用いて 0 で初期化されるため、ここで TLB 用 PGD も同時に初期化されるように
変更を加える (図 4.8)。
/∗ ar c h / i 3 8 6 /mm/ p g t a b l e . c ∗/
p g d t ∗ p g d a l l o c ( struct mm struct ∗mm)
{
int i ;
#i f CONFIG SUPER PAGE
#i f d e f CONFIG X86 PAE
p g d t ∗ pgd = q u i c k l i s t a l l o c ( 0 , GFP KERNEL, p g d c t o r ) ;
#e l s e
p g d t ∗ pgd = ( p g d t ∗ ) g e t f r e e p a g e s (GFP KERNEL, 1 ) ;
i f ( pgd )
p g d c t o r ( pgd ) ;
#endif
#e l s e
p g d t ∗ pgd = q u i c k l i s t a l l o c ( 0 , GFP KERNEL, p g d c t o r ) ;
#endif
図 4.7: 2 つ分の PGD 領域を取得するコード
PGD の設定は < include/asm − generic/pgtable − nopud.h > の set pgd マクロを用いて行うため、TLB
用 PGD と SW 用 PGD の両方に値が設定されるように図 4.9で示すソースコードに変更した。ここでも SW
用 PGD のアドレスに PTRS PER PGD を足すことで TLB 用 PGD を参照する。IA-32 では PGD 、PUD 、
PMD のポイント先は同じ PT を指すため、< include/asm − generic/pgtable − nopmd.h > の set pud マ
クロ、< include/asm − i386/pgtable − 2level.h > の set pmd マクロにも同様の変更を加えた。
ページテーブルを CPU の cr3 制御レジスタに設定する場合は load cr3 マクロを使用する。この時、ハー
ド ウェアには TLB 用 PGD を使用してもらうため、図 4.10に示すソースコードに変更した。変更を行った
ファイルは < include/asm − i386/mmuc ontext.h > である。そして、read cr3 マクロによって cr3 制御レ
20
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ ar c h / i 3 8 6 /mm/ p g t a b l e . c ∗/
#i f ( PTRS PER PMD == 1)
/∗ Non−PAE pgd c o n s t r u c t o r ∗/
s t a t i c void p g d c t o r ( void ∗ pgd )
{
unsigned long f l a g s ;
/∗ ! PAE, no p a g e t a b l e s h a r i n g ∗/
#i f CONFIG SUPER PAGE
memset ( pgd + s i z e o f ( p g d t ) ∗PTRS PER PGD , 0 , USER PTRS PER PGD∗ s i z e o f ( p g d t ) ) ;
#endif
memset ( pgd , 0 , USER PTRS PER PGD∗ s i z e o f ( p g d t ) ) ;
s p i n l o c k i r q s a v e (& p g d l o c k , f l a g s ) ;
/∗ must happen under l o c k ∗/
#i f CONFIG SUPER PAGE
c l o n e p g d r a n g e ( ( p g d t ∗ ) pgd + USER PTRS PER PGD + PTRS PER PGD,
s w a p p e r p g d i r + USER PTRS PER PGD ,
KERNEL PGD PTRS ) ;
p a r a v i r t a l l o c p d c l o n e ( ( p a ( pgd + s i z e o f ( p g d t ) ∗PTRS PER PGD)) > > PAGE SHIFT ,
p a ( s w a p p e r p g d i r ) > > PAGE SHIFT ,
USER PTRS PER PGD ,
KERNEL PGD PTRS ) ;
#endif
c l o n e p g d r a n g e ( ( p g d t ∗ ) pgd + USER PTRS PER PGD ,
s w a p p e r p g d i r + USER PTRS PER PGD ,
KERNEL PGD PTRS ) ;
p a r a v i r t a l l o c p d c l o n e ( p a ( pgd ) > > PAGE SHIFT ,
p a ( s w a p p e r p g d i r ) > > PAGE SHIFT ,
USER PTRS PER PGD ,
KERNEL PGD PTRS ) ;
p g d l i s t a d d ( pgd ) ;
s p i n u n l o c k i r q r e s t o r e (& p g d l o c k , f l a g s ) ;
}
図 4.8: 2 つ分の PGD 領域を初期化するコード
ジスタの値を取得する場合は、ページテーブルを SW 用 PGD に切替えるため、図 4.11に示すソースコー
ドに変更した。変更を行ったファイルは < arch/i386/mm/f ault.c > である。
21
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ i n c l u d e /asm−g e n e r i c / p g t a b l e −nopud . h ∗/
#i f CONFIG SUPER PAGE
#define s e t p g d r a w ( pgdptr , p g d v a l )
s e t p u d r a w ( ( p u d t ∗ ) ( pgdptr ) , ( p u d t ) { p g d v a l
})
#define s e t p g d ( pgdptr , p g d v a l ) do { \
s e t p g d r a w ( pgdptr , p g d v a l ) ; \
s e t p g d r a w ( pgdptr+PTRS PER PGD , p g d v a l ) ; \
} while ( 0 )
#e l s e
#define s e t p g d ( pgdptr , p g d v a l )
s e t p u d ( ( p u d t ∗ ) ( pgdptr ) , ( p u d t ) { p g d v a l } )
#endif
/∗ i n c l u d e /asm−g e n e r i c / p g t a b l e −nopmd . h ∗/
#i f CONFIG SUPER PAGE
#define s e t p u d r a w ( pudptr , pudval )
set pmd raw ( ( pmd t ∗ ) ( pudptr ) , ( pmd t ) { pudval
})
#define s e t p u d ( pudptr , pudval ) do { \
s e t p u d r a w ( pudptr , pudval ) \
s e t p u d r a w ( pudptr+PTRS PER PGD , pudval ) \
} while ( 0 )
#e l s e
#define s e t p u d ( pudptr , pudval )
set pmd ( ( pmd t ∗ ) ( pudptr ) , ( pmd t ) { pudval } )
#endif
/∗ i n c l u d e /asm−i 3 8 6 / p g t a b l e −2 l e v e l . h ∗/
#i f CONFIG SUPER PAGE
#define set pmd raw ( pmdptr , pmdval )
n a t i v e s e t p m d ( pmdptr , pmdval )
#define set pmd ( pmdptr , pmdval ) do{\
set pmd raw ( pmdptr , pmdval ) ; \
set pmd raw ( pmdptr + PTRS PER PGD , pmdval ) ; \
} while ( 0 )
#e l s e
#define set pmd ( pmdptr , pmdval )
n a t i v e s e t p m d ( pmdptr , pmdval )
#endif
図 4.9: TLB 用 PGD と SW 用 PGD に値を設定するコード
/∗ i n c l u d e /asm−i 3 8 6 / mmu context . h ∗/
/∗ s w i t c h m m 関 数 ∗/
#i f CONFIG SUPER PAGE
l o a d c r 3 ( next−>pgd+PTRS PER PGD ) ;
#e l s e
l o a d c r 3 ( next−>pgd ) ;
#endif
図 4.10: cr3 制御レジスタのページテーブル設定時の変更コード
/∗ ar c h / i 3 8 6 /mm/ f a u l t . c ∗/
/∗ v m a l l o c f a u l t 関 数 ∗/
pgd paddr = r e a d c r 3 ( ) ;
#i f CONFIG SUPER PAGE
pgd paddr −= ( s i z e o f ( p g d t ) ∗PTRS PER PGD ) ;
#endif
図 4.11: cr3 制御レジスタのページテーブル取得時の変更コード
22
第 4 章 Linux Super Page の設計
4.3.2
4.3 実装方法
Super Page 予約
アプリケーションが mmap などによりメモリ要求を行った場合、要求された仮想アドレス範囲内で 4MB
境界に重なっており、かつ 4MB 分の領域をカバーしている場合、その領域内の 1024 全ての PT エントリの
Super Page 予約フラグに 1 を立て Super Page 予約を行う。PT エントリの Super Page 予約フラグは PT
エントリのシステムソフトウェア用に予約されている場所の空きビットに実装した。図 4.12に Super Page
予約の概念図を示す。メモリ要求時には設計方針に従い物理メモリの割り当てを行わない。
0x00c00000
0x01000000
Virtual
Memory
Address
0x01400000
0x01800000
vm_area_struct
vm_start;
vm_end;
PGD
PT
PAGE base address
31
1
1
9
Super Page
Reserve bit
0
1
図 4.12: Super Page 予約の概念図
Super Page 予約を実装する前に、設計方針に基づき Super Page を積極的に利用できるように動的に要求メ
モリの開始アドレスを Super Page 境界に合わせる実装を行った。変更を行ったファイルは < mm/mmap.c >
であり、arch get unmapped area 関数に変更を加えた。図 4.13に arch get unmapped area 関数の変更箇
所を示す。
/∗ mm/mmap. c ∗/
/∗ a r c h g e t u n m a p p e d a r e a 関 数 ∗/
i f ( addr ) {
#i f CONFIG SUPER PAGE
i f ( SP ALIGN ) {
/∗ # d e f i n e SUPER PAGE ALIGN( addr )
addr = SUPER PAGE ALIGN( addr ) ;
} else {
addr = PAGE ALIGN( addr ) ;
}
#e l s e
addr = PAGE ALIGN( addr ) ;
#endif
( ( ( addr)+SUPER PAGE SIZE−1)&SUPER PAGE MASK) ∗/
図 4.13: 動的な Super Page 境界合わせを行うコード
この変更により、図 4.14に示すような 4MB ページサイズで扱えるメモリ領域が増える。実際に端数増加
における性能推移調査で用いたプログラムを本実装後に実行したところ、図 4.15に示す結果が得られ 、性
能の低下を防ぐことを確認した。
Virtual 0x00c00000
Memory
Address
PGD
for TLB
0x01000000
0x01400000
0x01800000
Virtual 0x00c00000
Memory
Address
vm_area_struct
vm_start;
vm_end;
PS Flag
PGD
for TLB
PS Flag
PTE
PAGE
0x01000000
0x01400000
0x01800000
vm_area_struct
vm_start;
vm_end;
PS Flag
PS Flag
4MB
4MB
PS Flag
PTE
4MB
PAGE
4MB
図 4.14: 動的な Super Page 境界合わせによる効果
23
4MB
第 4 章 Linux Super Page の設計
4.3 実装方法
(a)Load Stride
(b)Store Stride
図 4.15: 動的な Super Page 境界合わせ実装前後の性能推移
次に Super Page 予約について説明する。mmap システムコールを実行すると メモリ領域を確保する
do mmap 関数が呼び 出される。do mmap 関数は do mmap pgoff 関数を呼び 出し 、実際にプロセス空間
などの領域を確保する。このため、Super Page 予約における変更は < mm/mmap.c > の要求アドレス範
囲を設定する do brk 関数と do mmap pgoff 関数が呼び出す mmap region 関数に変更を加えた (図 4.16)。
do brk 関数はヒープ領域を拡張する際に呼び出され 、do mmap pgoff 関数の簡易版となっている。
/∗ mm/mmap. c ∗/
/∗ d o b r k 関 数 と d o m m a p p g o f f 関 数 が 呼び 出 す m m a p r e g i o n 関 数 ∗/
#i f d e f CONFIG SUPER PAGE
i f ( s u p e r p a g e o n && l e n >= (PAGE SIZE << s u p e r p a g e o r d e r [ 1 ] ) ) {
m a k e p t e s p r e s e n t ( addr , addr + l e n ) ;
}
#endif
図 4.16: Super Page 予約のための mmap region 関数と do brk 関数への変更
Super Page 予約時には我々が新たに作成したファイル < mm/superpage.c > で定義する make ptes present
関数を呼び出す。呼び出し条件は、要求アドレス範囲が Super Page サイズより大きく、Super Page 機構が有
効であることである。make ptes present 関数は要求アドレスで Super Page 境界に合う場合を探し 、Super
Page 割り当て可能な領域を再帰的に探し出す。Super Page 割り当て可能な領域を見つけた場合に、そのメモ
リ領域に対応する 1024 全ての PT エントリの Super Page 予約フラグに 1 を設定する。Super Page 予約フラ
グの設定は set sp range 関数を呼び出し行う。set sp range 関数は仮想アドレスと mm struct 構造体を用い
て、対応する PT を探し出し 、1024 全てのエントリに Super Page 予約を行う。図 4.17に make ptes present
関数、図 4.18に set sp range 関数を示す。
24
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ mm/ s u p e r p a g e . c ∗/
i n t m a k e p t e s p r e s e n t ( unsigned long addr , unsigned long end )
{
int i ;
unsigned long rem ;
i f ( addr >= end )
BUG( ) ;
/∗
∗ The f i r s t o r d e r ( i =0) i s t h e o r d i n a r y p t e ( 1 page ) , t h e n we s k i p t o
∗ a l l o c a t e the pte .
∗/
f o r ( i = 0 ; i < s u p e r p a g e n r − 1 ; i ++) {
rem = ( ˜ addr + 1 ) & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i + 1 ] ) − 1 ) ;
while ( rem &&
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
i f ( i&&s u p e r p a g e b i t m a s k & (1<< i ) ) {
s u p e r p a g e r e s e r v e [ i ]++;
s e t s p r a n g e ( addr , s u p e r p a g e o r d e r [ i ] , s u p e r p a g e p r o t [ i ] ) ;
}
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
rem −= PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
}
}
f o r ( i = s u p e r p a g e n r − 1 ; i > 0 ; i −−) {
while (
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
i f ( s u p e r p a g e b i t m a s k & (1<< i ) ) {
s u p e r p a g e r e s e r v e [ i ]++;
s e t s p r a n g e ( addr , s u p e r p a g e o r d e r [ i ] , s u p e r p a g e p r o t [ i ] ) ;
}
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
}
}
return 0 ;
}
図 4.17: Super Page 予約を行う make ptes present 関数
25
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ mm/ s u p e r p a g e . c ∗/
void s e t s p r a n g e ( unsigned long a d d r e s s , i n t o r d e r , p g p r o t t p r o t )
{
int i ;
p g d t ∗ pgd ;
p u d t ∗ pud ;
pmd t ∗pmd ;
p t e t ∗ pte ;
struct mm struct ∗mm = c u r r e n t −>mm;
s p i n l o c k (&mm−>p a g e t a b l e l o c k ) ;
pgd = p g d o f f s e t (mm, a d d r e s s ) ;
i f ( ! pgd ) goto out ;
pud = p u d o f f s e t ( pgd , a d d r e s s ) ;
i f ( ! pud ) goto out ;
pmd = p m d o f f s e t ( pud , a d d r e s s ) ;
i f ( ! pmd ) goto out ;
s p i n u n l o c k (&mm−>p a g e t a b l e l o c k ) ;
p t e = p t e a l l o c m a p (mm, pmd , ( a d d r e s s & ˜PGDIR MASK ) ) ;
s p i n l o c k (&mm−>p a g e t a b l e l o c k ) ;
i f ( ! pte none (∗ pte ) ) {
goto out ;
}
f o r ( i = 0 ; i < 1<< o r d e r ; i ++)
i f ( ! p t e n o n e ( ∗ ( p t e+i ) ) ) {
goto out ;
}
f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
s e t p t e r a w ( pte , p t e m o d i f y ( ∗ pte , p r o t ) ) ;
p t e++;
}
out :
s p i n u n l o c k (&mm−>p a g e t a b l e l o c k ) ;
return ;
}
図 4.18: Super Page 予約フラグの設定を行う set sp range 関数
26
第 4 章 Linux Super Page の設計
4.3.3
4.3 実装方法
Super Page 割り当て
実際に割り当てられていないアドレスに初めてアクセスする場合、ページフォルト割り込みが発生し 、物
理メモリを割り当てる。図 4.19にページフォルト発生時の関数呼び出しの流れを示す。handle pte fault 関
数は引数で渡されたアドレスに対応する PT エントリを参照し 、新しいページフレームの確保方法を決定
し 、それぞれの確保方法に合った関数を呼び出す。我々はユーザプロセスから要求されたメモリ領域でかつ
ファイルがマッピングされていない領域に対して Super Page を割り当てるため、< mm/memory.c > の
do anonymous page 関数に Super Page 割り当てを行う変更を加える。
(Page Fault Trap Entry Routine)
page_fault()
Access to Address Space
that Process does not has.
or
Wrong Access(e.g.COW)
do_page_fault()
Page Fault
in User Space
Access to Address Space
that Process has.
Vmalloc Area
handle_mm_fault()
SIGSEGV is generated
for Process
Page Fault
in Kernel Space
Map to Physical Page
Not Vmalloc Area
Kernel Panic
Page Fault Process
handle_pte_fault()
do_file_page()
do_swap_page()
do_wp_page()
do_no_page()
do_anonymous_page()
図 4.19: ページフォルト発生時の関数呼び出しの流れ
do anonymous page 関数において、書き込みアクセスの場合に PT のエントリを参照し必要なページオー
ダーを調べる。そしてオーダー分のページをバディシステムに対して要求し 、物理ページの取得を行う。バ
ディシステムにページを要求する際、オリジナルカーネルでは alloc zeroed user highpage movable 関数を
用いてページ要求をしており、この関数を利用した場合はページのオーダーは必ず 0 となる。このため、
alloc zeroed user highpages movable 関数を作成し 、引数にオーダーを用意し 、複数ページの要求を行える
ように変更している。Super Page の取得が成功した場合はそのアドレスを TLB 用 PGD に設定する。そし
て TLB 用 PGD が 4MB 用のアドレス変換テーブルとして使用されるよう TLB 用 PGD の PS ビットに 1
を設定する。また、SW 用 PGD には 4KB によるメモリ管理を行うため PS フラグを設定せず、取得した
4MB ページに対応する 1024 個の PT エントリに 4KB ページを割り当てる。このため、ソフトウェアが使
用する SW 用 PGD は従来の PGD と変わることはない。バディシステムから Super Page の取得が失敗し
た場合は 4MB ページを 4KB ページにダウングレードし 4KB ページサイズ割り当てで再試行する。TLB 用
PGD の設定は < include/asm − i386/pgalloc.h > に追加した super page populate 関数を用いて行う。そ
の後、取得した 4MB ページに対応する 1024 個の PT エントリを設定する。図 4.20に do anonymous page
関数の主な変更部分のコード を示す。また、図 4.21に TLB 用 PGD に値を設定する super page populate
関数のコード を示す。
27
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ mm/memory . c ∗/
/∗ d o an o n y m o u s 関 数 ∗/
if ( write access ) {
#i f CONFIG SUPER PAGE
retry :
oldpte = ∗ page table ;
order = super page order [ pte to sp index ( oldpte ) ] ;
wktable =
( p t e t ∗ ) ( ( unsigned long ) p a g e t a b l e &
˜ ( ( 1UL < < ( o r d e r + SIZEOF PTE LOG2 ) ) − 1 ) ) ;
f o r ( i = 0 ; i < 1 < < o r d e r ; i ++) {
i f ( ! p t e n o n e ( ∗ ( w k t a b l e+i ) ) ) {
down pte sp ( page table , p t e t o s p i n d e x ( oldpte ) ) ;
goto r e t r y ;
}
}
#endif
/∗ A l l o c a t e our own p r i v a t e page . ∗/
pte unmap ( p a g e t a b l e ) ;
i f ( u n l i k e l y ( a n o n v m a p r e p a r e (vma ) ) )
goto oom ;
#i f CONFIG SUPER PAGE
page = a l l o c z e r o e d u s e r h i g h p a g e s m o v a b l e (vma , a d d r e s s , o r d e r ) ;
i f ( ! page ) {
i f ( order ) {
s u p e r p a g e d o w n g r a d e [ p t e t o s p i n d e x ( o l d p t e )]++;
down pte sp ( page table , p t e t o s p i n d e x ( oldpte ) ) ;
goto r e t r y ;
}
else {
goto oom ;
}
}
i f ( order ) {
b r e a k a r e a ( page , o r d e r ) ;
s u p e r p a g e a l l o c a t e [ p t e t o s p i n d e x ( o l d p t e )]++;
p a g e t a b l e = p t e o f f s e t m a p l o c k (mm, pmd , a d d r e s s , & p t l ) ;
vma−>v m f l a g s | = VM SUPERPAGE;
spaddr = a d d r e s s & ˜ ( ( PAGE SIZE << o r d e r ) − 1 ) ;
s u p e r p a g e p o p u l a t e (mm, spaddr , page , vma−>vm page prot ,
pte to sp index ( oldpte ) ) ;
f o r ( i = 0 ; i < 1 < < o r d e r ; i ++) {
entry = pte mkwrite ( pte mkdirty (
mk pte ( page+i ,
p g p r o t ( p g p r o t v a l (vma−>v m p a g e p r o t ) | p g p r o t v a l ( s u p e r p a g e p r o t [
pte to sp index ( oldpte ) ] ) ) ) ) ) ;
i n c m m c o u n t e r (mm, a n o n r s s ) ;
l r u c a c h e a d d a c t i v e ( page+i ) ;
page add new anon rmap ( page+i , vma , spaddr ) ;
s e t p t e a t (mm, spaddr , w k t a b l e+i , e n t r y ) ;
spaddr += PAGE SIZE ;
}
} else {
図 4.20: do anonymous page 関数内の Super Page 割り当てを行うコード
28
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ i n c l u d e /asm−i 3 8 6 / p g a l l o c . h ∗/
#i f CONFIG SUPER PAGE
s t a t i c i n l i n e void s u p e r p a g e p o p u l a t e ( struct mm struct ∗mm, unsigned long a d d r e s s ,
struct page ∗ page , p g p r o t t p r o t , i n t s p i n d e x ) {
p g d t ∗ pgd ;
p u d t ∗ pud ;
pmd t ∗pmd ;
union {
pmd t e n t r y ;
pte t pte entry ;
} x;
pgd = p g d o f f s e t (mm, a d d r e s s ) ;
pud = p u d o f f s e t ( pgd , a d d r e s s ) ;
pmd = p m d o f f s e t ( pud , a d d r e s s ) ;
x . p t e e n t r y = mk pte ( page ,
p g p r o t ( p g p r o t v a l ( p r o t ) | PAGE PSE ) ) ;
x . pte entry = pte mkwrite ( pte mkdirty ( x . pte entry ) ) ;
#i f d e f CONFIG X86 PAE
set pmd raw (pmd + PTRS PER PMD ,
pmd ( pmd val ( x . e n t r y ) ) ) ;
#e l s e
set pmd raw (pmd + PTRS PER PGD ,
pmd ( pmd val ( x . e n t r y ) ) ) ;
#endif
}
#endif
図 4.21: TLB 用 PGD の設定を行う super page populate 関数
29
第 4 章 Linux Super Page の設計
4.3.4
4.3 実装方法
Super Page 返却
2008 年 2 月 1 日において未実装であり、現在は Super Page の返却を従来と同じ方法で行っている。メ
モリ開放時のページテーブルなどの解放を < mm/memory.c > の unmap page range 関数が行うため、本
関数を中心にソースコード を追いかけ、Super Page 返却を実現させる部分を探し実装を行う予定である。
4.3.5
ダウングレード
Super Page を割り当てられたページがページスワップやメモリ管理作業によるベースページ単位の作業
を行うため、以下の関数にダウングレード を実装している。
• < mm/memory.c >
copy page range 関数
unmap page range 関数
zeromap page range 関数
• < mm/mprotect.c >
change protection 関数
• < mm/swapf ile.c >
unuse vma 関数
ダウングレードは < mm/super page.c > の adj sp range 関数を用いて行う。vm area struct 構造体の状
態フラグ vm flag に Super Page 用に VM SUPERPAGE という状態を追加し 、該当ページが Super Page 割
り当てされているかをこのフラグで判断する。各関数内で VM SUPERPAGE の状態を判断し 、Super Page
割り当てがされている場合は adj sp range 関数によってダウングレード を行う。図 4.22にダウングレード
を実装した関数へ挿入したコード を示す。
#i f CONFIG SUPER PAGE
i f ( ( ( vma−>v m f l a g s & (VM SHARED | VM MAYWRITE)) == VM MAYWRITE) && (vma−>v m f l a g s &
VM SUPERPAGE) ) {
s p i n l o c k (&src mm−>p a g e t a b l e l o c k ) ;
a d j s p r a n g e ( src mm , 1 , addr , end ) ;
s p i n u n l o c k (&src mm−>p a g e t a b l e l o c k ) ;
vma−>v m f l a g s &= ˜VM SUPERPAGE;
}
#endif
図 4.22: ダウングレード の必要な関数への挿入コード
図 4.23に adj sp range 関数のソースコードを示す。adj sp range 関数は Super Page 境界に合うメモリ領
域を探し 、Super Page のダウングレード を再帰的に行う。実際のダウングレードは adj sp range 関数が内
部で呼び出す adj sp pte 関数で行う (図 4.24)。adj sp pte 関数は仮想アドレスと mm struct 構造体を用い
て、対応する PT を探し出し 、down pte sp 関数を呼び出し PT の Super Page 予約をクリアする (図 4.25)。
そして最後に clear pmd sp マクロを用いて SW 用 PGD を TLB 用 PGD にコピーする (図 4.26)。
30
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ mm/ s u p e r p a g e . c ∗/
void a d j s p r a n g e ( struct mm struct ∗mm, i n t zap ,
unsigned long addr , unsigned long end )
{
int i ;
unsigned long rem ;
i f ( addr >= end )
BUG( ) ;
f o r ( i = 0 ; i < s u p e r p a g e n r − 1 ; i ++) {
rem = ( ˜ addr + 1 ) & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i + 1 ] ) − 1 ) ;
while ( rem &&
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
a d j s p p t e (mm, zap , addr , s u p e r p a g e o r d e r [ i ] ) ;
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
rem −= PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
};
}
f o r ( i = s u p e r p a g e n r − 1 ; i > = 0 ; i −−) {
while (
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
a d j s p p t e (mm, zap , addr , s u p e r p a g e o r d e r [ i ] ) ;
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
};
}
return ;
}
図 4.23: ページサイズのダウングレード を行う adj sp range 関数
/∗ mm/ s u p e r p a g e . c ∗/
void a d j s p p t e ( struct mm struct ∗mm, i n t zap ,
unsigned long a d d r e s s , i n t o r d e r )
{
int i ;
i n t downgrade =0;
p g d t ∗ pgd ;
p u d t ∗ pud ;
pmd t ∗pmd ;
p t e t ∗ pte ;
pgd = p g d o f f s e t (mm, a d d r e s s ) ;
pud = p u d o f f s e t ( pgd , a d d r e s s ) ;
i f ( ! pud ) return ;
pmd = p m d o f f s e t ( pud , a d d r e s s ) ;
i f ( ! pmd ) return ;
p t e = p t e o f f s e t m a p (pmd , a d d r e s s ) ;
i f ( ! p t e ) return ;
/∗
We assume t h a t t h e l a r g e s t s u p e r page i s l e s s or e q u a l t o t h e
mapped a r e a by t h e pmd . Then f o l l o w i n g code d o e s n o t t a k e
t h e p m d o f f s e t a g a i n . I f you want t o u se a l a r g e r s u p e r page ,
you need t o c h e c k t h e code .
∗/
f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
retry :
i f ( s u p e r p a g e o r d e r [ p t e t o s p i n d e x ( ∗ ( p t e+i ) ) ] > o r d e r ) {
d o w n p t e s p ( p t e+i , p t e t o s p i n d e x ( ∗ ( p t e+i ) ) ) ;
downgrade =1;
goto r e t r y ;
}
}
i f ( zap ) c l e a r p t e s p ( pte , p t e t o s p i n d e x ( ∗ p t e ) ) ;
i f ( zap | | downgrade ) c l e a r p m d s p (pmd ) ;
return ;
}
図 4.24: adj sp pte 関数
31
第 4 章 Linux Super Page の設計
4.3 実装方法
/∗ mm/ s u p e r p a g e . c ∗/
void d o w n p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x )
{
int i , order ;
p t e t ∗ addr ;
order = super page order [ index ] ;
addr = ( p t e t ∗ ) ( ( unsigned long ) p t e p t r &
˜ ( ( 1UL<<(o r d e r + SIZEOF PTE LOG2 ) ) − 1 ) ) ;
f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
#i f CONFIG X86
( ∗ ( addr+i ) ) . p t e l o w =
( ( ∗ ( addr+i ) ) . p t e l o w & ˜SUPER PAGE MASK ) |
pgprot val ( super page prot [ index −1]);
#e l s e
p t e v a l ( ∗ ( addr+i ) ) = ( p t e v a l ( ∗ ( addr+i ) ) & ˜SUPER PAGE MASK ) |
pgprot val ( super page prot [ index −1]);
#endif
}
}
図 4.25: down pte sp 関数
/∗ i n c l u d e /asm−i 3 8 6 / p g t a b l e . h ∗/
#i f CONFIG SUPER PAGE
extern p g p r o t t s u p e r p a g e p r o t [ ] ;
extern i n t s u p e r p a g e o r d e r [ ] ;
#define p t e t o s p i n d e x ( x ) ( ( ( x ) . p t e l o w & SUPER PAGE MASK) > > SUPER PAGE MASK SHIFT)
static i n l i n e p t e t mk pte sp clean ( p t e t pte )
{ ( p t e ) . p t e l o w &= ˜SUPER PAGE MASK ; return p t e ; }
void d o w n p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x ) ;
void c l e a r p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x ) ;
#define s e t p t e r a w ( p t e p t r , p t e v a l ) s e t p t e ( p t e p t r , p t e v a l )
#i f d e f CONFIG X86 PAE
#define SIZEOF PTE LOG2 3
s t a t i c i n l i n e void c l e a r p m d s p ( pmd t ∗pmd ) {
set pmd raw ( ( pmd+PTRS PER PMD ) , ∗ pmd ) ;
}
#e l s e
#define SIZEOF PTE LOG2 2
s t a t i c i n l i n e void c l e a r p m d s p ( pmd t ∗pmd ) {
set pmd raw ( ( pmd+PTRS PER PGD ) , ∗ pmd ) ;
}
#endif
#endif
図 4.26: clear pmd sp マクロ
32
第 4 章 Linux Super Page の設計
4.3.6
4.3 実装方法
カーネルインタフェース
Linux では /proc ファイルシステムを用いてシステムのチューニングパラメータへのアクセスを提供してい
る。このため/proc ファイルシステムを用いて Super Page 機構用パラメータを操作する。< mm/super page.c >
ファイル内に用意した super page getinfo 関数を用いることで、< /proc/super page > を介してパラメータ
の読み出しが可能である。また、設定は < mm/super page.c > ファイル内で ctl table 構造体を用いて定義
したパラメータに対して、< /proc/sys/super page > を利用して行なう。図 4.2に < /proc/super page >
で読み出し可能なパラメータ、図 4.3に < /proc/sys/super page > で設定可能なパラメータを示す。Super
Page パラメータの読み出しは cat コマンド、設定は echo コマンド または sysctl インタフェースを用いて行
なうことができる。図 4.27に Super Page パラメータの読み出しと設定を行なった際のターミナル画面を
示す。
表 4.2: < /proc/super page > で読み出し可能なパラメータ
パラメータ
Zoned Buddy allocate MAXORDER
current on
current nr
current bitmask
current vm align
order reserve allocate fail
内容
バデ ィシステムの割り当て可能な最大オーダー
Super Page 使用可能状態 (0:使用不可、1:使用可能)
システムの利用可能なページ数
Super Page 用のビットマスク
動的 Super Page 境界合わせ機能の有無 (0:無効、1:有効)
割り当てオーダー、Super Page 予約数、
Super Page 割り当て数、Super Page 割り当て失敗数
表 4.3: < /proc/sys/super page > で設定可能なパラメータ
パラメータ
bitmask
logreset
nr
on
vm align
内容
Super Page 用のビットマスク
Super Page パラメータの予約数、割り当て数、ダウングレード 数のリセット (1:リセット )
システムの利用可能なページ数
Super Page 使用可能状態 (0:使用不可、1:使用可能)
動的 Super Page 境界合わせ機能の有無 (0:無効、1:有効)
図 4.27: Super Page パラメータの設定と読み出し実行時のターミナル画面
33
第 5 章 性能評価
性能評価を 3 つのマシンで行なった。表 5.1にそれぞれのマシンに搭載されているプロセッサ情報を示す。
本稿では AMD Athlon(tm) を搭載したマシンを Athlon マシン 、Intel(R) Celeron(R) を搭載したマシンを
Celeron マシン 、Intel(R) Pentium(R) 4 を搭載したマシンを Pentium 4 マシンと述べる。評価は行列転置
プログラム、SPEC CPU2000 ベンチマーク、姫野ベンチマークの 3 つを用いて行い、コンパイラは GNU
gcc バージョン 3.3.2 と GNU g77 バージョン 3.3.2 を用いた。
表 5.1: 使用プロセッサ
使用プロセッサ
AMD Athlon(tm)
Intel(R) Celeron(R)
Intel(R) Pentium(R) 4
CPU
Family
6
15
15
Model
8
2
2
CPU
Frequency[MHz]
1094.152
2392.279
2800.868
Cache
Size[KB]
256
128
512
Data TLB entry
for 4MB and 2MB
for 4KB
8(L1)
32(L1), 256(L2)
64
64
行列転置プログラム
5.1
行列の転置を行うプログラムを実行し 、メモリ転送性能を評価する。本プログラムは清水尚彦研究室ホーム
ページから取得可能である8) 。プログラムの内容は以下の通りである。コンパイルオプションには ”-funroll-
loops”を用いた。ソースコード の一部を図 5.1に示す。
• Dimension*Dimension の正方配列 b から同サイズの正方配列 a への転置複製を行う
• mmap 関数によりメモリを確保する
• 複製元の配列を縦方向に読み出す方式 (Load Stride 方式) と複製先の配列に縦方向に書き込む方式
(Store Stride 方式) を行う
• Dimension の値を 500 から 3500 の間で設定する
f o r ( k = 0 ; k<ITR ; k++) {
f o r ( i = 0 ; i <dim ; i ++) {
f o r ( j = 0 ; j <dim ; j ++) {
a[ i ][ j ] = b[ j ][ i ];
}
}
}
図 5.1: 行列転置ベンチマークプログラム
5.1.1
実行結果
図 5.2 、図 5.3 、図 5.4に Athlon マシンにおけるオリジナルと Super Page カーネルの Load Stride 方式
及び Store Stride 方式の転送性能と、Super Page カーネルの転送性能をオリジナルの転送性能で割って算
出した転送性能比を示す。同様に図 5.5 、図 5.6 、図 5.7には Celeron マシンの、図 5.8 、図 5.9 、図 5.10には
Pentium 4 マシンの転送性能と転送性能比を示す。
34
第 5 章 性能評価
5.1 行列転置プログラム
200
200
Original Kernel
150
Performance[MB/s]
Performance[MB/s]
150
100
100
50
0
500
Super Page Kernel
50
1000
1500
2000
2500
3000
0
500
3500
1000
The Dimension of the Transpose matrix
1500
2000
2500
3000
3500
The Dimension of the Transpose matrix
(a) オリジナルカーネル
(b)Super Page カーネル
図 5.2: Athlon マシンにおける Load Stride 方式転送性能
200
200
Original Kernel
150
Performance[MB/s]
Performance[MB/s]
150
100
100
50
0
500
Super Page Kernel
50
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
0
500
3500
(a) オリジナルカーネル
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
3500
(b)Super Page カーネル
図 5.3: Athlon マシンにおける Store Stride 方式転送性能
5
5
Load Stride case
4
Relative Performance of the Super page
Relative Performance of the Super page
4
3
2
1
0
500
Store Stride case
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
3
2
1
0
500
3500
(a)Load Stride
1000
1500
2000
2500
The Dimension of the Transpose matrix
(b)Store Stride
図 5.4: Athlon マシンにおけるオリジナル対 Super Page カーネル性能比
35
3000
3500
第 5 章 性能評価
5.1 行列転置プログラム
300
Original Kernel
250
250
200
200
Performance[MB/s]
Performance[MB/s]
300
150
150
100
100
50
50
0
500
1000
1500
2000
2500
3000
Super Page Kernel
0
500
3500
1000
The Dimension of the Transpose matrix
1500
2000
2500
3000
3500
The Dimension of the Transpose matrix
(a) オリジナルカーネル
(b)Super Page カーネル
図 5.5: Celeron マシンにおける Load Stride 方式転送性能
300
Original Kernel
250
250
200
200
Performance[MB/s]
Performance[MB/s]
300
150
150
100
100
50
50
0
500
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
Super Page Kernel
0
500
3500
(a) オリジナルカーネル
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
3500
(b)Super Page カーネル
図 5.6: Celeron マシンにおける Store Stride 方式転送性能
5
5
Load Stride case
4
Relative Performance of the Super page
Relative Performance of the Super page
4
3
2
1
0
500
Store Stride case
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
3
2
1
0
500
3500
(a)Load Stride
1000
1500
2000
2500
The Dimension of the Transpose matrix
(b)Store Stride
図 5.7: Celeron マシンにおけるオリジナル対 Super Page カーネル性能比
36
3000
3500
第 5 章 性能評価
5.1 行列転置プログラム
700
Original Kernel
600
600
500
500
Performance[MB/s]
Performance[MB/s]
700
400
300
400
300
200
200
100
100
0
500
1000
1500
2000
2500
3000
Super Page Kernel
0
500
3500
1000
The Dimension of the Transpose matrix
1500
2000
2500
3000
3500
The Dimension of the Transpose matrix
(a) オリジナルカーネル
(b)Super Page カーネル
図 5.8: Pentium 4 マシンにおける Load Stride 方式転送性能
700
Original Kernel
600
600
500
500
Performance[MB/s]
Performance[MB/s]
700
400
300
400
300
200
200
100
100
0
500
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
Super Page Kernel
0
500
3500
(a) オリジナルカーネル
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
3500
(b)Super Page カーネル
図 5.9: Pentium 4 マシンにおける Store Stride 方式転送性能
8
8
Load Stride case
6
5
4
3
2
1
0
500
Store Stride case
7
Relative Performance of the Super page
Relative Performance of the Super page
7
6
5
4
3
2
1
1000
1500
2000
2500
The Dimension of the Transpose matrix
3000
0
500
3500
(a)Load Stride
1000
1500
2000
2500
The Dimension of the Transpose matrix
(b)Store Stride
図 5.10: Pentium 4 マシンにおけるオリジナル対 Super Page カーネル性能比
37
3000
3500
第 5 章 性能評価
5.1 行列転置プログラム
表 5.2にそれぞれのマシンにおけるオリジナルと Super Page カーネルの最大性能比、最小性能比を示す。
表 5.2: 行列転置ベンチマーク性能比
マシン
Load Stride
Store Stride
最大 [倍]
最小 [倍]
最大 [倍]
最小 [倍]
athlon マシン
4.6
1.2
4.8
1.2
Celeron マシン
4.1
0.4
4.3
0.4
Pentium 4 マシン
6.9
0.4
4.4
0.6
それぞれのプロセッサの 4MB 用の TLB エントリ数は athlon が 8 エントリ、Celeron と Pentium 4 が
64 エントリである。4MB ページサイズによるメモリ管理を行った場合、athlon では ”4M B ∗ 8entry” の
32MB 、Celeron と Pentium 4 で ”4M B ∗ 64entry” の 256MB が TLB の有効範囲となる。ただし 、Celeron
と Pentium 4 は 64 エントリを全て 4MB 用として使用しているとは限らない。行列転置プログラムにおけ
る最大メモリ利用量は Dimension が 3500 の場合、利用するメモリ領域は 188MB である。これを考慮し 、
Celeron と Pentium 4 は Dimension が最大値の 3500 に近付くと TLB ミスが増加し 、Super Page 機構利
用時の性能は緩やかに低下すると考えた。今回の結果では Pentium 4 では緩やかな性能低下であったが 、
Celeron では Dimension が 1000 付近で性能が急激に低下し 、Dimension が 1500 以降となると Super Page
カーネルとオリジナルカーネルの性能差がなくなるという結果を得た。また athlon マシンでは、4MB 用の
TLB エントリ数の少なさから、Super Page 機構利用時において Dimension が 1500 、つまり利用メモリが
約 36MB 付近で性能が低下すると予想したが 、大きく性能低下することはなかった。
38
第 5 章 性能評価
5.2
5.2SPEC CPU2000
SPEC CPU2000
SPEC CPU2000 は SPEC(Standard Performance Evaluation Corporation) によって設計され 、実用的
なハード ウェアの広範囲で、徹底的な性能計算の測定比較を提供するものである9) 。その実装は結果的に実
際のユーザアプリケーションから開発されたソースコードに帰着し 、ベンチマークは評価環境におけるプロ
セッサ、メモリ、コンパイラの性能を測定する。SPEC CPU2000 には整数演算性能を評価する CINT2000
と浮動小数点演算性能を評価する CFP2000 の 2 つがある。今回はこの 2 つを実行し 、評価を行った。表
5.3に SPEC CPU2000 に用いたオプションを示す。
表 5.3: SPEC CPU2000 オプション一覧表
テストベンチ
CINT 2000
全て
164.gzip
175.vpr
176.gcc
181.mcf
186.crafty
197.parser
252.eon
253.perlbmk
254.gap
CINT 2000
5.2.1
255.vortex
256.bzip2
300.twolf
全て
168.wupwise
171.swim
172.mgrid
173.applu
177.mesa
178.galgel
179.art
183.equake
187.facerec
188.ammp
189.lucas
191.fma3d
200.sixtrack
301.apsi
オプション
-O3 -mfpmath=sse -march=pentium3 -funroll-loops
無し
無し
-ffloat-store
無し
-DLINUX i386
無し
無し
-DSPEC CPU2000 LINUX I386 -DSPEC CPU2000 NEED BOOL
-DSPEC CPU2000 NEED TIME H -DSPEC CPU2000 GLIBC22
-DSYS IS USG -DSYS HAS IOCTL PROTO
-DSYS HAS TIME PROTO -DSYS HAS SIGNAL PROTO
-DSYS HAS ANSI -DSYS HAS CALLOC PROTO
-DSYS HAS READ PROTO
無し
無し
無し
-O3 -fomit-frame-pointer -malign-double
無し
無し
無し
無し
無し
無し
無し
無し
無し
無し
無し
無し
無し
無し
実行結果
図 5.11 、図 5.12 、図 5.13にそれぞれのマシンで実行した SPEC CPU2000 ベンチマークの実行結果を
示す。ただし 、コンパイルエラーによって未実行のベンチマークがいくつかある。未実行のベンチマー
クは、CINT2000 の 252.eon 、255.vortex ベンチマーク、CFP2000 の 178.galgel 、187.facerec 、189.lucas 、
191.fma3d ベンチマークである。 今回の実行結果から、3 つのマシンにおける CFP2000 、CINT2000 のプ
ログラムにおける性能比は約 1 倍であり性能向上を得られなかった。しかし 、未実行のベンチマークもあ
るため、全てのベンチマークを実行した上で評価をまとめたい。
39
第 5 章 性能評価
5.2SPEC CPU2000
(a)CINT2000
(b)CFP2000
図 5.11: Athlon マシンにおける SPEC CPU2000 実行結果
(b)CFP2000
(a)CINT2000
図 5.12: Celeron マシンにおける SPEC CPU2000 実行結果
(b)CFP2000
(a)CINT2000
図 5.13: Pentium 4 マシンにおける SPEC CPU2000 実行結果
40
第 5 章 性能評価
5.3
5.3 姫野ベンチマーク
姫野ベンチマーク
姫野ベンチマークは理科学研究所情報基盤センターのセンター長である姫野龍太郎氏が非圧縮流体解析
コード の性能評価のために考え、ポアッソン方程式解法をヤコビの反復法で解く場合に主要なループの処理
速度を計るものである10) 。また姫野ベンチマークテストは主に計算機のメモリバンド 幅などの性能を測定
するために用いられる。姫野ベンチマークテストには C 言語版と Fortran 版があるが,本評価では Fortran
版を用いて S サイズと M サイズの実行を行った。コンパイルオプションには ”-O3”を用いた。
5.3.1
実行結果
図 5.14 、図 5.15 、図 5.16にそれぞれのマシンで実行した姫野ベンチマークの実行結果を示す。
図 5.14: Athlon マシンにおける姫野ベンチマーク実 図 5.15: Celeron マシンにおける姫野ベンチマーク実
行結果
行結果
図 5.16: Pentium 4 マシンにおける姫野ベンチマーク実行結果
Celeron マシン 、Pentium 4 マシンにおいては性能比は約 1 倍であり、オリジナルと Super Page カーネ
ルで性能差を得ることはできなかった。しかし 、athlon マシンにおいては Super Page カーネルの性能はオ
リジナルの約 0.3 倍となり、性能が大きく低下した。athlon の TLB エントリ数は今回使用した Intel のプロ
セッサの 1/8 であり、4MB 用の TLB エントリ数が少ないことが今回の性能低下を招いたと考える。近年
発表された AMD の 10h ファミリープロセッサのデータ TLB エントリ数は L1 キャッシュで 24 、L2 キャッ
シュで 64 であり、このような TLB のエントリ数の多いプロセッサを使用すれば 、AMD のマシンにおいて
も今回のような性能低下を招くことはないと考える。
41
第 6 章 今後の課題
6.1
Super Page 返却の実装
設計方針である Super Page 返却の実装が完了していないため、Super Page 返却の実装を行う。そして、
実装後に Super Page を利用するプログラムを複数回実行し 、システムの Super Page 保有数の遷移を調査
することで本実装の有効性を評価する。
6.2
最新 Linux カーネルへの対応
Linux カーネルのバージョンは逐次更新されており、バージョンの違いによってソースコードが全く異な
る場合がある。このため、今後は新規バージョンに対応した Super Page 機構を作成する必要がある。2008
年 2 月 1 日現在における安定版カーネルバージョンは 2.6.24 であるため、次回はこのカーネルバージョン
をターゲットに Super Page 機構を実装する。
6.3
他プロセッサアーキテクチャへの対応
現在 Linux カーネルでサポートしているプロセッサアーキテクチャは Alpha 、SPARC 、IA-32 、ARM 、
IA-64 、PowerPC 、SPARC64 など 多数存在する。このため、今後は他のプロセッサアーキテクチャに対応
した Super Page 機構を実装する必要がある。特に 64 ビットプロセッサは 32 ビットプロセッサと比べ性能
面で向上が期待でき、64 ビットプロセッサを搭載したコンピュータが今後の主流となる考えることができ
るため、64 ビットプロセッサに対応した Super Page 機構の実装を積極的に行う必要がある。
6.4
性能評価
評価マシンにおけるコンパイル環境の整備不足により、SPEC CPU2000 では未実行のベンチマークがあ
る。このため、今後は評価マシンにおけるコンパイル環境の整備を行い、全てのベンチマークを実行し 、評
価結果をまとめる。また、今回の性能評価では同じアーキテクチャのプロセッサを用いて評価を行ったが 、
プロセッサの違いにより性能に差があった。これは 4MB 用の TLB エントリ数の違いが原因であると考え、
今後は TLB のエントリ数と Super Page カーネルにおけるアプリケーション性能の関係を明らかにし 、ど
のようなプロセッサに Super Page カーネルが有効であるかを検討する。
42
第 7 章 おわりに
近年、Super Page を用いたメモリ管理を行うことによって TLB ミスを削減させ、アプ リケーションの
性能向上を図る OS がいくつか存在する。しかし 、既存のこれらの OS には使いやすさ、効率的なメモリ
利用、そしてアプ リケーションの移植の面などに問題が存在する。我々はこれらの問題を解決した Super
Page 機構を LinuxOS に実装し 、行列転置プログラム、SPEC CPU2000 、姫野ベンチマークを用いて性能
評価を行った。行列転置プログラムにおいては athlon マシン 、Pentium 4 マシンにおいて約 2 倍から 5 倍
の性能向上を図ることができたが 、SPEC CPU2000 と姫野ベンチマークにおいては Super Page カーネル
はオリジナルカーネルと同等の性能であった。
今後は現在未実装である Super Page 返却の実装を行い、Super Page の再利用性を向上させる。また、最
新のカーネルバージョンや他のプロセッサアーキテクチャ、特に 64 ビットプロセッサをターゲットとした
実装を行い、Linux Super Page の幅広いサポートを行うとともに 、Linux Super Page がど のようなプロ
セッサに有効であるかを検討する。
43
謝辞
研究指導教員であります清水尚彦教授につきましては、本研究を進める上で多大なる御指導と数々の有
益な御助言を頂きました。また、様々な研究発表の機会を与えていただき、いくつかの成果を残すことがで
きましたことを感謝いたします。
清水研究室の方々には研究活動やその他の面で精神的、技術的に支援して頂きました。そして、清水研究
室で関わったプロジェクト メンバの方々とは、プロジェクトを進める中で苦楽を共にし 、お互いに拙差琢磨
し勤勉に励むことができました。本当にありがとうございました。
最後に私の大学院進学に理解をしていただき、献身的な協力を頂きました家族の方々に感謝いたします。
44
業績
論文
1. 木下,並木, 堀口,清水:
初学者によるペイントツールハード ウェアの開発とその教育的効果
第 26 回パルテノン研究会,2005 年 5 月
2. 並木, 木下,堀口,清水:
組込みシステム設計教育としてのペイントツールハード ウェアの開発
第 7 回組込みシステム技術に関するサマーワークショップ ,2005 年 7 月
3. 並木,水野, 木下,御村, 大山:
MDD ロボットチャレンジチーム MONTBLANC 報告書
情報処理学会第 3 回 MDD ロボットチャレンジ ,2005 年 11 月
4. 並木, 木下,清水:
SFL による 8086 互換プロセッサとコンピュータシステムの設計及び DOS マシンとしての実現
第 28 回パルテノン研究会,2006 年 6 月
5. 木下,並木, 清水:
実践教育としての IBM PC 互換システムの設計
リコンフィギャラブルシステム研究会,2006 年 9 月
6. 木下,並木, 近藤, 中島, 清水:
ハード ウェア・ソフトウェア
協調エミュレーション・シミュレーション手法
第 20 回システム評価研究発表会,2007 年 3 月
7. Takahito Nakajima, Shigeru Namiki, Shuhei Kinoshita and Naohiko Shimizu:
A Portable Co-Verification System Which Generates Transactor and Testbench Automatically
International Conference on Field-Programmable Technology 2007,2007 年 12 月
8. 金子, 田村、中島、木下,清水:
組込み教材「時計」の開発
第 31 回パルテノン研究会,2007 年 12 月
9. 木下,清水:
2.6 系カーネルに対する Linux Super Page の実装と性能評価
第 168 回計算機アーキテクチャ研究会,2008 年 1 月
展示会出展
1. MDD ロボットチャレンジ飛行船制御システムの開発
Embedded Technology 2005
2. FPGA を利用したワンチップコンピュータシステム
Embedded Technology 2005
45
業績
3. LSI 開発のための FPGA を用いた高速検証環境の構築
Embedded Technology 2006
4. PC/XT 互換システムの開発
Electronic Design and Solution Fair 2007
5. LSI 開発のための FPGA を用いた高速検証環境の構築
Electronic Design and Solution Fair 2007
6. 組み込み教材開発に向けての取り組み
Embedded Technology 2007
7. 組み込み教材開発に向けての取り組み
Electronic Design and Solution Fair 2008
その他
1. 特別企画 MDD ロボットチャレンジチーム MONTBLANC 奨励賞組込みソフトウェアシンポジウ
ム,2005
46
参考文献
1) 高取 研, ”IA32 版 Linux Super Page の開発”, 2001F 年度 東海大学 工学部 通信工学科 学部論文, 2001
2) Naohiko Shimizu, Ken Takatori, ”A Linux Super Page Kernel for Alpha, Sparc64 and IA32 -Reducing
TLB Misses of Applications”, MEDIA 2002 workshop, 2002
3) 早坂 晴康, ”シャド ーペジーディレクトリを用いた IA-32 版 Linux Super Page の実現と Super Page 端
数増大によって起こるメモリ転送性能低下に対する Page Coloring による改善”, 2003 年度 東海大学大
学院 工学研究科 電気工学専攻 修士論文, 2003
4) 高橋 浩和, 小田 逸郎, 山幡 為佐久, ”Linux カーネル 2.6 解読室”, ソフトバンク クリエイティブ株式会
社, 2007
5) Daniel P. Bovet, Marco Cesati, ”詳解 Linux カーネル 第3版”, 株式会社オライリー・ジャパン , 2007
6) Linux Kernel Hack Japan,
http://hira.main.jp/wiki/ (2008 年 1 月 31 日)
7) The Linux Kernel Archives,
http://www.sgi.com/ (2008 年 1 月 31 日)
8) 東海大学清水尚彦研究室ホームページ ,
http://shimizu-lab.dt.u-tokai.ac.jp/ (2008 年 1 月 31 日)
9) Spec CPU2000,
http://www.spec.org (2008 年 1 月 31 日)
10) HIMENO BMT,
http://accc.riken.jp/HPC/index.html/ (2008 年 1 月 31 日)
11) Intel,
http://www.intel.com/ (2008 年 1 月 31 日)
12) AMD,
http://www.amd.com/ (2008 年 1 月 31 日)
13) SGI,
http://www.sgi.com/ (2008 年 1 月 31 日)
14) HP,
http://www.hp.com/ (2008 年 1 月 31 日)
15) SUN,
http://www.sun.com/ (2008 年 1 月 31 日)
47
付 録A
Linux2.6.23 における IA-32 用 Super Page パッ
チファイル
本研究における変更ファイルと追加ファイルは以下に示す通りであり、我々は Linux2.6.23 における IA-32
用 Super Page パッチファイルを作成した。
• 変更ファイル
– arch/i386/Kconf ig
– arch/i386/kernel/head.S
– arch/i386/mm/f ault.c
– arch/i386/mm/init.c
– arch/i386/mm/pgtable.c
– include/asm − generic/pgtable − nopmd.h
– include/asm − generic/pgtable − nopud.h
– include/asm − i386/cpuf eature.h
– include/asm − i386/mmuc ontext.h
– include/asm − i386/page.h
– include/asm − i386/pgalloc.h
– include/asm − i386/pgtable − 2level.h
– include/asm − i386/pgtable − 3level.h
– include/asm − i386/pgtable.h
– include/asm − i386/tlbf lush.h
– include/linux/gf p.h
– include/linux/highmem.h
– include/linux/mm.h
– include/linux/sysctl.h
– kernel/sysctl.c
– mm/M akef ile
– mm/memory.c
– mm/mempolicy.c
– mm/mmap.c
– mm/mprotect.c
– mm/swapf ile.c
• 追加ファイル
– mm/superp age.c
Linux Super Page の利用方法について説明する。カレントディレクトリを linux2.6.23 のカーネルソースの
ある場所に移し 、本パッチファイルをカレントディレクトリに置く。そして patch コマンドを用いて ”patch
−p1 < パッチファイル ” とタイプし 、上記に示したソースの変更部分及び追加部分をオリジナルカーネル
に追加する。そして、Super Page カーネル用にカーネルをコンパイルする場合は、”SuperP ageSupport”
の項目を必ずオンにしてからコンパイルする (図 A.1)。コンパイル完了後、Super Page カーネルを起動さ
せ第 4章で説明したカーネルインタフェースを用いて、Super Page 使用可能パラメータをオンにすること
で Super Page の利用が可能となる。リスト A.1に Linux2.6.23 における IA-32 用 Super Page パッチファイ
ルを示す。
48
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
図 A.1: make menuconfig 実行時のターミナル画面
リスト A.1: Linux2.6.23 における IA-32 用 Super Page パッチファイル
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
d i f f −urN l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 / K c o n f i g l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 / K c o n f i g
−−− l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 / K c o n f i g 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 / K c o n f i g 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 9 2 6 , 6 + 9 2 6 , 2 5 @@
I f unsure , s ay Y.
+
+c o n f i g SUPER PAGE
+ b o o l ” T r a n s p a r e n t SuperPage Support ”
+ def bool y
+ help
+ With t u r n i n g on , k e r n e l w i l l u s e maximum s u p e r page f o r
+ bss , brk o r anonymous mmap a r e a t r a n s p a r e n t l y .
+
+c o n f i g FORCE MAX ZONEORDER
+ int
+ depends on SUPER PAGE
+ default ” 11 ”
+
+c o n f i g X86 K7 INVLPG BUG
+ b o o l ” Athlon 4MB TLB BUG workaround ”
+ depends on SUPER PAGE && MK7
+ def bool y
+
+
endmenu
c o n f i g ARCH ENABLE MEMORY HOTPLUG
@@ − 1 3 0 1 , 3 + 1 3 2 0 , 5 @@
c o n f i g KTIME SCALAR
bool
default y
+
+
d i f f −urN l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 / k e r n e l / head . S l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 / k e r n e l /
head . S
−−− l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 / k e r n e l / head . S 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 / k e r n e l / head . S 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 1 3 0 , 6 + 1 3 0 , 1 0 @@
∗ can be used a s a GPR i f you r e a l l y need i t . . .
∗/
49
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
p a g e p d e o f f s e t = ( PAGE OFFSET > > 20);
+#i f CONFIG SUPER PAGE
+ s h a d o w p d e o f f s e t = 0 x1000 ;
+ shadow page pde offset = page pde offset + shadow pde offset ;
+#e n d i f
movl $ ( pg0 − PAGE OFFSET) , % e d i
movl $ ( s w a p p e r p g d i r − PAGE OFFSET) , % edx
@@ − 1 3 8 , 6 + 1 4 2 , 1 0 @@
l e a l 0 x007(% e d i ) ,% e c x
/∗ C r e a t e PDE e n t r y ∗/
movl %ecx ,(% edx )
/∗ S t o r e i d e n t i t y PDE e n t r y ∗/
movl %ecx , p a g e p d e o f f s e t (%edx ) /∗ S t o r e k e r n e l PDE e n t r y ∗/
+#i f CONFIG SUPER PAGE
+ movl %ecx , s h a d o w p d e o f f s e t (%edx )
/∗ S t o r e i d e n t i t y SHADOW PDE e n t r y ∗/
+ movl %ecx , s h a d o w p a g e p d e o f f s e t (%edx ) /∗ S t o r e k e r n e l PDE e n t r y ∗/
+#e n d i f
a d d l $4 ,% edx
movl $1024 , % e c x
11:
@@ − 1 6 7 , 7 + 1 7 5 , 1 1 @@
#e n d i f
/∗ Do an e a r l y i n i t i a l i z a t i o n o f t h e fixmap a r e a ∗/
+#i f CONFIG SUPER PAGE
+ movl $ ( s w a p p e r t l b d i r − PAGE OFFSET) , % edx
+#e l s e
movl $ ( s w a p p e r p g d i r − PAGE OFFSET) , % edx
+#e n d i f
movl $ ( swapper pg pmd − PAGE OFFSET) , % eax
a d d l $0x007 , % eax
/∗ 0 x007 = PRESENT+RW+USER ∗/
movl %eax , 4 0 9 2 ( % edx )
@@ − 2 3 6 , 7 + 2 4 8 , 1 1 @@
/∗
∗ Enable p a g i n g
∗/
+#i f CONFIG SUPER PAGE
+ movl $ s w a p p e r t l b d i r − PAGE OFFSET,% eax
+#e l s e
movl $ s w a p p e r p g d i r − PAGE OFFSET,% eax
+#e n d i f
movl %eax ,% c r 3 /∗ s e t t h e page t a b l e p o i n t e r . . ∗/
movl % cr0 ,% eax
o r l $0x80000000 ,% eax
@@ − 5 1 1 , 7 + 5 2 7 , 1 3 @@
. s e c t i o n ” . b s s . p a g e a l i g n e d ” , ”wa”
. a l i g n PAGE SIZE asm
ENTRY( s w a p p e r p g d i r )
+#i f CONFIG SUPER PAGE
+ . f i l l 1024 ,4 ,0
+ENTRY( s w a p p e r t l b d i r )
. f i l l 1024 ,4 ,0
+#e l s e
+ . f i l l 1024 ,4 ,0
+#e n d i f
ENTRY( swapper pg pmd )
. f i l l 1024 ,4 ,0
ENTRY( e m p t y z e r o p a g e )
d i f f −urN l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 /mm/ f a u l t . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 /mm/ f a u l t . c
−−− l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 /mm/ f a u l t . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 /mm/ f a u l t . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 2 7 5 , 6 + 2 7 5 , 9 @@
∗ an i n t e r r u p t i n t h e middle o f a t a s k switch . .
∗/
pgd paddr = r e a d c r 3 ( ) ;
+#i f CONFIG SUPER PAGE
+ pgd paddr −= ( s i z e o f ( p g d t ) ∗PTRS PER PGD ) ;
+#e n d i f
pmd k = v m a l l o c s y n c o n e ( v a ( pgd paddr ) , a d d r e s s ) ;
i f ( ! pmd k )
return −1;
50
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
@@ − 5 4 6 , 7 + 5 4 9 , 6 @@
p r i n t k ( ” a t v i r t u a l a d d r e s s %08 l x \n” , a d d r e s s ) ;
p r i n t k (KERN ALERT ” p r i n t i n g e i p : \ n” ) ;
p r i n t k ( ”%08 l x \n” , r e g s −>e i p ) ;
−
page = r e a d c r 3 ( ) ;
page = ( ( t y p e o f ( page ) ∗ )
v a ( page ) ) [ a d d r e s s >> PGDIR SHIFT ] ;
#i f d e f CONFIG X86 PAE
d i f f −urN l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 /mm/ i n i t . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 /mm/ i n i t . c
−−− l i n u x − 2 . 6 . 2 3 / a r c h / i 3 8 6 /mm/ i n i t . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 /mm/ i n i t . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 5 0 , 6 + 5 0 , 1 9 @@
DEFINE PER CPU( struct mmu gather , mmu gathers ) ;
unsigned long h i g h s t a r t p f n , h i g h e n d p f n ;
+#i f CONFIG SUPER PAGE
+#i f d e f CONFIG X86 PAE
+i n t s u p e r p a g e o r d e r [ SUPER PAGE NR] = { 0 , 9 } ;
+#e l s e
+i n t s u p e r p a g e o r d e r [ SUPER PAGE NR] = { 0 , 1 0 } ;
+#e n d i f
+p g p r o t t s u p e r p a g e p r o t [ SUPER PAGE NR] = { p g p r o t ( 0 ) ,
+
+EXPORT SYMBOL( s u p e r p a g e o r d e r ) ;
+EXPORT SYMBOL( s u p e r p a g e p r o t ) ;
+#e n d i f
+
+
s t a t i c i n t n o i n l i n e d o t e s t w p b i t ( void ) ;
p g p r o t ( PAGE SUPER ) } ;
/∗
@@ −567 ,7 +580 ,11 @@
pagetable init ();
+#i f CONFIG SUPER PAGE
+ l o a d c r 3 ( s w a p p e r p g d i r+PTRS PER PGD ) ;
+#e l s e
load cr3 ( swapper pg dir );
+#e n d i f
#i f d e f CONFIG X86 PAE
/∗
@@ −749 ,11 +766 ,19 @@
s i z e t p g d s i z e = PTRS PER PGD∗ s i z e o f ( p g d t ) ;
i f (PTRS PER PMD > 1 ) {
+#i f CONFIG SUPER PAGE
+ pmd cache = k m e m c a c h e c r e a t e (”pmd” ,
+
PTRS PER PMD∗ s i z e o f ( pmd t ) ∗ 2 ,
+
PTRS PER PMD∗ s i z e o f ( pmd t ) ∗ 2 ,
+
SLAB PANIC,
+
pmd ctor ) ;
+#e l s e
pmd cache = k m e m c a c h e c r e a t e (”pmd” ,
PTRS PER PMD∗ s i z e o f ( pmd t ) ,
PTRS PER PMD∗ s i z e o f ( pmd t ) ,
SLAB PANIC,
pmd ctor ) ;
+#e n d i f
i f ( ! SHARED KERNEL PMD) {
/ ∗ I f we ’ r e i n PAE mode and have a non−s h a r e d
k e r n e l pmd , t h e n t h e pgd s i z e must be a
d i f f −urN l i n u x −2.6.23/ a r c h / i 3 8 6 /mm/ p g t a b l e . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 /mm/
pgtable . c
−−− l i n u x −2.6.23/ a r c h / i 3 8 6 /mm/ p g t a b l e . c 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / a r c h / i 3 8 6 /mm/ p g t a b l e . c 2008 −01 −21 18:43:15.000000000 +0900
@@ −240 ,11 +240 ,23 @@
unsigned long f l a g s ;
51
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/ ∗ !PAE, no p a g e t a b l e s h a r i n g ∗/
+#i f CONFIG SUPER PAGE
+ memset ( pgd + s i z e o f ( p g d t ) ∗PTRS PER PGD , 0 , USER PTRS PER PGD∗ s i z e o f ( p g d t ) ) ;
+#e n d i f
memset ( pgd , 0 , USER PTRS PER PGD∗ s i z e o f ( p g d t ) ) ;
s p i n l o c k i r q s a v e (& p g d l o c k , f l a g s ) ;
/∗ must happen under l o c k ∗/
+#i f CONFIG SUPER PAGE
+ c l o n e p g d r a n g e ( ( p g d t ∗ ) pgd + USER PTRS PER PGD + PTRS PER PGD,
+
s w a p p e r p g d i r + USER PTRS PER PGD ,
+
KERNEL PGD PTRS ) ;
+ p a r a v i r t a l l o c p d c l o n e ( ( p a ( pgd + s i z e o f ( p g d t ) ∗PTRS PER PGD)) > > PAGE SHIFT ,
+
p a ( s w a p p e r p g d i r ) > > PAGE SHIFT ,
+
USER PTRS PER PGD ,
+
KERNEL PGD PTRS ) ;
+#e n d i f
c l o n e p g d r a n g e ( ( p g d t ∗ ) pgd + USER PTRS PER PGD ,
s w a p p e r p g d i r + USER PTRS PER PGD ,
KERNEL PGD PTRS ) ;
@@ − 3 0 0 , 1 2 + 3 1 2 , 2 1 @@
pmd t ∗pmd ;
i f ( i d x >= USER PTRS PER PGD ) {
+#i f CONFIG SUPER PAGE
+ pmd = ( pmd t ∗ ) g e t f r e e p a g e s (GFP KERNEL, 1 ) ;
+#e l s e
pmd = ( pmd t ∗ ) g e t f r e e p a g e (GFP KERNEL ) ;
−
+#e n d i f
i f ( pmd)
memcpy (pmd ,
( void ∗ ) p g d p a g e v a d d r ( s w a p p e r p g d i r [ i d x ] ) ,
s i z e o f ( pmd t ) ∗ PTRS PER PMD ) ;
+#i f CONFIG SUPER PAGE
+ i f ( pmd)
+
memcpy (pmd + PTRS PER PMD,
+
( void ∗ ) p g d p a g e v a d d r ( s w a p p e r p g d i r [ i d x ] ) ,
+
s i z e o f ( pmd t ) ∗ PTRS PER PMD ) ;
+#e n d i f
} else
pmd = k m e m c a c h e a l l o c ( pmd cache , GFP KERNEL ) ;
@@ − 3 1 5 , 7 + 3 3 6 , 1 1 @@
s t a t i c void p m d c a c h e f r e e ( pmd t ∗ pmd , i n t i d x )
{
i f ( i d x >= USER PTRS PER PGD)
+#i f CONFIG SUPER PAGE
+ f r e e p a g e s ( ( unsigned long )pmd , 1 ) ;
+#e l s e
f r e e p a g e ( ( unsigned long )pmd ) ;
+#e n d i f
else
k m e m c a c h e f r e e ( pmd cache , pmd ) ;
}
@@ − 3 2 3 , 7 + 3 4 8 , 1 7 @@
p g d t ∗ p g d a l l o c ( struct mm struct ∗mm)
{
int i ;
+#i f CONFIG SUPER PAGE
+#i f d e f CONFIG X86 PAE
p g d t ∗ pgd = q u i c k l i s t a l l o c ( 0 , GFP KERNEL, p g d c t o r ) ;
+#e l s e
+ p g d t ∗ pgd = ( p g d t ∗ ) g e t f r e e p a g e s (GFP KERNEL, 1 ) ;
+ i f ( pgd )
+ p g d c t o r ( pgd ) ;
+#e n d i f
+#e l s e
+ p g d t ∗ pgd = q u i c k l i s t a l l o c ( 0 , GFP KERNEL, p g d c t o r ) ;
52
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
+#e n d i f
i f ( PTRS PER PMD = = 1 | | ! pgd )
return pgd ;
@@ − 3 3 6 , 6 + 3 7 1 , 1 0 @@
p a r a v i r t a l l o c p d ( p a (pmd) > > PAGE SHIFT ) ;
s e t p g d (&pgd [ i ] ,
pgd (1 +
p a (pmd ) ) ) ;
+#i f CONFIG SUPER PAGE
+ p a r a v i r t a l l o c p d ( p a (pmd + (PTRS PER PMD∗ s i z e o f ( pmd t ))) > > PAGE SHIFT ) ;
+ s e t p g d r a w (&pgd [ i + PTRS PER PGD ] ,
pgd (1 +
p a (pmd + (PTRS PER PMD∗ s i z e o f ( pmd t
)))));
+#e n d i f
}
return pgd ;
@@ − 3 4 4 , 9 + 3 8 3 , 2 1 @@
p g d t pgdent = pgd [ i ] ;
void ∗ pmd = ( void ∗ ) v a ( p g d v a l ( pgdent ) − 1) ;
p a r a v i r t r e l e a s e p d ( p a (pmd) > > PAGE SHIFT ) ;
+#i f CONFIG SUPER PAGE
+ p a r a v i r t r e l e a s e p d ( p a (pmd + (PTRS PER PMD∗ s i z e o f ( pmd t ))) > > PAGE SHIFT ) ;
+#e n d i f
p m d c a c h e f r e e (pmd , i ) ;
}
+#i f CONFIG SUPER PAGE
+#i f d e f CONFIG X86 PAE
+ q u i c k l i s t f r e e ( 0 , p g d d t o r , pgd ) ;
+#e l s e
+ p g d d t o r ( pgd ) ;
+ f r e e p a g e s ( ( unsigned long ) pgd , 1 ) ;
+#e n d i f
+#e l s e
q u i c k l i s t f r e e ( 0 , p g d d t o r , pgd ) ;
+#e n d i f
return NULL;
}
@@ − 3 6 0 , 1 0 + 4 1 1 , 2 2 @@
p g d t pgdent = pgd [ i ] ;
void ∗ pmd = ( void ∗ ) v a ( p g d v a l ( pgdent ) − 1 ) ;
p a r a v i r t r e l e a s e p d ( p a (pmd) > > PAGE SHIFT ) ;
+#i f CONFIG SUPER PAGE
+
p a r a v i r t r e l e a s e p d ( p a (pmd + (PTRS PER PMD∗ s i z e o f ( pmd t ))) > > PAGE SHIFT ) ;
+#e n d i f
p m d c a c h e f r e e (pmd , i ) ;
}
/∗ i n t h e non−PAE case , f r e e p g t a b l e s ( ) c l e a r s u s e r pgd e n t r i e s ∗/
+#i f CONFIG SUPER PAGE
+#i f d e f CONFIG X86 PAE
+ q u i c k l i s t f r e e ( 0 , p g d d t o r , pgd ) ;
+#e l s e
+ p g d d t o r ( pgd ) ;
+ f r e e p a g e s ( ( unsigned long ) pgd , 1 ) ;
+#e n d i f
+#e l s e
q u i c k l i s t f r e e ( 0 , p g d d t o r , pgd ) ;
+#e n d i f
}
void c h e c k p g t c a c h e ( void )
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−g e n e r i c / p g t a b l e −nopmd . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /
i n c l u d e /asm−g e n e r i c / p g t a b l e −nopmd . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−g e n e r i c / p g t a b l e −nopmd . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−g e n e r i c / p g t a b l e −nopmd . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 3 6 , 7 + 3 6 , 1 5 @@
∗ ( pmds a r e f o l d e d i n t o puds s o t h i s doesn ’ t g e t a c t u a l l y c a l l e d ,
∗ but t h e d e f i n e i s needed f o r a g e n e r i c i n l i n e f u n c t i o n . )
∗/
53
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
+#i f CONFIG SUPER PAGE
+#d e f i n e s e t p u d r a w ( pudptr , pudval )
set pmd raw ( ( pmd t ∗ ) ( pudptr ) , ( pmd t ) { pudval } )
+#d e f i n e s e t p u d ( pudptr , pudval ) do { \
+ s e t p u d r a w ( pudptr , pudval ) \
+ s e t p u d r a w ( pudptr+PTRS PER PGD , pudval ) \
+ } while ( 0 )
+#e l s e
#d e f i n e s e t p u d ( pudptr , pudval )
set pmd ( ( pmd t ∗ ) ( pudptr ) , ( pmd t ) { pudval } )
+#e n d i f
s t a t i c i n l i n e pmd t ∗ p m d o f f s e t ( p u d t ∗ pud , u n s i g n e d l o n g a d d r e s s )
{
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−g e n e r i c / p g t a b l e −nopud . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /
i n c l u d e /asm−g e n e r i c / p g t a b l e −nopud . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−g e n e r i c / p g t a b l e −nopud . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−g e n e r i c / p g t a b l e −nopud . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 3 3 , 7 + 3 3 , 1 5 @@
∗ ( puds a r e f o l d e d i n t o pgds s o t h i s doesn ’ t g e t a c t u a l l y c a l l e d ,
∗ but t h e d e f i n e i s needed f o r a g e n e r i c i n l i n e f u n c t i o n . )
∗/
+#i f CONFIG SUPER PAGE
+#d e f i n e s e t p g d r a w ( pgdptr , p g d v a l )
s e t p u d r a w ( ( p u d t ∗ ) ( pgdptr ) , ( p u d t ) { p g d v a l } )
+#d e f i n e s e t p g d ( pgdptr , p g d v a l ) do { \
+ s e t p g d r a w ( pgdptr , p g d v a l ) ; \
+ s e t p g d r a w ( pgdptr+PTRS PER PGD , p g d v a l ) ; \
+ } while ( 0 )
+#e l s e
#d e f i n e s e t p g d ( pgdptr , p g d v a l )
s e t p u d ( ( p u d t ∗ ) ( pgdptr ) , ( p u d t ) { p g d v a l } )
+#e n d i f
s t a t i c i n l i n e p u d t ∗ p u d o f f s e t ( p g d t ∗ pgd , unsigned long a d d r e s s )
{
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / c p u f e a t u r e . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm
−i 3 8 6 / c p u f e a t u r e . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / c p u f e a t u r e . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / c p u f e a t u r e . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 1 3 2 , 7 + 1 3 2 , 1 1 @@
#d e f i n e c p u h a s f p u
b o o t c p u h a s (X86 FEATURE FPU)
#d e f i n e cpu has vme b o o t c p u h a s (X86 FEATURE VME)
#d e f i n e c p u h a s d e
b o o t c p u h a s (X86 FEATURE DE)
+#i f CONFIG SUPER PAGE
+#d e f i n e c p u h a s p s e
( b o o t c p u h a s (X86 FEATURE PSE ) | b o o t c p u h a s ( X86 FEATURE PSE36 ) )
+#e l s e
#d e f i n e c p u h a s p s e
b o o t c p u h a s (X86 FEATURE PSE)
+#e n d i f
#d e f i n e c p u h a s t s c
b o o t c p u h a s (X86 FEATURE TSC)
#d e f i n e c p u h a s p a e
b o o t c p u h a s (X86 FEATURE PAE)
#d e f i n e c p u h a s p g e
b o o t c p u h a s (X86 FEATURE PGE)
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / mmu context . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /
asm−i 3 8 6 / mmu context . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / mmu context . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / mmu context . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 5 0 , 7 + 5 0 , 1 1 @@
c p u s e t ( cpu , next−>cpu vm mask ) ;
/∗ Re−l o a d page t a b l e s ∗/
+#i f CONFIG SUPER PAGE
+ l o a d c r 3 ( next−>pgd+PTRS PER PGD ) ;
+#e l s e
l o a d c r 3 ( next−>pgd ) ;
+#e n d i f
/∗
∗ l o a d t h e LDT, i f t h e LDT i s d i f f e r e n t :
@@ −67 ,7 +71 ,11 @@
/ ∗ We were i n l a z y t l b mode and leave mm d i s a b l e d
∗ t l b f l u s h IPI d e l i v e r y . We must r e l o a d % c r 3 .
54
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
∗/
+#i f CONFIG SUPER PAGE
+
l o a d c r 3 ( next−>pgd+PTRS PER PGD ) ;
+#e l s e
l o a d c r 3 ( next−>pgd ) ;
+#e n d i f
l o a d L D T n o l o c k (&next−>c o n t e x t ) ;
}
}
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / page . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 /
page . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / page . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / page . h 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 3 4 , 8 + 3 4 , 1 4 @@
#d e f i n e c l e a r u s e r p a g e ( page , vaddr , pg ) c l e a r p a g e ( page )
#d e f i n e c o p y u s e r p a g e ( to , from , vaddr , pg ) c o p y p a g e ( to , from )
+#i f CONFIG SUPER PAGE
+#d e f i n e
a l l o c z e r o e d u s e r h i g h p a g e ( m o v a b l e f l a g s , vma , vaddr )
a l l o c z e r o e d u s e r h i g h p a g e s ( m o v a b l e f l a g s , vma , vaddr , 0 )
+#d e f i n e
a l l o c z e r o e d u s e r h i g h p a g e s ( m o v a b l e f l a g s , vma , vaddr , o r d e r ) \
+ a l l o c p a g e s v m a (GFP HIGHUSER |
GFP ZERO | m o v a b l e f l a g s , vma , vaddr , o r d e r )
+#e l s e
#d e f i n e
a l l o c z e r o e d u s e r h i g h p a g e ( m o v a b l e f l a g s , vma , vaddr ) \
a l l o c p a g e v m a (GFP HIGHUSER |
GFP ZERO | m o v a b l e f l a g s , vma , vaddr )
+#e n d i f
#d e f i n e HAVE ARCH ALLOC ZEROED USER HIGHPAGE
/∗
d i f f −urN l i n u x −2.6.23/ i n c l u d e /asm−i 3 8 6 / p g a l l o c . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−
i386 / p g a l l o c . h
−−− l i n u x −2.6.23/ i n c l u d e /asm−i 3 8 6 / p g a l l o c . h 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / p g a l l o c . h
2008 −01 −21 18:43:15.000000000 +0900
@@ −3 ,6 +3 ,7 @@
#i n c l u d e < l i n u x / t h r e a d s . h>
#i n c l u d e < l i n u x /mm. h> / ∗ f o r s t r u c t page ∗/
+#i n c l u d e <asm/ p g t a b l e . h>
#i f d e f CONFIG PARAVIRT
#i n c l u d e <asm/ p a r a v i r t . h>
@@ − 2 9 , 6 + 3 0 , 3 2 @@
( unsigned long long ) PAGE SHIFT ) ) ) ; \
} while ( 0 )
+
+#i f CONFIG SUPER PAGE
+s t a t i c i n l i n e void s u p e r p a g e p o p u l a t e ( struct mm struct ∗mm, unsigned long a d d r e s s ,
+
struct page ∗ page , p g p r o t t p r o t , i n t s p i n d e x ) {
+ p g d t ∗ pgd ;
+ p u d t ∗ pud ;
+ pmd t ∗pmd ;
+
+ union {
+
pmd t e n t r y ;
+
pte t pte entry ;
+ } x;
+ pgd = p g d o f f s e t (mm, a d d r e s s ) ;
+ pud = p u d o f f s e t ( pgd , a d d r e s s ) ;
+ pmd = p m d o f f s e t ( pud , a d d r e s s ) ;
+ x . p t e e n t r y = mk pte ( page ,
p g p r o t ( p g p r o t v a l ( p r o t ) | PAGE PSE ) ) ;
+ x . pte entry = pte mkwrite ( pte mkdirty ( x . pte entry ) ) ;
+#i f d e f CONFIG X86 PAE
+ set pmd raw (pmd + PTRS PER PMD ,
pmd ( pmd val ( x . e n t r y ) ) ) ;
+#e l s e
+ set pmd raw (pmd + PTRS PER PGD ,
pmd ( pmd val ( x . e n t r y ) ) ) ;
+#e n d i f
+}
+#e n d i f
55
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
+
+
/∗
∗ A l l o c a t e and f r e e page t a b l e s .
∗/
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / p g t a b l e −2 l e v e l . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e
/asm−i 3 8 6 / p g t a b l e −2 l e v e l . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / p g t a b l e −2 l e v e l . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / p g t a b l e −2 l e v e l . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 2 7 , 8 + 2 7 , 1 6 @@
#i f n d e f CONFIG PARAVIRT
#d e f i n e s e t p t e ( p t e p t r , p t e v a l )
n a t i v e s e t p t e ( pteptr , pteval )
#d e f i n e s e t p t e a t (mm, addr , ptep , p t e v a l ) n a t i v e s e t p t e a t (mm, addr , ptep , p t e v a l )
+#i f CONFIG SUPER PAGE
+#d e f i n e set pmd raw ( pmdptr , pmdval )
n a t i v e s e t p m d ( pmdptr , pmdval )
+#d e f i n e set pmd ( pmdptr , pmdval ) do{\
+ set pmd raw ( pmdptr , pmdval ) ; \
+ set pmd raw ( pmdptr + PTRS PER PGD , pmdval ) ; \
+ } while ( 0 )
+#e l s e
#d e f i n e set pmd ( pmdptr , pmdval )
n a t i v e s e t p m d ( pmdptr , pmdval )
#e n d i f
+#e n d i f
#d e f i n e s e t p t e a t o m i c ( p t e p t r , p t e v a l ) s e t p t e ( p t e p t r , p t e v a l )
#d e f i n e s e t p t e p r e s e n t (mm, addr , ptep , p t e v a l ) s e t p t e a t (mm, addr , ptep , p t e v a l )
@@ − 5 1 , 7 + 5 9 , 1 3 @@
#e n d i f
#d e f i n e p t e p a g e ( x )
pfn to page ( pte pfn (x ))
+
+#i f CONFIG SUPER PAGE
+#d e f i n e p t e n o n e ( x )
( ! ( ( x ) . p t e l o w&˜SUPER PAGE MASK) )
+#e l s e
#d e f i n e p t e n o n e ( x )
( ! ( x ) . pte low )
+#e n d i f
+
#d e f i n e p t e p f n ( x ) ( p t e v a l ( x) > > PAGE SHIFT)
#d e f i n e p f n p t e ( pfn , p r o t )
p t e ( ( ( p f n ) < < PAGE SHIFT ) | p g p r o t v a l ( p r o t ) )
#d e f i n e pfn pmd ( pfn , p r o t )
pmd ( ( ( p f n ) < < PAGE SHIFT ) | p g p r o t v a l ( p r o t ) )
@@ − 7 8 , 8 + 9 2 , 1 3 @@
/∗ Encode and de−code a swap e n t r y ∗/
#d e f i n e
swp type (x)
( ( ( x ) . v a l > > 1) & 0 x 1 f )
+#i f CONFIG SUPER PAGE
+#d e f i n e
swp offset (x )
( ( x ) . v a l > > 10)
+#d e f i n e
s w p e n t r y ( type , o f f s e t ) ( ( s w p e n t r y t ) { ( ( t y p e ) < < 1 ) | ( ( o f f s e t ) < < 1 0 ) } )
+#e l s e
#d e f i n e
swp offset (x)
( ( x ) . v a l > > 8)
#d e f i n e
s w p e n t r y ( type , o f f s e t ) ( ( s w p e n t r y t ) { ( ( t y p e ) < < 1 ) | ( ( o f f s e t ) < < 8 ) } )
+#e n d i f
#d e f i n e
p t e t o s w p e n t r y ( pte )
( ( swp entry t ) { ( pte ) . pte low } )
#d e f i n e
swp entry to pte (x)
(( pte t ) { ( x ) . val })
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / p g t a b l e −3 l e v e l . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e
/asm−i 3 8 6 / p g t a b l e −3 l e v e l . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / p g t a b l e −3 l e v e l . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / p g t a b l e −3 l e v e l . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 9 9 , 1 0 + 9 9 , 2 8 @@
#d e f i n e s e t p t e a t (mm, addr , ptep , p t e )
n a t i v e s e t p t e a t (mm, addr , ptep , p t e )
#d e f i n e s e t p t e p r e s e n t (mm, addr , ptep , p t e ) n a t i v e s e t p t e p r e s e n t (mm, addr , ptep , p t e )
#d e f i n e s e t p t e a t o m i c ( ptep , p t e )
n a t i v e s e t p t e a t o m i c ( ptep , p t e )
−#d e f i n e set pmd (pmdp , pmd)
n a t i v e s e t p m d (pmdp , pmd)
−#d e f i n e s e t p u d ( pudp , pud )
n a t i v e s e t p u d ( pudp , pud )
#d e f i n e p t e c l e a r (mm, addr , ptep )
n a t i v e p t e c l e a r (mm, addr , ptep )
+#i f CONFIG SUPER PAGE
+#d e f i n e p m d c l e a r r a w (pmd)
n a t i v e p m d c l e a r (pmd)
+#d e f i n e set pmd raw (pmdp , pmd)
n a t i v e s e t p m d (pmdp , pmd)
56
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
+#d e f i n e set pmd (pmdp , pmd) do{\
+ set pmd raw (pmdp , pmd ) ; \
+ set pmd raw (pmdp + PTRS PER PMD , pmd ) ; \
+ } while ( 0 )
+#d e f i n e p m d c l e a r (pmd) do{\
+ p m d c l e a r r a w (pmd ) ; \
+ p m d c l e a r r a w (pmd + PTRS PER PMD ) ; \
+ } while ( 0 )
+#d e f i n e s e t p u d r a w ( pudp , pud )
n a t i v e s e t p u d ( pudp , pud )
+#d e f i n e s e t p u d ( pudp , pud ) do{\
+ s e t p u d r a w ( pudp , pud ) \
+ s e t p u d r a w ( pudp + PTRS PER PUD , pud ) \
+ } while ( 0 )
+#e l s e
#d e f i n e p m d c l e a r (pmd)
n a t i v e p m d c l e a r (pmd)
+#d e f i n e set pmd (pmdp , pmd)
n a t i v e s e t p m d (pmdp , pmd)
+#d e f i n e s e t p u d ( pudp , pud )
n a t i v e s e t p u d ( pudp , pud )
+#e n d i f
#e n d i f
/∗
@@ −148 ,10 +166 ,17 @@
#d e f i n e p t e p a g e ( x ) p f n t o p a g e ( p t e p f n ( x ) )
+#i f CONFIG SUPER PAGE
+s t a t i c i n l i n e i n t p t e n o n e ( p t e t p t e )
+{
+ r e t u r n ! ( p t e . p t e l o w &˜SUPER PAGE MAKE) && ! p t e . p t e h i g h ;
+{
+#e l s e
s t a t i c i n l i n e i n t pte none ( p t e t pte )
{
r e t u r n ! p t e . p t e l o w && ! p t e . p t e h i g h ;
}
+#e n d i f
s t a t i c i n l i n e unsigned long p t e p f n ( p t e t pte )
{
d i f f −urN l i n u x −2.6.23/ i n c l u d e /asm−i 3 8 6 / p g t a b l e . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−
i386 / p g t a b l e . h
−−− l i n u x −2.6.23/ i n c l u d e /asm−i 3 8 6 / p g t a b l e . h 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / p g t a b l e . h
2008 −01 −21 18:43:15.000000000 +0900
@@ −35 ,6 +35 ,9 @@
#d e f i n e ZERO PAGE( vaddr ) ( v i r t t o p a g e ( e m p t y z e r o p a g e ) )
extern unsigned long empty zero page [ 1 0 2 4 ] ;
extern pgd t swapper pg dir [1024];
+#i f CONFIG SUPER PAGE
+e x t e r n p g d t s w a p p e r t l b d i r [ 1 0 2 4 ] ;
+#e n d i f
e x t e r n s t r u c t kmem cache ∗ pmd cache ;
extern s p i n l o c k t pgd lock ;
e x t e r n s t r u c t page ∗ p g d l i s t ;
@@ −115 ,7 +118 ,16 @@
#d e f i n e PAGE DIRTY 0 x040
#d e f i n e PAGE PSE 0 x080 / ∗ 4 MB ( or 2MB) page , Pentium + , i f p r e s e n t . . ∗/
#d e f i n e PAGE GLOBAL 0 x100 /∗ G l o b a l TLB e n t r y PPro+ ∗/
+
+#i f CONFIG SUPER PAGE
+#d e f i n e PAGE SUPER 0 x200
/∗ SuperPage c a n d i d a t e d page ∗/
+#d e f i n e SUPER PAGE MASK PAGE SUPER
+#d e f i n e SUPER PAGE MASK SHIFT 9
+#d e f i n e SUPER PAGE NR 2
+#e l s e
#d e f i n e PAGE UNUSED1 0 x200 /∗ a v a i l a b l e f o r programmer ∗/
+#e n d i f
+
#d e f i n e PAGE UNUSED2 0 x400
#d e f i n e PAGE UNUSED3 0 x800
57
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
@@ − 2 6 0 , 6 + 2 7 2 , 2 8 @@
#d e f i n e p t e u p d a t e d e f e r (mm, addr , ptep ) do { } while ( 0 )
#e n d i f
+#i f CONFIG SUPER PAGE
+extern p g p r o t t s u p e r p a g e p r o t [ ] ;
+extern i n t s u p e r p a g e o r d e r [ ] ;
+#d e f i n e p t e t o s p i n d e x ( x ) ( ( ( x ) . p t e l o w & SUPER PAGE MASK) > > SUPER PAGE MASK SHIFT)
+s t a t i c i n l i n e p t e t m k p t e s p c l e a n ( p t e t p t e )
+ { ( p t e ) . p t e l o w &= ˜SUPER PAGE MASK ; return p t e ; }
+void d o w n p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x ) ;
+void c l e a r p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x ) ;
+#d e f i n e s e t p t e r a w ( p t e p t r , p t e v a l ) s e t p t e ( p t e p t r , p t e v a l )
+#i f d e f CONFIG X86 PAE
+#d e f i n e SIZEOF PTE LOG2 3
+s t a t i c i n l i n e void c l e a r p m d s p ( pmd t ∗pmd ) {
+ set pmd raw ( ( pmd+PTRS PER PMD ) , ∗ pmd ) ;
+}
+#e l s e
+#d e f i n e SIZEOF PTE LOG2 2
+s t a t i c i n l i n e void c l e a r p m d s p ( pmd t ∗pmd ) {
+ set pmd raw ( ( pmd+PTRS PER PGD ) , ∗ pmd ) ;
+}
+#e n d i f
+#e n d i f
+
/∗ l o c a l p t e u p d a t e s need not use x c h g f o r l o c k i n g ∗/
s t a t i c i n l i n e p t e t n a t i v e l o c a l p t e p g e t a n d c l e a r ( p t e t ∗ ptep )
{
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / t l b f l u s h . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−
i386 / t l b f l u s h . h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e /asm−i 3 8 6 / t l b f l u s h . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e /asm−i 3 8 6 / t l b f l u s h . h
2008 −01 −21 18:43:15.000000000 +0900
@@ − 5 7 , 6 + 5 7 , 9 @@
#d e f i n e c p u h a s i n v l p g ( b o o t c p u d a t a . x86 > 3 )
+#i f d e f CONFIG X86 K7 INVLPG BUG
+#d e f i n e
f l u s h t l b o n e ( addr )
f l u s h t l b ()
+#e l s e
#i f d e f CONFIG X86 INVLPG
# define
f l u s h t l b o n e ( addr )
f l u s h t l b s i n g l e ( addr )
#e l s e
@@ − 6 8 , 6 + 7 1 , 7 @@
flush tlb ();
\
} while ( 0 )
#e n d i f
+#e n d i f
/∗
∗ TLB f l u s h i n g :
d i f f −urN l i n u x −2.6.23/ i n c l u d e / l i n u x / g f p . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x / g f p . h
−−− l i n u x −2.6.23/ i n c l u d e / l i n u x / g f p . h 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x / g f p . h 2008 −01 −21 18:43:15.000000000 +0900
@@ −155 ,6 +155 ,28 @@
NODE DATA( n i d)−> n o d e z o n e l i s t s + g f p z o n e ( g f p m a s k ) ) ;
}
+#i f CONFIG SUPER PAGE
+#i f d e f CONFIG NUMA
+e x t e r n s t r u c t page ∗ a l l o c p a g e s c u r r e n t ( g f p t gfp mask , u n s i g n e d o r d e r ) ;
+
+s t a t i c i n l i n e s t r u c t page ∗
+a l l o c p a g e s ( g f p t gfp mask , u n s i g n e d i n t o r d e r )
+{
+ i f ( u n l i k e l y ( o r d e r >= MAX ORDER) )
+ r e t u r n NULL;
+
58
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
+ r e t u r n a l l o c p a g e s c u r r e n t ( gfp mask , o r d e r ) ;
+}
+e x t e r n s t r u c t page ∗ a l l o c p a g e v m a ( g f p t gfp mask ,
+
s t r u c t v m a r e a s t r u c t ∗ vma , u n s i g n e d l o n g addr ) ;
+#e l s e
+#d e f i n e a l l o c p a g e s ( gfp mask , o r d e r ) \
+ a l l o c p a g e s n o d e ( numa node id ( ) , gfp mask , o r d e r )
+#d e f i n e a l l o c p a g e s v m a ( gfp mask , vma , addr , o r d e r ) a l l o c p a g e s ( gfp mask , o r d e r )
+#d e f i n e a l l o c p a g e v m a ( gfp mask , vma , addr ) a l l o c p a g e s v m a ( gfp mask , vma , addr , 0 )
+#e n d i f
+
+#e l s e
#i f d e f CONFIG NUMA
e x t e r n s t r u c t page ∗ a l l o c p a g e s c u r r e n t ( g f p t gfp mask , u n s i g n e d o r d e r ) ;
@@ −173 ,6 +195 ,7 @@
a l l o c p a g e s n o d e ( numa node id ( ) , gfp mask , o r d e r )
#d e f i n e a l l o c p a g e v m a ( gfp mask , vma , addr ) a l l o c p a g e s ( gfp mask , 0 )
#e n d i f
+#e n d i f
#d e f i n e a l l o c p a g e ( g f p m a s k ) a l l o c p a g e s ( gfp mask , 0 )
e x t e r n u n s i g n e d l o n g FASTCALL( g e t f r e e p a g e s ( g f p t gfp mask , u n s i g n e d i n t o r d e r ) ) ;
d i f f −urN l i n u x −2.6.23/ i n c l u d e / l i n u x /highmem . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x /
highmem . h
−−− l i n u x −2.6.23/ i n c l u d e / l i n u x /highmem . h 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x /highmem . h 2008 −01 −21 18:43:15.000000000 +0900
@@ −72 ,6 +72 ,67 @@
smp wmb ( ) ;
}
+#i f CONFIG SUPER PAGE
+#i f n d e f HAVE ARCH ALLOC ZEROED USER HIGHPAGE
+/∗∗
+ ∗
a l l o c z e r o e d u s e r h i g h p a g e − A l l o c a t e a z e r o e d HIGHMEM page f o r a VMA w i t h c a l l e r −
s p e c i f i e d movable GFP f l a g s
+ ∗ @ m o v a b l e f l a g s : The GFP f l a g s r e l a t e d t o t h e p a g e s f u t u r e a b i l i t y t o move l i k e
GFP MOVABLE
+ ∗ @vma : The VMA t h e page i s t o be a l l o c a t e d f o r
+ ∗ @vaddr : The v i r t u a l a d d r e s s t h e page w i l l be i n s e r t e d i n t o
+ ∗
+ ∗ This f u n c t i o n w i l l a l l o c a t e a page f o r a VMA b u t t h e c a l l e r i s e x p e c t e d
+ ∗ t o s p e c i f y v i a m o v a b l e f l a g s w h e t h e r t h e page w i l l be movable i n t h e
+ ∗ f u t u r e or not
+ ∗
+ ∗ An a r c h i t e c t u r e may o v e r r i d e t h i s f u n c t i o n by d e f i n i n g
+ ∗ HAVE ARCH ALLOC ZEROED USER HIGHPAGE and p r o v i d i n g t h e i r own
+ ∗ implementation .
+ ∗/
+s t a t i c i n l i n e struct page ∗
+ a l l o c z e r o e d u s e r h i g h p a g e s ( g f p t movableflags ,
+
struct v m a r e a s t r u c t ∗ vma ,
+
unsigned long vaddr ,
+
unsigned i n t o r d e r )
+{
+ unsigned long spaddr ;
+ struct page ∗ page = a l l o c p a g e s v m a (GFP HIGHUSER | m o v a b l e f l a g s ,
+
vma , vaddr , o r d e r ) ;
+
+ i f ( page )
+
spaddr = vaddr & ˜ ( ( PAGE SIZE << o r d e r ) − 1 ) ;
+
f o r ( i = 0 ; i < 1 < < o r d e r ; i ++) {
+
c l e a r u s e r h i g h p a g e ( page+i , spaddr ) ;
+
spaddr += PAGE SIZE ;
+
}
+
+ return page ;
+}
+#d e f i n e
a l l o c z e r o e d u s e r h i g h p a g e ( m o v a b l e f l a g s , vmaptr , vaddr )
a l l o c z e r o e d u s e r h i g h p a g e s ( m o v a b l e f l a g s , vmaptr , vaddr , 0 )
59
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
+#e n d i f
+
+/∗ ∗
+ ∗ a l l o c z e r o e d u s e r h i g h p a g e m o v a b l e − A l l o c a t e a z e r o e d HIGHMEM page f o r a VMA t h a t
t h e c a l l e r knows can move
+ ∗ @vma : The VMA t h e page i s t o be a l l o c a t e d f o r
+ ∗ @vaddr : The v i r t u a l a d d r e s s t h e page w i l l be i n s e r t e d i n t o
+ ∗
+ ∗ This f u n c t i o n w i l l a l l o c a t e a page f o r a VMA t h a t t h e c a l l e r knows w i l l
+ ∗ be a b l e t o m i g r a t e i n t h e f u t u r e u s i n g move pages ( ) or r e c l a i m e d
+ ∗/
+s t a t i c i n l i n e struct page ∗
+a l l o c z e r o e d u s e r h i g h p a g e s m o v a b l e ( struct v m a r e a s t r u c t ∗ vma ,
+
unsigned long vaddr , unsigned i n t o r d e r )
+{
+ return
a l l o c z e r o e d u s e r h i g h p a g e s ( GFP MOVABLE , vma , vaddr , o r d e r ) ;
+}
+
+s t a t i c i n l i n e void c l e a r h i g h p a g e ( struct page ∗ page )
+{
+ void ∗ kaddr = kmap atomic ( page , KM USER0 ) ;
+ c l e a r p a g e ( kaddr ) ;
+ kunmap atomic ( kaddr , KM USER0 ) ;
+}
+#d e f i n e a l l o c z e r o e d u s e r h i g h p a g e m o v a b l e ( vmaptr , vaddr )
a l l o c z e r o e d u s e r h i g h p a g e s m o v a b l e ( vmaptr , vaddr , 0 )
+#e l s e
#i f n d e f HAVE ARCH ALLOC ZEROED USER HIGHPAGE
/∗ ∗
∗
a l l o c z e r o e d u s e r h i g h p a g e − A l l o c a t e a z e r o e d HIGHMEM page f o r a VMA w i t h c a l l e r −
s p e c i f i e d movable GFP f l a g s
@@ −123 ,6 +184 ,7 @@
c l e a r p a g e ( kaddr ) ;
kunmap atomic ( kaddr , KM USER0 ) ;
}
+#e n d i f
/∗
∗ Same b u t a l s o f l u s h e s a l i a s e d c a c h e c o n t e n t s t o RAM.
d i f f −urN l i n u x −2.6.23/ i n c l u d e / l i n u x /mm. h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x /mm. h
−−− l i n u x −2.6.23/ i n c l u d e / l i n u x /mm. h 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x /mm. h 2008 −01 −21 18:43:15.000000000 +0900
@@ −170 ,6 +170 ,7 @@
#d e f i n e VM ALWAYSDUMP 0 x04000000 / ∗ Always i n c l u d e i n c o r e dumps ∗/
#d e f i n e VM CAN NONLINEAR 0 x08000000 /∗ Has −> f a u l t & d o e s n o n l i n e a r p a g e s ∗/
+#d e f i n e VM SUPERPAGE 0 x10000000 /∗ Super Page VM ∗/
#i f n d e f VM STACK DEFAULT FLAGS /∗ a r c h can o v e r r i d e t h i s ∗/
#d e f i n e VM STACK DEFAULT FLAGS VM DATA DEFAULT FLAGS
@@ − 1 2 1 8 , 5 + 1 2 1 9 , 1 8 @@
const char ∗ arch vma name ( struct v m a r e a s t r u c t ∗ vma ) ;
+#i f CONFIG SUPER PAGE
+extern i n t s u p e r p a g e o n ;
+extern i n t s u p e r p a g e n r ;
+extern unsigned long s u p e r p a g e r e s e r v e [ ] ;
+extern unsigned long s u p e r p a g e a l l o c a t e [ ] ;
+extern unsigned long s u p e r p a g e d o w n g r a d e [ ] ;
+void s u p e r p a g e i n i t ( void ) ;
+i n t m a k e p t e s p r e s e n t ( unsigned long addr , unsigned long end ) ;
+void
b r e a k a r e a ( struct page ∗ page , unsigned long o r d e r ) ;
+void a d j s p r a n g e ( struct mm struct ∗mm, i n t zap , unsigned long a d d r e s s , unsigned long end
);
+#d e f i n e b r e a k a r e a ( page , o r d e r )
b r e a k a r e a ( page , o r d e r )
+#e n d i f
+
#e n d i f /∗
KERNEL
∗/
#e n d i f /∗ LINUX MM H ∗/
60
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
d i f f −urN l i n u x − 2 . 6 . 2 3 / i n c l u d e / l i n u x / s y s c t l . h l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x /
sysctl .h
−−− l i n u x − 2 . 6 . 2 3 / i n c l u d e / l i n u x / s y s c t l . h 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / i n c l u d e / l i n u x / s y s c t l . h 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 7 4 , 7 + 7 4 , 1 1 @@
CTL S390DBF=5677 , /∗ s390 debug ∗/
CTL SUNRPC=7249 , /∗ s u n r p c debug ∗/
CTL PM=9899 , /∗ f r v power management ∗/
− CTL FRV=9898 , /∗ f r v s p e c i f i c s y s c t l s ∗/
+ CTL FRV=9898 /∗ f r v s p e c i f i c s y s c t l s ∗/
+#i f CONFIG SUPER PAGE
+ ,
+
CTL SUPER PAGE=11 /∗ SuperPage ∗/
+#e n d i f
};
/∗ CTL BUS names : ∗/
d i f f −urN l i n u x − 2 . 6 . 2 3 / k e r n e l / s y s c t l . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / k e r n e l / s y s c t l . c
−−− l i n u x − 2 . 6 . 2 3 / k e r n e l / s y s c t l . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 / k e r n e l / s y s c t l . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 1 6 0 , 6 + 1 6 0 , 1 1 @@
int s y s c t l l e g a c y v a l a y o u t ;
#e n d i f
+#i f CONFIG SUPER PAGE
+void s u p e r p a g e i n i t ( void ) ;
+void a l l o c p a g e s i n i t ( void ) ;
+#e n d i f
+
extern i n t p r o v e l o c k i n g ;
extern i n t l o c k s t a t ;
@@ − 1 4 8 1 , 6 + 1 4 8 6 , 1 0 @@
static
i n i t i n t s y s c t l i n i t ( void )
{
s y s c t l s e t p a r e n t (NULL, r o o t t a b l e ) ;
+#i f CONFIG SUPER PAGE
+ super page init ();
+ alloc pages init ();
+#e n d i f
return 0 ;
}
d i f f −urN l i n u x − 2 . 6 . 2 3 /mm/ M a k e f i l e l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ M a k e f i l e
−−− l i n u x − 2 . 6 . 2 3 /mm/ M a k e f i l e 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ M a k e f i l e 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 2 9 , 4 + 2 9 , 5 @@
obj−$ (CONFIG MIGRATION) += m i g r a t e . o
obj−$ (CONFIG SMP) += a l l o c p e r c p u . o
obj−$ (CONFIG QUICKLIST) += q u i c k l i s t . o
+obj−$ (CONFIG SUPER PAGE) += s u p e r p a g e . o
d i f f −urN l i n u x − 2 . 6 . 2 3 /mm/memory . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/memory . c
−−− l i n u x − 2 . 6 . 2 3 /mm/memory . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/memory . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 5 0 , 6 + 5 0 , 2 7 @@
#i n c l u d e < l i n u x / d e l a y a c c t . h>
#i n c l u d e < l i n u x / i n i t . h>
#i n c l u d e < l i n u x / w r i t e b a c k . h>
+#i n c l u d e < l i n u x / mempolicy . h>
+#i n c l u d e < l i n u x / f s . h>
+#i n c l u d e < l i n u x / t y p e s . h>
+
+#i f CONFIG SUPER PAGE
+#i n c l u d e < l i n u x / k e r n e l . h>
+#i n c l u d e < l i n u x / s c h e d . h>
+#i n c l u d e < l i n u x / nodemask . h>
+#i n c l u d e < l i n u x / c p u s e t . h>
+#i n c l u d e < l i n u x / g f p . h>
+#i n c l u d e < l i n u x / s l a b . h>
61
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
+#i n c l u d e
+#i n c l u d e
+#i n c l u d e
+#i n c l u d e
+#i n c l u d e
+#i n c l u d e
+#i n c l u d e
+
+#i n c l u d e
+#e n d i f
< l i n u x / s t r i n g . h>
< l i n u x / i n t e r r u p t . h>
< l i n u x / compat . h>
< l i n u x / s e q f i l e . h>
< l i n u x / p r o c f s . h>
< l i n u x / m i g r a t e . h>
< l i n u x / s e c u r i t y . h>
<asm/ c a c h e f l u s h . h>
#i n c l u d e <asm/ p g a l l o c . h>
#i n c l u d e <asm/ u a c c e s s . h>
@@ − 6 0 3 , 6 + 6 2 4 , 1 5 @@
i f ( i s v m h u g e t l b p a g e (vma ) )
return c o p y h u g e t l b p a g e r a n g e ( dst mm , src mm , vma ) ;
+#i f CONFIG SUPER PAGE
+ i f ( ( ( vma−>v m f l a g s & (VM SHARED | VM MAYWRITE)) == VM MAYWRITE) && (vma−>v m f l a g s &
VM SUPERPAGE) ) {
+
s p i n l o c k (&src mm−>p a g e t a b l e l o c k ) ;
+
a d j s p r a n g e ( src mm , 1 , addr , end ) ;
+
s p i n u n l o c k (&src mm−>p a g e t a b l e l o c k ) ;
+ vma−>v m f l a g s &= ˜VM SUPERPAGE;
+ }
+#e n d i f
+
d s t p g d = p g d o f f s e t ( dst mm , addr ) ;
s r c p g d = p g d o f f s e t ( src mm , addr ) ;
do {
@@ − 7 6 0 , 6 + 7 9 0 , 1 3 @@
t l b s t a r t v m a ( t l b , vma ) ;
pgd = p g d o f f s e t (vma−>vm mm, addr ) ;
do {
+#i f CONFIG SUPER PAGE
+ i f ( vma−>v m f l a g s & VM SUPERPAGE) {
+
a d j s p r a n g e (vma−>vm mm, 1 , addr , end ) ;
+
i f ( ( vma−>v m s t a r t==addr ) && (vma−>vm end==end ) )
+
vma−>v m f l a g s &= ˜VM SUPERPAGE;
+ }
+#e n d i f
n e x t = p g d a d d r e n d ( addr , end ) ;
i f ( p g d n o n e o r c l e a r b a d ( pgd ) ) {
( ∗ zap work )−−;
@@ − 1 1 9 0 , 6 + 1 2 2 7 , 1 3 @@
BUG ON( addr >= end ) ;
pgd = p g d o f f s e t (mm, addr ) ;
+#i f CONFIG SUPER PAGE
+ i f ( vma−>v m f l a g s & VM SUPERPAGE) {
+
a d j s p r a n g e (mm, 1 , addr , end ) ;
+ i f ( ( vma−>v m s t a r t==addr ) & ( vma−>vm end==end ) )
+
vma−>v m f l a g s &= ˜VM SUPERPAGE;
+ }
+#e n d i f
f l u s h c a c h e r a n g e (vma , addr , end ) ;
do {
n e x t = p g d a d d r e n d ( addr , end ) ;
@@ − 2 2 5 1 , 1 7 + 2 2 9 5 , 6 9 @@
struct page ∗ page ;
spinlock t ∗ ptl ;
pte t entry ;
+#i f CONFIG SUPER PAGE
+ int i , order ;
+ unsigned long spaddr ;
+ p t e t oldpte , ∗ wktable ;
+#e n d i f
if ( write access ) {
+#i f CONFIG SUPER PAGE
62
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
+r e t r y :
+
oldpte = ∗ page table ;
+
order = super page order [ pte to sp index ( oldpte ) ] ;
+
wktable =
+
( p t e t ∗ ) ( ( unsigned long ) p a g e t a b l e &
+
˜ ( ( 1UL < < ( o r d e r + SIZEOF PTE LOG2 ) ) − 1 ) ) ;
+
f o r ( i = 0 ; i < 1 < < o r d e r ; i ++) {
+
i f ( ! p t e n o n e ( ∗ ( w k t a b l e+i ) ) ) {
+
down pte sp ( page table , p t e t o s p i n d e x ( oldpte ) ) ;
+
goto r e t r y ;
+
}
+
}
+#e n d i f
/∗ A l l o c a t e our own p r i v a t e page . ∗/
pte unmap ( p a g e t a b l e ) ;
i f ( u n l i k e l y ( a n o n v m a p r e p a r e (vma ) ) )
goto oom ;
+
+#i f CONFIG SUPER PAGE
+ page = a l l o c z e r o e d u s e r h i g h p a g e s m o v a b l e (vma , a d d r e s s , o r d e r ) ;
+
i f ( ! page ) {
+
i f ( order ) {
+
s u p e r p a g e d o w n g r a d e [ p t e t o s p i n d e x ( o l d p t e )]++;
+
down pte sp ( page table , p t e t o s p i n d e x ( oldpte ) ) ;
+
goto r e t r y ;
+
}
+
else {
+
goto oom ;
+
}
+ }
+
i f ( order ) {
+
b r e a k a r e a ( page , o r d e r ) ;
+
s u p e r p a g e a l l o c a t e [ p t e t o s p i n d e x ( o l d p t e )]++;
+
p a g e t a b l e = p t e o f f s e t m a p l o c k (mm, pmd , a d d r e s s , & p t l ) ;
+
vma−>v m f l a g s | = VM SUPERPAGE;
+
spaddr = a d d r e s s & ˜ ( ( PAGE SIZE << o r d e r ) − 1 ) ;
+
s u p e r p a g e p o p u l a t e (mm, spaddr , page , vma−>vm page prot ,
+
pte to sp index ( oldpte ) ) ;
+
f o r ( i = 0 ; i < 1 < < o r d e r ; i ++) {
+
entry = pte mkwrite ( pte mkdirty (
+
mk pte ( page+i ,
p g p r o t ( p g p r o t v a l (vma−>v m p a g e p r o t ) | p g p r o t v a l ( s u p e r p a g e p r o t
[ pte to sp index ( oldpte ) ] ) ) ) ) ) ;
+
i n c m m c o u n t e r (mm, a n o n r s s ) ;
+
l r u c a c h e a d d a c t i v e ( page+i ) ;
+
page add new anon rmap ( page+i , vma , spaddr ) ;
+
s e t p t e a t (mm, spaddr , w k t a b l e+i , e n t r y ) ;
+
spaddr += PAGE SIZE ;
+
}
+
} else {
+#e l s e
page = a l l o c z e r o e d u s e r h i g h p a g e m o v a b l e (vma , a d d r e s s ) ;
i f ( ! page )
goto oom ;
+#e n d i f
e n t r y = mk pte ( page , vma−>v m p a g e p r o t ) ;
e n t r y = maybe mkwrite ( p t e m k d i r t y ( e n t r y ) , vma ) ;
@@ − 2 2 7 1 , 6 + 2 3 6 7 , 9 @@
i n c m m c o u n t e r (mm, a n o n r s s ) ;
l r u c a c h e a d d a c t i v e ( page ) ;
page add new anon rmap ( page , vma , a d d r e s s ) ;
+#i f CONFIG SUPER PAGE
+ s e t p t e a t (mm, a d d r e s s , p a g e t a b l e , e n t r y ) ;
+ }
} else {
/∗ Map t h e ZERO PAGE − v m p a g e p r o t i s r e a d o n l y ∗/
page = ZERO PAGE( a d d r e s s ) ;
@@ − 2 2 8 3 , 9 + 2 3 8 2 , 2 4 @@
63
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
+
goto r e l e a s e ;
i n c m m c o u n t e r (mm, f i l e r s s ) ;
p a g e a d d f i l e r m a p ( page ) ;
s e t p t e a t (mm, a d d r e s s , p a g e t a b l e , e n t r y ) ;
}
+#e l s e
+ } else {
+ /∗ Map t h e ZERO PAGE − v m p a g e p r o t i s r e a d o n l y ∗/
+ page = ZERO PAGE( a d d r e s s ) ;
+ p a g e c a c h e g e t ( page ) ;
+ e n t r y = mk pte ( page , vma−>v m p a g e p r o t ) ;
+ p t l = p t e l o c k p t r (mm, pmd ) ;
+ spin lock ( ptl );
+ i f ( ! pte none (∗ page table ) )
+
goto r e l e a s e ;
+ i n c m m c o u n t e r (mm, f i l e r s s ) ;
+ p a g e a d d f i l e r m a p ( page ) ;
+ }
s e t p t e a t (mm, a d d r e s s , p a g e t a b l e , e n t r y ) ;
+#e n d i f
/∗ No need t o i n v a l i d a t e − i t was non−p r e s e n t b e f o r e ∗/
update mmu cache (vma , a d d r e s s , e n t r y ) ;
d i f f −urN l i n u x − 2 . 6 . 2 3 /mm/ mempolicy . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ mempolicy . c
−−− l i n u x − 2 . 6 . 2 3 /mm/ mempolicy . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ mempolicy . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 1 3 0 2 , 6 + 1 3 0 2 , 3 7 @@
∗
∗ Should be c a l l e d with t h e mm sem o f t h e vma h o l d .
∗/
+#i f CONFIG SUPER PAGE
+struct page ∗
+a l l o c p a g e s v m a ( g f p t gfp , struct v m a r e a s t r u c t ∗ vma , unsigned long addr , unsigned i n t
order )
+{
+ struct mempolicy ∗ p o l = g e t v m a p o l i c y ( c u r r e n t , vma , addr ) ;
+ struct z o n e l i s t ∗ z l ;
+
+ cpuset update task memory state ( ) ;
+
+ i f ( u n l i k e l y ( pol −>p o l i c y == MPOL INTERLEAVE) ) {
+ unsigned n i d ;
+
+ n i d = i n t e r l e a v e n i d ( pol , vma , addr , PAGE SHIFT ) ;
+ return a l l o c p a g e i n t e r l e a v e ( gfp , o r d e r , n i d ) ;
+ }
+ z l = z o n e l i s t p o l i c y ( gfp , p o l ) ;
+ i f ( p o l != & d e f a u l t p o l i c y && p o l ! = c u r r e n t −>mempolicy ) {
+ /∗
+
∗ s l o w p a t h : r e f c o u n t e d p o l i c y −− s h a r e d or vma
+
∗/
+ struct page ∗ page =
a l l o c p a g e s ( gfp , o r d e r , z l ) ;
+
mpol free ( pol ) ;
+ return page ;
+ }
+ /∗
+ ∗ f a s t path :
d e f a u l t or t a s k p o l i c y
+ ∗/
+ return
a l l o c p a g e s ( gfp , o r d e r , z l ) ;
+}
+#d e f i n e a l l o c p a g e v m a ( gfp , vmaptr , addr ) a l l o c p a g e s v m a ( gfp , vmaptr , addr , 0 )
+#e l s e
struct page ∗
a l l o c p a g e v m a ( g f p t gfp , struct v m a r e a s t r u c t ∗ vma , unsigned long addr )
{
@@ − 1 3 3 0 , 7 + 1 3 6 1 , 7 @@
∗/
return
a l l o c p a g e s ( gfp , 0 , z l ) ;
}
64
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
−
+#e n d i f
/∗ ∗
∗ a l l o c p a g e s c u r r e n t − A l l o c a t e pages .
∗
d i f f −urN l i n u x −2.6.23/mm/mmap. c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/mmap. c
−−− l i n u x −2.6.23/mm/mmap. c 2007 −10 −10 05:31:38.000000000 +0900
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/mmap. c 2008 −01 −21 18:43:15.000000000 +0900
@@ −31 ,10 +31 ,24 @@
#i n c l u d e <asm/ t l b . h>
#i n c l u d e <asm/ mmu context . h>
+#i f CONFIG SUPER PAGE
+ #i n c l u d e < l i n u x / k e r n e l . h>
+#e n d i f
+
#i f n d e f arch mmap check
#d e f i n e arch mmap check ( addr , l e n , f l a g s ) ( 0 )
#e n d i f
+#i f CONFIG SUPER PAGE
+e x t e r n i n t s u p e r p a g e v m a l i g n ;
+#d e f i n e SP ALIGN ( s u p e r p a g e v m a l i g n &1)
+#d e f i n e SUPER PAGE DEBUG A ( s u p e r p a g e v m a l i g n &8)
+#d e f i n e SUPER PAGE DEBUG B ( s u p e r p a g e v m a l i g n &4)
+#d e f i n e SUPER PAGE SIZE ( ( PAGE SIZE << s u p e r p a g e o r d e r [ s u p e r p a g e n r − 1 ] ) )
+#d e f i n e SUPER PAGE MASK ( ˜ ( SUPER PAGE SIZE−1))
+#d e f i n e SUPER PAGE ALIGN( addr ) ( ( ( addr)+SUPER PAGE SIZE−1)&SUPER PAGE MASK)
+#e n d i f
+
s t a t i c v o i d unmap region ( s t r u c t mm struct ∗mm,
s t r u c t v m a r e a s t r u c t ∗ vma , s t r u c t v m a r e a s t r u c t ∗ prev ,
u n s i g n e d l o n g s t a r t , u n s i g n e d l o n g end ) ;
@@ −933 ,6 +947 ,8 @@
/ ∗ Obtain t h e a d d r e s s t o map t o . we v e r i f y ( or s e l e c t ) i t and e n s u r e
∗ t h a t i t r e p r e s e n t s a v a l i d s e c t i o n of the address space .
∗/
+ i f (SUPER PAGE DEBUG A)
+ p r i n t k ( ” k i n o : : d o p g o f f ( ) : : SUPER PAGE DEBUG A : : % d , addr : : 0 x%x \n” ,
SUPER PAGE DEBUG A , addr ) ;
addr = g e t u n m a p p e d a r e a ( f i l e , addr , l e n , p g o f f , f l a g s ) ;
i f ( addr & ˜PAGE MASK)
return addr ;
@@ − 1 2 0 1 , 6 + 1 2 1 7 , 1 1 @@
}
i f ( ( f l a g s & MAP POPULATE) & & ! ( f l a g s & MAP NONBLOCK) )
m a k e p a g e s p r e s e n t ( addr , addr + l e n ) ;
+#i f d e f CONFIG SUPER PAGE
+ i f ( s u p e r p a g e o n && l e n >= (PAGE SIZE << s u p e r p a g e o r d e r [ 1 ] ) ) {
+
m a k e p t e s p r e s e n t ( addr , addr + l e n ) ;
+ }
+#e n d i f
return addr ;
unmap and free vma :
@@ − 1 2 3 1 , 6 + 1 2 5 2 , 7 @@
∗
∗ This f u n c t i o n ” knows ” t h a t −ENOMEM has t h e b i t s s e t .
∗/
+
#i f n d e f HAVE ARCH UNMAPPED AREA
unsigned long
a r c h g e t u n m a p p e d a r e a ( struct f i l e ∗ f i l p , unsigned long addr ,
@@ − 1 2 4 0 , 6 + 1 2 6 2 , 9 @@
struct v m a r e a s t r u c t ∗ vma ;
unsigned long s t a r t a d d r ;
+ i f (SUPER PAGE DEBUG A)
+ p r i n t k ( ” k i n o : : a r c h g e t u n m a p p e d a r e a ( ) \ n” ) ;
+
65
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
i f ( l e n > TASK SIZE )
return −ENOMEM;
@@ − 1 2 4 7 , 1 1 + 1 2 7 2 , 2 4 @@
return addr ;
i f ( addr ) {
+#i f CONFIG SUPER PAGE
+ i f ( SP ALIGN ) {
+
addr = SUPER PAGE ALIGN( addr ) ;
+ } else {
+
addr = PAGE ALIGN( addr ) ;
+ }
+#e l s e
addr = PAGE ALIGN( addr ) ;
+#e n d i f
+ i f (SUPER PAGE DEBUG A)
+
p r i n t k ( ” k i n o : : a r c h g e t u n m a p p e d a r e a : : addr : 0 x%x\n” , addr ) ;
vma = f i n d v m a (mm, addr ) ;
i f ( TASK SIZE − l e n >= addr &&
−
( ! vma | | addr + l e n <= vma−>v m s t a r t ) )
+
( ! vma | | addr + l e n <= vma−>v m s t a r t ) ) {
+
i f (SUPER PAGE DEBUG A)
+
p r i n t k ( ” k i n o : : a r c h g e t u n m a p p e d a r e a : : s u c c e s s addr : 0 x%x \n” , addr ) ;
return addr ;
+ }
}
i f ( l e n > mm−>c a c h e d h o l e s i z e ) {
s t a r t a d d r = addr = mm−>f r e e a r e a c a c h e ;
@@ − 1 3 1 5 , 6 + 1 3 5 3 , 8 @@
struct mm struct ∗mm = c u r r e n t −>mm;
unsigned long addr = addr0 ;
+ i f (SUPER PAGE DEBUG A)
+ p r i n t k ( ” k i n o : : a r c h g e t u n m a p p e d a r e a t o p d o w n ( ) \ n” ) ;
/∗ r e q u e s t e d l e n g t h t o o b i g f o r e n t i r e a d d r e s s s p a c e ∗/
i f ( l e n > TASK SIZE )
return −ENOMEM;
@@ − 1 3 2 4 , 1 1 + 1 3 6 4 , 2 4 @@
/∗ r e q u e s t i n g a s p e c i f i c a d d r e s s ∗/
i f ( addr ) {
+#i f CONFIG SUPER PAGE
+ i f ( SP ALIGN ) {
+
addr = SUPER PAGE ALIGN( addr ) ;
+ } else {
+
addr = PAGE ALIGN( addr ) ;
+ }
+#e l s e
addr = PAGE ALIGN( addr ) ;
+#e n d i f
+ i f (SUPER PAGE DEBUG A)
+
p r i n t k ( ” k i n o : : a r c h g e t u n m a p p e d a r e a t o p d o w n : : addr : 0 x%x \n” , addr ) ;
vma = f i n d v m a (mm, addr ) ;
i f ( TASK SIZE − l e n >= addr &&
−
( ! vma | | addr + l e n <= vma−>v m s t a r t ) )
+
( ! vma | | addr + l e n <= vma−>v m s t a r t ) ) {
+
i f (SUPER PAGE DEBUG A)
+
p r i n t k ( ” k i n o : : a r c h g e t u n m a p p e d a r e a t o p d o w n : : s u c c e s s addr : 0 x%x \n” , addr ) ;
return addr ;
+ }
}
/∗ c h e c k i f f r e e a r e a c a c h e i s u s e f u l f o r us ∗/
@@ − 1 4 1 2 , 6 + 1 4 6 5 , 1 0 @@
unsigned long ( ∗ g e t a r e a ) ( struct f i l e ∗ , unsigned long ,
unsigned long , unsigned long , unsigned long ) ;
+
+ i f (SUPER PAGE DEBUG A)
66
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1197
+
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
+
p r i n t k ( ” k i n o : : g e t u n m a p p e d a r e a ( ) : : SUPER PAGE DEBUG A : : % d\n” , SUPER PAGE DEBUG A
);
g e t a r e a = c u r r e n t −>mm−>g e t u n m a p p e d a r e a ;
i f ( f i l e && f i l e −>f o p && f i l e −>f o p −>g e t u n m a p p e d a r e a )
g e t a r e a = f i l e −>f o p −>g e t u n m a p p e d a r e a ;
@@ − 2 0 1 2 , 6 + 2 0 6 9 , 1 1 @@
mm−>locked vm += l e n >> PAGE SHIFT ;
m a k e p a g e s p r e s e n t ( addr , addr + l e n ) ;
}
+#i f d e f CONFIG SUPER PAGE
+ i f ( s u p e r p a g e o n && l e n >= (PAGE SIZE << s u p e r p a g e o r d e r [ 1 ] ) ) {
+
m a k e p t e s p r e s e n t ( addr , addr + l e n ) ;
+ }
+#e n d i f
return addr ;
}
d i f f −urN l i n u x − 2 . 6 . 2 3 /mm/ mprotect . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ m p r o t e c t . c
−−− l i n u x − 2 . 6 . 2 3 /mm/ m pro tect . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ mprotec t . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 1 1 9 , 6 + 1 1 9 , 1 3 @@
BUG ON( addr >= end ) ;
pgd = p g d o f f s e t (mm, addr ) ;
f l u s h c a c h e r a n g e (vma , addr , end ) ;
+#i f CONFIG SUPER PAGE
+ i f ( vma−>v m f l a g s & VM SUPERPAGE) {
+
a d j s p r a n g e (mm, 1 , addr , end ) ;
+ i f ( ( vma−>v m s t a r t==addr ) && (vma−>vm end==end ) )
+
vma−>v m f l a g s &= ˜VM SUPERPAGE;
+ }
+#e n d i f
do {
n e x t = p g d a d d r e n d ( addr , end ) ;
i f ( p g d n o n e o r c l e a r b a d ( pgd ) )
d i f f −urN l i n u x − 2 . 6 . 2 3 /mm/ s u p e r p a g e . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ s u p e r p a g e . c
−−− l i n u x − 2 . 6 . 2 3 /mm/ s u p e r p a g e . c 1 9 7 0 − 0 1 − 0 1 0 9 : 0 0 : 0 0 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ s u p e r p a g e . c 2 0 0 8 − 0 2 − 0 8 1 9 : 4 5 : 4 0 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 0 , 0 + 1 , 3 9 6 @@
+/∗
+ Linux Super Page i n t e r n a l f u n c t i o n s .
+∗/
+#i n c l u d e < l i n u x /mm. h>
+#i n c l u d e < l i n u x /mman . h>
+#i n c l u d e < l i n u x / swap . h>
+#i n c l u d e < l i n u x / s m p l o c k . h>
+#i n c l u d e < l i n u x /highmem . h>
+#i n c l u d e < l i n u x /pagemap . h>
+
+#i n c l u d e <asm/ p g a l l o c . h>
+#i n c l u d e <asm/ u a c c e s s . h>
+#i n c l u d e <asm/ t l b . h>
+#i n c l u d e <asm/ system . h> /∗ new ∗/
+#i n c l u d e < l i n u x / p r o c f s . h>
+#i n c l u d e < l i n u x / s y s c t l . h>
+#i n c l u d e < l i n u x /mmzone . h>/∗ f o r MAX ORDER ∗/
+#i n c l u d e ” i n t e r n a l . h”
+
+#i n c l u d e < l i n u x / s c h e d . h>
+#i n c l u d e < l i n u x / k e r n e l . h>
+#i n c l u d e < l i n u x / e r r n o . h>
+#i n c l u d e < l i n u x /smp . h>
+#i n c l u d e < l i n u x / s l a b . h>
+#i n c l u d e < l i n u x / s p i n l o c k . h>
+#i n c l u d e < l i n u x / module . h>
+#i n c l u d e < l i n u x / q u i c k l i s t . h>
+
+
+
+/∗ We use a r b i t r a r y h i g h number f o r t h e s y s c t l . You may have t o change i t . ∗/
67
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
+
+#d e f i n e CTL SET ON 1
+#d e f i n e CTL SET NR 2
+#d e f i n e CTL SET ALIGN 3
+#d e f i n e CTL SET BITMASK 4
+#d e f i n e CTL SET LOGRES 5
+
+i n t s u p e r p a g e o n = 0 ; /∗ We s t a r t w i t h o u t s u p e r p a g e a t f i r s t . ∗/
+i n t s u p e r p a g e n r = 1 ; /∗ We s t a r t w i t h o u t s u p e r p a g e a t f i r s t . ∗/
+i n t s u p e r p a g e v m a l i g n = 0 ; /∗ We s t a r t w i t h o u t s u p e r p a g e a l i g n a t f i r s t . ∗/
+i n t s u p e r p a g e t a i l a l i g n = 0 ; /∗ We s t a r t w i t h o u t s u p e r p a g e t a i l a l i g n a t f i r s t . ∗/
+i n t s u p e r p a g e b i t m a s k = (1<<SUPER PAGE NR) − 1 ; /∗ To c o n t r o l each o r d e r o f t h e
r e s e r v a t i o n . ∗/
+i n t s u p e r p a g e l o g r e s e t = 0 ; /∗ I f 1 t h e n r e s e t c o u n t e r when dumped ∗/
+
+unsigned long s u p e r p a g e r e s e r v e [ SUPER PAGE NR ] ;
+unsigned long s u p e r p a g e a l l o c a t e [ SUPER PAGE NR ] ;
+unsigned long s u p e r p a g e d o w n g r a d e [ SUPER PAGE NR ] ;
+#i f CONFIG SYSCTL
+s t a t i c c t l t a b l e s u p e r p a g e t a b l e [ ] = {
+ {
+ . c t l n a m e = CTL SET ON ,
+ . procname = ” on ” ,
+ . data = &s u p e r p a g e o n ,
+ . maxlen = s i z e o f ( i n t ) ,
+ . mode = 0644 ,
+ . proc handler = &proc dointvec ,
+ },
+ {
+ . c t l n a m e = CTL SET NR ,
+ . procname = ” nr ” ,
+ . data = & s u p e r p a g e n r ,
+ . maxlen = s i z e o f ( i n t ) ,
+ . mode = 0644 ,
+ . proc handler = &proc dointvec ,
+ },
+ {
+ . c t l n a m e = CTL SET ALIGN ,
+ . procname = ” v m a l i g n ” ,
+ . data = & s u p e r p a g e v m a l i g n ,
+ . maxlen = s i z e o f ( i n t ) ,
+ . mode = 0644 ,
+ . proc handler = &proc dointvec ,
+ },
+ {
+ . c t l n a m e = CTL SET BITMASK ,
+ . procname = ” bitmask ” ,
+ . data = &s u p e r p a g e b i t m a s k ,
+ . maxlen = s i z e o f ( i n t ) ,
+ . mode = 0644 ,
+ . proc handler = &proc dointvec ,
+ },
+ {
+ . c t l n a m e = CTL SET LOGRES ,
+ . procname = ” l o g r e s e t ” ,
+ . data = & s u p e r p a g e l o g r e s e t ,
+ . maxlen = s i z e o f ( i n t ) ,
+ . mode = 0644 ,
+ . proc handler = &proc dointvec ,
+ },
+ { . ctl name = 0 }
+};
+s t a t i c c t l t a b l e s y s t a b l e [ ] = {
+ {
+ . c t l n a m e = CTL SUPER PAGE,
+ . procname = ” s u p e r p a g e ” ,
+ . mode = 0555 ,
+ . child = super page table ,
+ },
+ { . ctl name = 0 }
68
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
+};
+
+#e n d i f
+
+#i f CONFIG PROC FS
+i n t s u p e r p a g e g e t i n f o ( char ∗ buf , char ∗ ∗ s t a r t , o f f t f p o s , i n t l e n g t h )
+{
+
char ∗ p = b u f ;
+
int i ;
+
+
if ( super page logreset ) {
+
super page logreset = 0;
+
f o r ( i =1; i <SUPER PAGE NR ; i ++) {
+
super page reserve [ i ] = 0;
+
super page allocate [ i ] = 0;
+
super page downgrade [ i ] = 0 ;
+
}
+
}
+
+
p += s p r i n t f ( p , ” Zoned Buddy a l l o c a t e MAXORDER: % d\n” , MAX ORDER) ;
+
p += s p r i n t f ( p , ” c u r r e n t on : % d\n” , s u p e r p a g e o n ) ;
+
p += s p r i n t f ( p , ” c u r r e n t nr : % d\n” , s u p e r p a g e n r ) ;
+
p += s p r i n t f ( p , ” c u r r e n t bitmask : % d\n” , s u p e r p a g e b i t m a s k ) ;
+
p += s p r i n t f ( p , ” c u r r e n t v m a l i g n : % d\n” , s u p e r p a g e v m a l i g n ) ;
+
p += s p r i n t f ( p , ” o r d e r \ t r e s e r v e \ t a l l o c a t e \ t f a i l \ n” ) ;
+
f o r ( i =1; i <SUPER PAGE NR ; i ++) {
+
p += s p r i n t f ( p , ”%d : \ t%l d \ t%l d \ t \ t%l d \n” ,
+
super page order [ i ] ,
+
super page reserve [ i ] ,
+
super page allocate [ i ] ,
+
super page downgrade [ i ]
+
);
+
}
+
return p − b u f ;
+ }
+#e n d i f
+
+void s u p e r p a g e i n i t ( ) {
+ int i ;
+ s u p e r p a g e n r = SUPER PAGE NR ;
+#i f CONFIG PROC FS
+ f o r ( i =0; i <SUPER PAGE NR ; i ++) {
+ super page reserve [ i ] = 0;
+ super page allocate [ i ] = 0;
+ super page downgrade [ i ] = 0 ;
+ }
+ c r e a t e p r o c i n f o e n t r y ( ” s u p e r p a g e ” , 0 , NULL, s u p e r p a g e g e t i n f o ) ;
+#e n d i f
+#i f CONFIG SYSCTL
+ register sysctl table ( sys table );
+#e n d i f
+}
+
+
+#i f CONFIG PROC FS
+i n t g e t a l l o c p a g e s n u m b e r ( struct zone ∗ zone , unsigned i n t o r d e r ) {
+ i n t i , number ;
+ unsigned long f l a g s ;
+ struct f r e e a r e a ∗ a r e a = zone−>f r e e a r e a + o r d e r ;
+ struct l i s t h e a d ∗ head , ∗ c u r r ; /∗ ∗ p r e v ; ∗/
+
+ s p i n l o c k i r q s a v e (&zone−>l o c k , f l a g s ) ;
+ head = & a rea −> f r e e l i s t ;
+ c u r r = head−>n e x t ;
+ number = 0 ;
+
+ f o r ( i = 0 ; i < 1 0 0 0 0 0 ; i ++) {
+
i f ( c u r r == head ) break ;
+
number++;
+
c u r r = c u r r −>n e x t ;
69
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
+ }
+
+ s p i n u n l o c k i r q r e s t o r e (&zone−>l o c k , f l a g s ) ;
+ return number ;
+}
+#e n d i f
+
+#i f CONFIG PROC FS
+i n t a l l o c p a g e s i n f o ( char ∗ buf , char ∗ ∗ s t a r t , o f f t f p o s , i n t l e n g t h ) {
+ i n t i , max order ;
+ char ∗ p = b u f ;
+
+ max order = MAX ORDER; /∗ f r e e a r e a [MAX ORDER ] ; ∗/
+
+ p += s p r i n t f ( p , ”ZONE NORMAL\n” ) ;
+ f o r ( i = 0 ; i <max order ; i ++) {
+
p += s p r i n t f ( p , ” f r e e a r e a [%d ] = % d\n” , i ,
+
get alloc pages number
+
( c o n t i g p a g e d a t a . n o d e z o n e s+ZONE NORMAL, i ) ) ;
+ }
+
return p − b u f ;
+}
+#e n d i f
+
+void a l l o c p a g e s i n i t ( ) {
+#i f CONFIG PROC FS
+ c r e a t e p r o c i n f o e n t r y ( ” a l l o c p a g e s ” , 0 , NULL, a l l o c p a g e s i n f o ) ;
+#e n d i f
+}
+
+
+
+ /∗
+
∗ A l l o c a t i n g PTEs f o r f u t u r e f a l t h a n d l i n g .
+
∗/
+void s e t s p r a n g e ( unsigned long a d d r e s s , i n t o r d e r , p g p r o t t p r o t )
+{
+ int i ;
+ p g d t ∗ pgd ;
+ p u d t ∗ pud ;
+ pmd t ∗pmd ;
+ p t e t ∗ pte ;
+
+ struct mm struct ∗mm = c u r r e n t −>mm;
+
+ s p i n l o c k (&mm−>p a g e t a b l e l o c k ) ;
+
pgd = p g d o f f s e t (mm, a d d r e s s ) ;
+
i f ( ! pgd ) goto out ;
+
pud = p u d o f f s e t ( pgd , a d d r e s s ) ;
+
i f ( ! pud ) goto out ;
+
pmd = p m d o f f s e t ( pud , a d d r e s s ) ;
+
i f ( ! pmd ) goto out ;
+
s p i n u n l o c k (&mm−>p a g e t a b l e l o c k ) ;
+
p t e = p t e a l l o c m a p (mm, pmd , ( a d d r e s s & ˜PGDIR MASK ) ) ;
+ s p i n l o c k (&mm−>p a g e t a b l e l o c k ) ;
+
i f ( ! pte none (∗ pte ) ) {
+
goto out ;
+
}
+
f o r ( i = 0 ; i < 1<< o r d e r ; i ++)
+
i f ( ! p t e n o n e ( ∗ ( p t e+i ) ) ) {
+
goto out ;
+
}
+
f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
+
s e t p t e r a w ( pte , p t e m o d i f y ( ∗ pte , p r o t ) ) ;
+
p t e++;
+
}
+out :
+
s p i n u n l o c k (&mm−>p a g e t a b l e l o c k ) ;
+
return ;
+}
70
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
+
+ /∗
+
∗ S i m p l i s t i c new page t a b l e a l l o c a t i o n f o r s y s b r k . .
+
∗ Only GH b i t ! = 0 t a b l e s w i l l be a l l o c a t e d .
+
∗ At t h i s time , we w i l l not a l l o c a t e r e a l s t o r a g e , i t remains
+
∗ for the p a g e f a u l t handler .
+
∗/
+i n t m a k e p t e s p r e s e n t ( unsigned long addr , unsigned long end )
+{
+ int i ;
+ unsigned long rem ;
+ i f ( addr >= end )
+
BUG( ) ;
+ /∗
+
∗ The f i r s t o r d e r ( i =0) i s t h e o r d i n a r y p t e ( 1 page ) , t h e n we s k i p t o
+
∗ a l l o c a t e the pte .
+
∗/
+ f o r ( i = 0 ; i < s u p e r p a g e n r − 1 ; i ++) {
+
rem = ( ˜ addr + 1 ) & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i + 1 ] ) − 1 ) ;
+
while ( rem &&
+
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
+
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
+
i f ( i&&s u p e r p a g e b i t m a s k & (1<< i ) ) {
+
s u p e r p a g e r e s e r v e [ i ]++;
+
s e t s p r a n g e ( addr , s u p e r p a g e o r d e r [ i ] , s u p e r p a g e p r o t [ i ] ) ;
+
}
+
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
+
rem −= PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
+
}
+ }
+ f o r ( i = s u p e r p a g e n r − 1 ; i > 0 ; i −−) {
+
while (
+
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
+
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
+
i f ( s u p e r p a g e b i t m a s k & (1<< i ) ) {
+
s u p e r p a g e r e s e r v e [ i ]++;
+
s e t s p r a n g e ( addr , s u p e r p a g e o r d e r [ i ] , s u p e r p a g e p r o t [ i ] ) ;
+
}
+
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
+
}
+ }
+ return 0 ;
+}
+
+
+void d o w n p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x )
+{
+ int i , order ;
+ p t e t ∗ addr ;
+ order = super page order [ index ] ;
+ addr = ( p t e t ∗ ) ( ( unsigned long ) p t e p t r &
+
˜ ( ( 1UL<<(o r d e r + SIZEOF PTE LOG2 ) ) − 1 ) ) ;
+ f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
+#i f CONFIG X86
+
( ∗ ( addr+i ) ) . p t e l o w =
+
( ( ∗ ( addr+i ) ) . p t e l o w & ˜SUPER PAGE MASK ) |
+
pgprot val ( super page prot [ index −1]);
+#e l s e
+
p t e v a l ( ∗ ( addr+i ) ) = ( p t e v a l ( ∗ ( addr+i ) ) & ˜SUPER PAGE MASK ) |
+
pgprot val ( super page prot [ index −1]);
+#e n d i f
+ }
+}
+
+void
b r e a k a r e a ( struct page ∗ page , unsigned long o r d e r )
+{
+ int i ;
+ unsigned long s i z e = 1 < < o r d e r ;
+
+ f o r ( i = 0 ; i < s i z e ; i ++ ) {
71
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
+
s e t p a g e c o u n t ( page + i , 1 ) ;
+ }
+ return ;
+}
+
+void c l e a r p t e s p ( p t e t ∗ p t e p t r , i n t i n d e x )
+{
+ int i , order ;
+ p t e t ∗ addr ;
+ order = super page order [ index ] ;
+ addr = ( p t e t ∗ ) ( ( unsigned long ) p t e p t r &
+
˜ ( ( 1UL<<(o r d e r + SIZEOF PTE LOG2 ) ) − 1 ) ) ;
+ f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
+#i f CONFIG X86
+
( ∗ ( addr+i ) ) . p t e l o w &= ˜SUPER PAGE MASK ;
+#e l s e
+
p t e v a l ( ∗ ( addr+i )) &= ˜SUPER PAGE MASK ;
+#e n d i f
+ }
+}
+
+void a d j s p p t e ( struct mm struct ∗mm, i n t zap ,
+
unsigned long a d d r e s s , i n t o r d e r )
+{
+ int i ;
+ i n t downgrade =0;
+ p g d t ∗ pgd ;
+ p u d t ∗ pud ;
+ pmd t ∗pmd ;
+ p t e t ∗ pte ;
+
+
+ pgd = p g d o f f s e t (mm, a d d r e s s ) ;
+ pud = p u d o f f s e t ( pgd , a d d r e s s ) ;
+ i f ( ! pud ) return ;
+ pmd = p m d o f f s e t ( pud , a d d r e s s ) ;
+ i f ( ! pmd ) return ;
+ p t e = p t e o f f s e t m a p (pmd , a d d r e s s ) ;
+ i f ( ! p t e ) return ;
+/∗
+We assume t h a t t h e l a r g e s t s u p e r page i s l e s s or e q u a l t o t h e
+mapped a r e a by t h e pmd . Then f o l l o w i n g code d o e s n o t t a k e
+t h e p m d o f f s e t a g a i n . I f you want t o us e a l a r g e r s u p e r page ,
+you need t o c h e c k t h e code .
+∗/
+ f o r ( i = 0 ; i < 1<< o r d e r ; i ++) {
+ retry :
+
i f ( s u p e r p a g e o r d e r [ p t e t o s p i n d e x ( ∗ ( p t e+i ) ) ] > o r d e r ) {
+
d o w n p t e s p ( p t e+i , p t e t o s p i n d e x ( ∗ ( p t e+i ) ) ) ;
+
downgrade =1;
+
goto r e t r y ;
+
}
+ }
+ i f ( zap ) c l e a r p t e s p ( pte , p t e t o s p i n d e x ( ∗ p t e ) ) ;
+ i f ( zap | | downgrade ) c l e a r p m d s p (pmd ) ;
+ return ;
+}
+
+void a d j s p r a n g e ( struct mm struct ∗mm, i n t zap ,
+
unsigned long addr , unsigned long end )
+ {
+
int i ;
+
unsigned long rem ;
+
i f ( addr >= end )
+
BUG( ) ;
+
f o r ( i = 0 ; i < s u p e r p a g e n r − 1 ; i ++) {
+
rem = ( ˜ addr + 1 ) & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i + 1 ] ) − 1 ) ;
+
while ( rem &&
+
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
+
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
72
付録 A Linux2.6.23 における IA-32 用 Super Page パッチファイル
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
+
a d j s p p t e (mm, zap , addr , s u p e r p a g e o r d e r [ i ] ) ;
+
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
+
rem −= PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
+
};
+
}
+
f o r ( i = s u p e r p a g e n r − 1 ; i > = 0 ; i −−) {
+
while (
+
( addr & ( ( PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) − 1 ) ) = = 0UL &&
+
( ( end − addr ) > = (PAGE SIZE << s u p e r p a g e o r d e r [ i ] ) ) ) {
+
a d j s p p t e (mm, zap , addr , s u p e r p a g e o r d e r [ i ] ) ;
+
addr += PAGE SIZE << s u p e r p a g e o r d e r [ i ] ;
+
};
+
}
+
return ;
+ }
+
d i f f −urN l i n u x − 2 . 6 . 2 3 /mm/ s w a p f i l e . c l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ s w a p f i l e . c
−−− l i n u x − 2 . 6 . 2 3 /mm/ s w a p f i l e . c 2 0 0 7 − 1 0 − 1 0 0 5 : 3 1 : 3 8 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
+++ l i n u x − 2 . 6 . 2 3 . s p 2 0 0 8 0 2 0 1 /mm/ s w a p f i l e . c 2 0 0 8 − 0 1 − 2 1 1 8 : 4 3 : 1 5 . 0 0 0 0 0 0 0 0 0 + 0 9 0 0
@@ − 5 9 9 , 7 + 5 9 9 , 1 2 @@
addr = vma−>v m s t a r t ;
end = vma−>vm end ;
}
−
+#i f CONFIG SUPER PAGE
+ i f ( vma−>v m f l a g s & VM SUPERPAGE) {
+
a d j s p r a n g e (vma−>vm mm, 1 , vma−>v m s t a r t , vma−>vm end ) ;
+ vma−>v m f l a g s &= ˜VM SUPERPAGE;
+ }
+#e n d i f
pgd = p g d o f f s e t (vma−>vm mm, addr ) ;
do {
n e x t = p g d a d d r e n d ( addr , end ) ;
73