web-dev-qa-db-ja.com

Linuxカーネルのメモリ制限

私は当惑する問題を抱えています。カスタマイズされたCDBを実行するためにsgを使用するライブラリがあります。 sgのメモリ割り当てに日常的に問題があるシステムがいくつかあります。通常、sgドライバーのハード制限は約4MBですが、これらのいくつかのシステムでは、約2.3MBの要求があります。つまり、CDBは2.3MBの転送に割り当てる準備をしています。ここでは問題はありません:2.3 <4.0。

さて、マシンのプロファイル。それは64ビットCPUですが、CentOS 6.0 32ビットを実行します(私はそれらをビルドしなかったし、この決定とは関係ありません)。このCentOSディストリビューションのカーネルバージョンは2.6.32です。彼らは16GBのRAMを持っています。

システムでのメモリ使用状況は次のとおりです(ただし、このエラーは自動テスト中に発生するため、このerrnoがsg)。

top - 00:54:46 up 5 days, 22:05,  1 user,  load average: 0.00, 0.01, 0.21
Tasks: 297 total,   1 running, 296 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  15888480k total,  9460408k used,  6428072k free,   258280k buffers
Swap:  4194296k total,        0k used,  4194296k free,  8497424k cached

私は この記事Linux Journalから見つけました。これはカーネルにメモリを割り当てることに関するものです。記事は日付が付けられていますが、2.6に関係しているようです(筆頭の著者に関するコメント)。この記事では、カーネルは約1 GBのメモリに制限されていると述べています(物理および仮想または合計でそれぞれ1 GBであるかどうかは、テキストから完全に明確ではありません)。これは2.6.32の正確なステートメントかどうか疑問に思っています。結局のところ、これらのシステムがこの制限に達しているのではないかと思います。

これは実際には私の問題に対する答えではありませんが、2.6.32に対する主張の真実性について疑問に思っています。それでは、カーネルのメモリの実際の制限は何ですか?これはトラブルシューティングのための考慮事項である必要があるかもしれません。その他の提案は大歓迎です。これを非常に困惑させるのは、これらのシステムが、同じ問題を示さない他の多くのシステムと同じであることです。

12
Andrew Falanga

1 GiB 32ビットシステムでのLinuxカーネルメモリの制限は、32ビットアドレス指定の結果であり、かなり厳しい制限です。変更することは不可能ではありませんが、非常に良い理由ですが、変更すると結果が生じます。

Linuxが作成されていた1990年代初頭に、ウェイバックマシンを取り上げましょう。当時は、Linuxを2 MiBでRAM]で実行できるか、または本当に必要か4全体のMiBもちろん、16のMiBモンスターサーバーを備えたハイエンドのスノッブはすべて私たちに冷笑的でした。

その面白い小さなビネットは何と関係がありますか?その世界では、4 GiBの単純な32ビットアドレッシングから得られるアドレス空間を分割する方法について簡単に決定できます。一部のOSはそれを半分に分割し、 「カーネルフラグ」としてのアドレス:アドレス0から231-1は、上位ビットがクリアされ、ユーザー空間コード用であり、アドレス231 2まで32-1は上位ビットが設定されていて、カーネル用でした。あなたは単にアドレスを見て言うことができます:0x80000000以上、それはカーネル空間です、そうでなければそれはユーザー空間です。

PCのメモリサイズが4 GiBメモリ制限に向かって急増したため、この単純な2/2分割が問題になり始めました。ユーザー領域とカーネル領域の両方が大量のRAMで良い主張をしていましたが、コンピューターを持つ目的は、一般にカーネルを実行するのではなく、ユーザープログラムを実行することですが、OSはユーザーとカーネルの分割で遊んでいます。

物理か仮想かについてのあなたの質問に関しては、それは実際には問題ではありません。技術的には仮想メモリの制限ですが、それはLinuxがVMベースのOSだからです。 32 GiB of physical RAMは何も変更せず、swapon a 32 GiBパーティションをスワップします。32ビットのLinuxカーネルは、何をしても、4を超えるアドレスを指定することはできませんGiB同時に。

(はい、私は [〜#〜] pae [〜#〜] について知っています。64ビットOSがついに引き継がれるようになったので、私はその厄介なハックを忘れることができることを願っています。とにかく、この場合に役立つと信じています。)

結論として、1 GiB kernel VM制限に達している場合、2/2分割でカーネルを再構築できますが、ユーザー空間プログラムに直接影響します。

64ビットは正解です。

21
Warren Young

ウォーレン・ヤングの素晴らしい答え に少し付け加えたいのですが、実際には彼が書いているよりも悪いのです。

1GBのカーネルアドレス空間は、さらに2つの部分に分かれています。 128MBはvmalloc用で、896MBはlowmem用です。実際の意味を気にしないでください。メモリを割り当てるとき、カーネルコードは必要なものを選択する必要があります。空き容量のあるプールからメモリを取得することはできません。

vmallocを選択した場合、128MBに制限されます。 1GBはそれほど悪く見えません...

lowmemを選択すると、896MBに制限されます。 1GBからそれほど遠くないですが、この場合、すべての割り当ては次の2の累乗に切り上げられます。したがって、2.3MBの割り当ては実際には4MBを消費します。また、lowmemを使用する場合、1回の呼び出しで4MBを超える割り当てはできません。

64ビットは正解です。

2
ugoren