Linuxカーネル/proc/$PID/mapsのダーティページ統計

Linuxカーネル/proc/$PID/mapsのダーティページ統計

長すぎます。一体カーネルが/proc/$PID/maps

次のCプログラムの説明を考えてみましょう。

static char page1[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE)))

初期化されていない変数は最初はゼロです。私が理解したのは、プログラムの起動時にカーネルが初期化されていない変数をページ0にマップし、ページの書き込み時にコピー遅延割り当てを実行することです。ページエラーが発生したときにカーネルがダーティページの初期化されていない部分を説明する可能性があるため、これをお勧めします。

さて、この言葉を考えてみましょう。

static char page1[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE))) = {'c'}

ここで、ローダーはプログラムの初期化中にpage1の値をロードし、そのページをRWとしてマークします。したがって、プログラムによって実行されたすべての書き込みはページエラーを引き起こさないため、カーネルには表示されません。

これは私が実験のために書いたプログラムです。

#define PAGE_SIZE (4*1024)
static char page1[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE))) = {'c'};
int main()
{
  char c; int i; int *d;
  scanf("%c", &c);                // --------- tag 1
  for(i = 0; i < PAGE_SIZE; i++)
    {
      page1[i] = c;               // --------- tag 2
    }
  d = malloc(sizeof(int));
  while(1);
  return 0;
}

これで、ラベル1(コードのコメント)の前後に/proc/$PID/smaps含まれるセクションの出力がpage1下の表に貼り付けられます。

シュトゥ 1個前タグ TAG-2以降
サイズ: 8KB 8KB
カーネルページサイズ: 4KB 4KB
MMUページサイズ: 4KB 4KB
RSS: 8KB 8KB
添付: 8KB 8KB
共有_クリーン: 0KB 0KB
共有_汚い: 0KB 0KB
個人清掃: 4KB 0KB
個人_汚い: 4KB 8KB
引用: 8KB 8KB
匿名: 4KB 8KB

ご覧のとおり、太い色のパラメータが変更されました。

質問

  1. 私がこのページを書いたことをカーネルはどうやって知りましたか?
  2. この匿名フィールドは何で、なぜ変更されますか?

すべての作業を詳しく説明する他のページ/ブログ/マニュアルが役に立ちます。

私は推測する:

おそらく、カーネルはページがRWであるにもかかわらず、ページをROとしてマークし、ページエラーが発生して計算される可能性があります。あるいは、プロセスのページテーブルを連続的に巡回する他のプロセスがあるかもしれませんが、コストがかかりすぎます。

答え1

  1. Linuxがサポートするほとんどの(おそらくすべては確認されていません)アーキテクチャでは、MMUはどのページがダーティであるかを追跡します。したがって、カーネルは、ページが初期化されたときにコンテンツがゼロでない場合でも、ページテーブルエントリのダーティビットをクリアでき、MMUはページが変更されたときにそれを更新します。

  2. 匿名メモリは、ファイルのバックアップがないメモリです。ページを作成すると、ファイルがサポートされていないメモリの量が増えます。初期化時には実行可能イメージとしてサポートされますが、一度変更するとサポートされなくなります。

カーネルがダーティページを確認する場所については、以下を参照してください。参考までにpte_dirty

カーネルもやや「柔らかくて汚い」、ユーザースペースから消去され、チェックポイントの回復に使用できます。

関連情報