Linuxカーネルは64ビットシステムでmem_map配列をどのように初期化しますか?

Linuxカーネルは64ビットシステムでmem_map配列をどのように初期化しますか?

私はLinuxカーネルがC構造に依存して各物理ページフレームの状態を追跡することを知っていますstruct page。すべてのページフレームの構造はmem_map[]フォーマットされた配列を形成するため、struct pageページフレーム番号をインデックスとして使用して特定のページフレームの構造を簡単に取得できます。 4GiBの物理メモリを備えたx86 32ビットシステムでは、配列は2から20
項目で構成され、ページサイズは4096バイトであるため、各項目のサイズは32バイトであるため、配列全体は32MiBを消費します。これで、物理メモリが4TiBのx86 64ビットシステムに転送されると、配列はそれぞれ32バイトのサイズの2つの30項目で構成されるため、配列は32GiBを消費します。もちろん、物理メモリが増加するにつれて、プラットフォーム固有の4PiB(amd64アーキテクチャの場合は252バイト)に達すると、アレイを最大32TiBまで増やすことができます。カーネルは実際にブート時に大量のデータを初期化する必要がありますか、それとも何か抜けましたか?

答え1

3つあります。物理メモリモデルLinuxカーネルは、説明するフラットモデル、不連続メモリモデル、および希少メモリモデルを使用します。

すべてではありませんが、ほとんどのLinuxでサポートされている64ビットアーキテクチャはデフォルトで後者を使用します。これは、メモリ部分とほとんどのアーキテクチャに仮想的に割り当てられたメモリマッピングに依存します。実際の物理メモリを表すのに必要な項目は、必要に応じて割り当てられ初期化されます。大規模システムでは、開始が遅れないようにこの初期化を延期することも可能です。

答え2

https://lwn.net/Articles/839737/(2020年12月11日)まだ「ページ構造は一般的に利用可能なメモリの1.5%以上を占めています」と言います。パーセンテージは64/4096 = 1.5625%からのようです。

5700 GB のメモリがあり、Azure 上で動作する M416s_v2 Ubuntu 20.04 VM では、オーバーヘッドは 1.5657% で、1.5625% に近いです。

"cat /proc/meminfo |grep MemTotal:" 表示: "MemTotal: 5882783592 kB"

(Linux kdump用に512 MBのメモリを予約しました) console=tty1 を表示します console=ttyS0 Earlyprintk=ttyS0 crashkernel=512M パニック=-1"

1 - (5882783592 / (5700.0 * 1024 * 1024 - 512 * 1024)) = 0.015657580372575808

(5700*1024*1024)*(0.015657580372575808 - 64.0/4096)/1024=190.16511865047505

ページ構造に加えて、カーネル/ドライバコード/データ/BSSは約190MBを使用します。ここでは、ファームウェアによって予約されているメモリを無視します。

関連情報