コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2008年5月2日 >>> 2008年4月19日
link もっと後

2008年5月2日

Linuxのページテーブルが見当たらないときがある

目次: Linux

Linuxのページディレクトリを見ていると0xc000 0000以降(※)はページディレクトリエントリがあるのに、その先のページテーブルがありません。なぜこれで動くんでしょう?

調べてみると、なるほど、トリックがありました。

LinuxはCR4のPSEビット(Page Size Extension、ビット4)を1にして、4MB/4KBどちらのサイズでも使えるようにしています。

確かめ方は、右Alt + ScrLockを押してレジスタダンプすると簡単でしょうか?以下のようなメッセージが出るはずです。Pentium Proから導入されているはずですので、未対応というのはそうそうないかと…。

レジスタダンプの例
Pid: 0, comm:              swapper
EIP: 0060:[<c01019bd>] CPU: 0
EIP is at default_idle+0x31/0x59
 EFLAGS: 00010246    Not tainted  (2.6.18-6-486 #1)
EAX: 00000000 EBX: 00000800 ECX: c1101040 EDX: c030e000
ESI: 00099100 EDI: c0302800 EBP: 003a7007 DS: 007b ES: 007b
CR0: 8005003b CR2: c02bd7f4 CR3: 07175000 CR4: 00000690
 [<c0101a1c>] cpu_idle+0x37/0x4c
 [<c03105fa>] start_kernel+0x270/0x272

肝心なのはCR4レジスタの値です。CR4レジスタが0x0000 0690、2進数だと0110 1001 0000ですから、ビット4(ビット0から数えるので、右から5番目)のPSEビットが1になっていることが分かります。

(※)カーネルが使うリニアアドレス用のマッピングで、物理メモリ先頭896MB分を仮想アドレス0xc000 0000へマップしています。
物理: 0x0000 0000 .... 0x37ff ffff
リニア: 0xc000 0000 .... 0xf7ff ffff
というマッピングです。

二種類のページ

じゃあ4MBと4KBの区別はどこでやってるのさ?というと、ページディレクトリテーブルの要素である、ページディレクトリエントリでやっています。インテルのマニュアルによれば、ページディレクトリエントリの構成は以下のようになっています。


32ビットx86のページディレクトリエントリ

細かい説明は後述しますが、PSビット(Page Size、ビット7)が1になっていれば4MBのページを指し、0ならば4KBのページを使うことを意味します。

128MBの実メモリを割り当てた仮想マシン上でLinuxを起動して、適当なプロセスのページテーブルをダンプしてみると、768要素目から以下のようなページディレクトリエントリが見受けられます。

128MBしか実メモリがないので、768〜799番目(4MB x 32ページ)までしか値が埋まりません。余った800番目以降は別の用途に使われます。

カーネルのページディレクトリテーブルの一部
  768: 0x000001e3, 0x004001e3, 0x008001e3, 0x00c001e3, 
  772: 0x010001e3, 0x014001e3, 0x018001e3, 0x01c001e3, 
  776: 0x020001e3, 0x024001e3, 0x028001e3, 0x02c001e3, 
  780: 0x030001e3, 0x034001e3, 0x038001e3, 0x03c001e3, 
  784: 0x040001e3, 0x044001e3, 0x048001e3, 0x04c001e3, 
  788: 0x050001e3, 0x054001e3, 0x058001e3, 0x05c001e3, 
  792: 0x060001e3, 0x064001e3, 0x068001e3, 0x06c001e3, 
  796: 0x070001e3, 0x074001e3, 0x078001e3, 0x07c001e3, 
  800: 0x00000000, 0x00000000, 0x07baf067, 0x00000000, 

772番目を例に取ると、0xc100 0000〜0xc13f ffffの4MB分のアドレスをマップしています。0x010001e3は2進数だと0001 0000 0000 0000 0001 1110 0011ですので、先ほどの図に当てはめてみると、

ビット0: P(存在): 1
4KBページの時はページテーブルがロードされていることを表します。4MBページの場合はページが存在していることを表します。
ビット1: R/W(読み取り/書き込み): 1
0は読み取り専用、1なら書き込み可能であることを表します。
CR0のWPビット(書き込み保護、ビット16)を1にすると、スーパバイザからユーザの書き込み禁止ページに書き込んだときに、ページフォルト例外が発生するようになります。コピーオンライト機能の実現に役立ちます。
  • ページテーブルエントリEAが指すページAをコピーせよという命令に対し、実際はコピーせず、エントリEAを読み取り専用にし、さらに同じページを指すエントリEBを読み取り専用で作ります。
  • 読み取り時
    • エントリEAの指すページAへの読み取りは今まで通りです。
    • エントリEBは書き込みがない限りページAと同じ内容なので、読み取りだけならばエントリの指すページを変更する必要はありません。
  • 書き込み時
    • エントリEAの指すページAに書き込もうとすると、ページフォルト例外を発生させてページをコピーし、ページA' を作ります(書き込み時のコピー、コピーオンライト、COWとも)。
      以降はエントリEAは書き込み可能、指す先はページA' です(EA -> A', EB -> A)。
      そうしないとエントリEBが指すページAを使っている人が混乱します。エントリEBを使っている人から見ると、何もしていないのに(エントリEAの指すページAへの書き込み発生時に)勝手にページの内容が変わったように見えます。
    • 同様にエントリEBの指すページAに書き込もうとしても、ページフォルト例外が発生します。そのとき初めてページAの複製、ページBを作ります(コピーオンライト)。
      以降、エントリEBは書き込み可能、指す先はページBに変更されます。(EA -> A, EB -> B)
      ただし既にエントリEAがページAを指していないことが分かっているなら、コピー作業は無駄なのでしません。エントリEBはページAを指したままで、書き込み可能に変更されるだけです(EA -> A', EB -> A)。
ビット2: U/S(ユーザ/スーパバイザ): 0
0はスーパバイザ用の領域を意味し、1はユーザ/スーパバイザ用の領域を意味します。
ビット3: PWT(ページライトスルー): 0
0ならページへの書き込み時に、可能ならキャッシュのみを更新(ライトバック方式)します。1にするとキャッシュとメモリを同時に更新(ライトスルー方式)します。PCDが1のときは、そもそもキャッシュを使わないので無意味です。
  • CR0のNWビット(非ライトバック、ビット29)が1だと、ライトスルー方式が採用されます。こちらが優先です。
  • CR3のPWTビット(ページライトスルー、ビット3)が1だと、ライトスルー方式が採用されます。これはページディレクトリエントリだけのキャッシュ方式に適用されます。
しかしMTRRの設定とも関係します。ライトバックとライトスルーの設定がかち合ったときは、ライトスルーが優先されます。
ビット4: PCD(ページキャッシュ無効): 0
0にするとページをキャッシュします。1にするとページをキャッシュしなくなります。I/Oメモリなど、キャッシュしても意味がない領域などに使うそうです。
  • CR0のCDビット(キャッシュ無効、ビット30)が1だと、メモリに対するキャッシュ全てが無効になります。こちらが優先です。
  • CR3のPCDビット(ページキャッシュ無効、ビット4)が1だと、ページ単位のキャッシュは無効になります。これはページディレクトリエントリだけのキャッシュ方式に適用されます。
キャッシュの設定はMTRRの設定とも関係します。ライトバックとライトスルーがかち合ったときは、ライトスルーが優先されます。
ビット5: A(アクセス): 1
ページ番号が指しているページに読み込み、書き込みがあると1にセットされます。
ビット6: D(ダーティ): 1
ページ番号が指しているページに書き込みがあると1にセットされます。
ビット7: PS(ページサイズ): 1
0なら4KBページ、1なら4MBページを表します。ページディレクトリエントリ(一段目のテーブル)だけで有効です。
Linuxではページテーブル(二段目のテーブル)でアクセス権のないページを表すために、Pビットと合わせて使っています(当然CPUは無視します)。P:PS = 0:0なら存在しないページ、P:PS = 0:1ならアクセス権のないページを表します。
(4KBページ、ページテーブルエントリ(二段目のテーブル)のみ)Pentium Pro以降であれば、このビットはPATビットを表します。このビットが1であればPCDおよびPWTの2ビットで4つのメモリ属性(ライトバック、ライトスルー、MTRR優先のキャッシュ無効、MTRR上書きのキャッシュ無効)を表します。このビットが0であれば、従来と同じです。
ビット8: G(グローバル): 1
0ならTLBフラッシュの時に消されます、1なら消されずにずっと残ります。
CR4のPGEビット(グローバルページ有効、ビット7)を1にしないと意味がありません。
ビット12: PAT(ページ属性テーブル): 0
(4MBページのみ)0ならPAT機能を無効にして、1ならPAT機能を有効にします。
ビット31-22: ページ番号: 4(0x4)
先頭から16MB(4MB x 4個目)の位置にある4MB分の領域(0x0100 0000〜0x013f ffff)をマップすることを表します。

なぜ使い分けるのか

4MBのページングを使っているのはカーネル用のリニアアドレス(0xc000 0000〜)だけのようです。他のページディレクトリエントリにはPSビットが設定されていません。ページ番号の指す先には、もう一段ページテーブルがあり、その先にやっと4KBのページがあります。

理由ですが、インテルのマニュアルによると4MBと4KBのページは別のTLBに置かれるので、カーネルのように頻繁に使うコードやデータは4MBページに置いておくと、フラッシュされなくて良いよ、ってなことが書いてあります。また、ページサイズが大きければTLBミスも少ないよ、ってな解説もあります。恐らくそんな理由です。


あるプロセスのページディレクトリテーブル

絵にしてみるとこんな感じでしょうか。間違ってるかも…。

サイズはアドレスの範囲を意味するのではなくてテーブル自体の大きさのことです。ページディレクトリテーブル(一段目のテーブル)も、ページテーブル(二段目のテーブル)も 4バイトx 1024要素なので同じ4KBですよ、って言いたかっただけです。

編集者:すずき(2023/04/29 21:56)

コメント一覧

  • hdkさん(2008/05/03 14:11)
    あれ? PAT は? (・∀・)

    A ビットは書き込みがあっても 1 になりますね。A, D ビットは実際は TLB とも深く関わってます。R/W と CR0 の WR フラグも関係があります。
  • すずきさん(2008/05/03 16:23)
    PAT に MTRR ですか…正直、勘弁してくださいという領域ですorz
    良くわからんくせに、書き足しました。内容には全く自信ないです。
  • hdkさん(2008/05/03 18:07)
    MTRR ってわけわからんですよねー。
    たしか CR3 のキャッシュの設定って CPU がページディレクトリエントリを読み書きする時にキャッシュの設定をどうするかじゃなかったですか?
  • すずきさん(2008/05/03 19:19)
    >MTRR
    マニュアル読んだけど理解させる気ないね。難しすぎ。
    >CR3
    うお、早速間違ってた。直します。
  • すずきさん(2008/05/03 19:22)
    それにしても読みづらい日記だな…。
    hdk氏には感謝感謝。
  • すずきさん(2010/05/07 10:30)
    かなりいまさらになりますが…日記でやってるページテーブルダンプのやり方(bash, zsh 専用)
    # i=0x6e94000; dd if=/dev/mem skip=$((i / 4096)) bs=4096 count=1 | hexdump -v -e '" " 4/4 "0x%08x, " "\n"' | nl -v 0 -i 4 -s :
    です。

    i に代入する値は、
    ・適当にレジスタダンプ
    ・dmesg で結果見る
    ・CR3 レジスタ(= ページディレクトリエントリの値です)
    を確認してそれを 16進でそのまま入れてください。
  • すずきさん(2010/05/07 10:35)
    用語がふにゃふにゃしててすみません。訂正します。
    ページ「テーブル」のダンプじゃなくて、ページ「ディレクトリテーブル」のダンプです。
    日記に書いたとおり 4MB ページの場合は、ページテーブルはありません。
open/close この記事にコメントする



2008年5月1日

メーデー!メーデー!

今日はメーデーです。そんなことより、エクスプローラのネットワークドライブへの無駄なリトライがすごくイライラする。

あるマシンAでWindowsのネットワークドライブを設定(宛先をBとする)して、接続先であるマシンBを落とすと、当然そのネットワークドライブは使えなくなります。

そこまでは良いのですが、エクスプローラってば使えなくなったネットワークドライブにアクセスしようとすると10秒近くフリーズしてしまいます。TCP SYN+ACK待ちにしては諦めが早すぎるので、NetBIOSでしょうか?

さらに嫌なことに、ネットワークドライブと全く関係ない操作(例:フォーカスを戻す)でも、毎回ネットワークドライブを確認してはフリーズします。もうイライラして仕方ないです。

マシンAを起動した時点でマシンBが死んでいると、ネットワークドライブは切断されている扱いになって、上記の現象は起きません。その後マシンBを起動してもネットワークドライブは切断された扱いのままです。

切断されている状態だとネットワークドライブ上のファイルへのアクセスが軒並み失敗しますので、すぐにわかるかと思います。

しかしエクスプローラからネットワークドライブを見てしまうと再接続処理が走るようで、以降は接続された扱いになります。こうなるともうダメで、マシンBを落とすと上記のフリーズしまくり状態に突入します。

Sambaだとダメ

ネットワークドライブの接続先が Sambaの場合はフリーズ現象が発生します。接続先のマシンを落とすと、ネットワークドライブのプロパティには「ネットワークドライブ:NTFS(または未フォーマットとも)」などと表示されます。

一方で Windows XPの共有ドライブの場合はフリーズ現象が起こりません。接続先のマシンを落とすと、ネットワークドライブのプロパティには「切断されたネットワークドライブ」と表示されます。

どうもSambaはサーバ終了時に、接続中のクライアントに何かを通知すべきなのに、全部すっ飛ばして終了するみたいです。オプションでなんとかならんかなあ…。

原因不明

しかし、いつまでも未練がましく覚えているクライアント側も大概にしてほしいものです。なんとかしてネットワークドライブの記憶を消せないか探ってみました。

まず、以下のコマンドでARPのキャッシュをクリアしました。
arp -d *
しかし症状は変わらず。

次にNetBIOSのホスト名 <-> IPアドレスのキャッシュをクリアしました。
nbtstat -R
やはり直りません。

エクスプローラが何か覚えているのかもと explorer.exeを強制終了させ再起動しましたが、依然として直りません。

残るはSystemプロセス(pid: 4)が覚えている可能性がありますが、確かめる方法がわからんなあ。

編集者:すずき(2008/05/02 04:17)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2008年4月30日

黄金ウィーク

うちの会社は5/1と5/2が休みなので、今年のゴールデンウィークは6連休(5/1〜5/6)です。さらに4/29の祝日(昭和の日)を有給休暇(4/30)で繋いで8連休にする人が多いのではないでしょうか。

中には4/28も有給休暇にして 11連休(4/26〜5/6)でイ゛ェアアアア!!という猛者も居ます。

一方、自分は特に予定もなく今日も出社しておりました。普段と違うのは、チームの人が何人か居ないのと、良く知らない仕事(隣のチームの仕事の手伝い)が回ってきたくらいか…。

ちなみに隣のチームは修羅場ってて、ゴールデンウィークなんかねえよwwみたいな話をしている方がいました。恐ろしい子…!

編集者:すずき(2008/05/02 03:01)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2008年4月28日

一週間以上

ついに一週間更新せずに放置してしまいました。あわてて書き足すも、先週の頭あたりなんてもう覚えてないぜ。

私は正義、貴様を見ているぞ!

先日、JR長岡京駅で発見して以来、気になっていて仕方ないポスターがあります。鉄道警察隊によるちかん防止のポスターです。


せいぎくん

どうみても下手な絵、バラバラで虚ろな瞳、真っ赤な枠、首だけで浮かび「私は見ている 許さない」と決め台詞。「せいぎくん」はちかん被害にあった女性の代弁者なのでしょうか…呪ってやるという雰囲気すら感じます。見れば見るほどに怖いです。

ちなみに発行元が京都府警なので、京都府内の他駅(長岡京駅、以外)でも見かけるかもしれませんね。何、別に見たくない?あ、そう…。

編集者:すずき(2008/04/29 18:40)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2008年4月26日

見てるだけなら楽しい

M.U.G.E.Nという格闘ゲームの基盤プログラムがあります。キャラクターやステージを自由に追加でき、市販の格闘ゲームができることがそこそこできてしまう機能性をもっているそうです。(詳しくはWikipediaの M.U.G.E.Nの項をどうぞ)

ニコニコで公開されている MUGENの対戦動画(CPU戦)が面白くて、最近ずっと見ています。

格闘ゲームは見てる限りでは楽しいのですが、実際やると全く勝てずイライラします。コントローラを思い切り投げ飛ばしたくなる。

編集者:すずき(2008/04/29 01:38)

コメント一覧

  • ママ@ふふっ。さん(2008/04/30 16:28)
    1度、何メートルくらいとばせるか、やってみてください。
    こわれても、責任はもてませんが・・・
  • すずきさん(2008/05/01 19:19)
    遠投はしないですね。地面とか机に叩きつけます。
    以前、安物を机に叩きつけたらバラバラに砕け散ったことがありました。
open/close この記事にコメントする



2008年4月25日

飲み会

同期の人達と久々に飲み会をしました。どうも仕事の愚痴になっていかんね。酒飲んでいい気分なんだし、もっと前向きな話をした方が良いかもしれんなあ。

いつも使っているお店「とりひめ」のメニューが変わっていました。ピザが小さくなって貧乏くさくなりました。しかしとりひめサラダがVery goooood!! に進化していました。おいしかったので思わず4つ(@7人)も頼みました。

うまければ何でも良かった。今は反省していない。

編集者:すずき(2008/04/29 00:55)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2008年4月20日

やはりそこは社会人

大下さんちに遊びに行きました。金をけちって学生みたいなボロアパートに住んでるんじゃ…なんて思ってたんですけど。

全く心配無用でした。実に立派なお住まいです。部屋こそ前より狭いですが、綺麗だし、駅も近いし、入口もオートロックです。

ただ高い塀と有刺鉄線は、ちとやりすぎ感が拭えませんね。以前に事件が(しかも複数回)起きて、非難に晒されながら付けたか、有刺鉄線が大阪のスタンダードなのか?どちらにせよ、よくわからん街だなあ。

編集者:すずき(2008/04/29 00:44)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2008年5月2日 >>> 2008年4月19日
link もっと後

管理用メニュー

link 記事を新規作成

<2008>
<<<05>>>
----123
45678910
11121314151617
18192021222324
25262728293031

最近のコメント20件

  • link 21年9月20日
    すずきさん (11/19 01:04)
    「It was my pleasure.」
  • link 21年9月20日
    whtさん (11/17 23:41)
    「This blog solves my ...」
  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」
  • link 24年10月1日
    hdkさん (10/03 08:30)
    「おー、面白いですね。xrdpはすでに立ち...」
  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」
  • link 14年6月13日
    2048playerさん (09/26 01:00)
    「今のところ最も簡略化した式です。\n--...」
  • link 14年6月13日
    2048playerさん (09/16 01:00)
    「返信ありがとうございます。\nコメントが...」
  • link 14年6月13日
    すずきさん (09/12 21:19)
    「コメントありがとうございます。同じ結果に...」
  • link 14年6月13日
    2048playerさん (09/08 17:30)
    「私も2048の最高スコアを求めたのですが...」
  • link 14年6月13日
    2048さん (09/08 17:16)
    「私も2048の最高スコアを求めたのですが...」
  • link 14年6月13日
    2048playerさん (09/08 16:10)
    「私も2048の最高スコアを求めたのですが...」
  • link 02年8月4日
    lxbfYeaaさん (07/12 10:11)
    「555」
  • link 24年6月17日
    すずきさん (06/23 00:12)
    「ありがとうございます。バルコニーではない...」
  • link 24年6月17日
    hdkさん (06/22 22:08)
    「GPSの最初の同期を取る時は見晴らしのい...」
  • link 24年5月16日
    すずきさん (05/21 11:41)
    「あー、確かにdpkg-reconfigu...」
  • link 24年5月16日
    hdkさん (05/21 08:55)
    「システム全体のlocale設定はDebi...」
  • link 24年5月17日
    すずきさん (05/20 13:16)
    「そうですねえ、普通はStandardなの...」
  • link 24年5月17日
    hdkさん (05/19 07:45)
    「なるほど、そういうことなんですね。Exc...」

最近の記事3件

  • link 23年4月10日
    すずき (11/15 23:48)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年11月6日
    すずき (11/15 23:47)
    「[Ubuntu 24.04 LTS on ThinkPad X1 Carbon Gen 12] 目次: Linux会社ではTh...」
  • link 24年11月11日
    すずき (11/15 23:26)
    「[Pythonのテストフレームワーク] 目次: Python最近Pythonを触ることが増えたのでテストについて調べようと思い...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 11/19 01:04