batas memori kernel Linux

12

Saya memiliki masalah yang membingungkan. Saya memiliki perpustakaan yang menggunakan sg untuk mengeksekusi CDB yang disesuaikan. Ada beberapa sistem yang secara rutin memiliki masalah dengan alokasi memori di sg . Biasanya, driver sg memiliki batas keras sekitar 4MB, tetapi kami melihatnya pada beberapa sistem ini dengan ~ 2,3MB permintaan. Artinya, CDB sedang mempersiapkan untuk mengalokasikan untuk transfer 2.3mb. Seharusnya tidak ada masalah di sini: 2.3 <4.0.

Sekarang, profil mesin. Ini adalah CPU 64 bit tetapi menjalankan CentOS 6.0 32-bit (Saya tidak membangunnya juga tidak ada hubungannya dengan keputusan ini). Versi kernel untuk distro CentOS ini adalah 2.6.32. Mereka memiliki 16gb RAM.

Inilah tampilan penggunaan memori pada sistem (meskipun, karena kesalahan ini terjadi selama pengujian otomatis, saya belum memverifikasi apakah ini mencerminkan keadaan ketika errno ini dikembalikan dari 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

Saya menemukan artikel ini dari Linux Journal yaitu tentang mengalokasikan memori di kernel. Artikel ini bertanggal tetapi tampaknya berkaitan dengan 2.6 (beberapa komentar tentang penulis di kepala). Artikel tersebut menyebutkan bahwa kernel terbatas pada sekitar 1gb memori (meskipun tidak sepenuhnya jelas dari teks jika masing-masing 1gb untuk fisik dan virtual atau total). Saya ingin tahu apakah ini pernyataan yang akurat untuk 2.6.32. Pada akhirnya, saya bertanya-tanya apakah sistem ini mencapai batas ini.

Meskipun ini bukan jawaban untuk masalah saya, saya bertanya-tanya tentang kebenaran klaim 2.6.32. Jadi, berapa batas sebenarnya dari memori untuk kernel? Ini mungkin perlu menjadi pertimbangan untuk pemecahan masalah. Saran lain dipersilahkan. Apa yang membuat ini sangat membingungkan adalah bahwa sistem ini identik dengan banyak lainnya yang tidak menunjukkan masalah yang sama.

Andrew Falanga
sumber

Jawaban:

21

Batas 1 GiB untuk memori kernel Linux dalam sistem 32-bit adalah konsekuensi dari pengalamatan 32-bit, dan ini merupakan batasan yang cukup kaku. Bukan tidak mungkin untuk berubah, tetapi ada untuk alasan yang sangat bagus; mengubahnya memiliki konsekuensi.

Mari kita bawa mesin wayback ke awal 1990-an, ketika Linux sedang dibuat. Kembali pada masa itu, kita akan memiliki argumen tentang apakah Linux dapat dibuat untuk berjalan dalam 2 MiB RAM atau jika itu benar - benar membutuhkan 4 MiB keseluruhan . Tentu saja, para sombong kelas atas semua mencemooh kami, dengan 16 server monster MiB mereka.

Apa hubungannya sketsa kecil yang lucu itu dengan apa pun? Di dunia itu, mudah untuk membuat keputusan tentang bagaimana membagi ruang alamat 4 GiB yang Anda dapatkan dari pengalamatan 32-bit sederhana. Beberapa OS hanya membaginya menjadi dua, memperlakukan bit atas alamat sebagai "kernel flag": alamat 0 hingga 2 31 -1 telah bit atas dihapus, dan untuk kode ruang pengguna, dan alamat 2 31 hingga 2 32 - 1 memiliki set bit atas, dan untuk kernel. Anda bisa melihat alamatnya dan memberi tahu: 0x80000000 ke atas, ini adalah ruang kernel, jika tidak ruang pengguna.

Saat ukuran memori PC membengkak ke batas memori 4 GiB itu, pemecahan 2/2 sederhana ini mulai menjadi masalah. Ruang pengguna dan ruang kernel sama-sama memiliki klaim yang baik pada banyak RAM, tetapi karena tujuan kami memiliki komputer umumnya untuk menjalankan program pengguna, daripada menjalankan kernel, OS mulai bermain-main dengan pembagian pengguna / kernel. Perpecahan 3/1 adalah kompromi yang umum.

Mengenai pertanyaan Anda tentang fisik vs virtual, sebenarnya tidak masalah. Secara teknis, ini adalah batas memori virtual, tetapi itu hanya karena Linux adalah OS berbasis VM. Menginstal 32 GiB RAM fisik tidak akan mengubah apa pun, juga tidak akan membantu swaponpartisi swap 32 GiB. Apa pun yang Anda lakukan, kernel Linux 32-bit tidak akan pernah mampu mengatasi lebih dari 4 GiB secara bersamaan.

(Ya, saya tahu tentang PAE . Sekarang OS 64-bit akhirnya mengambil alih, saya harap kita bisa mulai melupakan hack jahat itu. Lagipula saya tidak percaya itu bisa membantu Anda dalam kasus ini.)

Intinya adalah bahwa jika Anda menjalankan ke batas VM kernel 1 GiB, Anda dapat membangun kembali kernel dengan split 2/2, tetapi itu berdampak langsung pada program ruang pengguna.

64-bit benar-benar jawaban yang tepat.

Warren Young
sumber
1
Terima kasih. Langgan ini bagus. Saya telah mengalami 2/2 split yang biasa digunakan di Windows. Pada waktu itu, saya mengetahui bahwa Linux menggunakan split 3/1. Saya berharap saya memikirkan hal itu ketika membaca artikel, saya pikir saya akan menghubungkan titik-titik. Jadi ... ini sepertinya aku harus mengingatnya. Mungkin tidak jauh dari jangkauan untuk berpikir sistem ini mencapai batas mengingat sifat dari tes. Pertanyaan besarnya adalah, mengapa sistem lain juga tidak mengalami hal ini. Terima kasih lagi.
Andrew Falanga
1
@AndrewFalanga: Sebenarnya, Windows modern juga menggunakan pemisahan fuzzy 3/1 .
Warren Young
1
Beberapa dari kami dapat menggabungkan memori dari tiga mesin berbeda yang diwarisi dari SSC untuk mendapatkan server 12 MB. Begitu banyak memori yang dapat kita lakukan apa pun yang kita inginkan ...
dmckee --- ex-moderator kitten
3
"Ya, saya tahu tentang model memori tersegmentasi x86 . Sekarang OS 32-bit akhirnya mengambil alih, saya harap kita bisa mulai melupakan peretasan jahat itu."
CVn
Ada dua kali lipat lebih banyak antara 32- dan 64-bit dibandingkan antara 16- dan 32, yang menggandakan jumlah waktu yang kita miliki untuk menunda peretasan tersebut, semuanya sama. Tapi semua yang lain tidak sama, apa dengan matahari terbenam Hukum Moore. Kami mendapat dua dekade dari komputasi x86 32-bit. Kita mungkin mendapatkan berabad-abad dari 64-bit. Pembacaan single-pass 2⁶⁴ byte RAM pada bandwidth DRAM saat ini akan memakan waktu sekitar 30 tahun . Di mana peningkatan bandwidth akan datang untuk memungkinkan kita mendekati batas 64-bit?
Warren Young
2

Saya ingin menambahkan sedikit jawaban Warren Young yang luar biasa , karena banyak hal yang sebenarnya lebih buruk daripada yang ditulisnya.

Ruang alamat kernel 1GB dibagi lagi menjadi dua bagian. 128MB untuk vmallocdan 896MB untuk lowmem. Tidak peduli apa artinya itu sebenarnya. Saat mengalokasikan memori, kode kernel harus memilih yang diinginkan. Anda tidak bisa hanya mendapatkan memori dari kolam mana saja yang memiliki ruang kosong.

Jika Anda memilih vmalloc, Anda dibatasi hingga 128MB. Sekarang 1GB tidak terlihat terlalu buruk ...

Jika Anda memilih lowmem, Anda dibatasi hingga 896MB. Tidak jauh dari 1GB, tetapi dalam hal ini, semua alokasi dibulatkan ke kekuatan berikutnya dari 2. Jadi alokasi 2.3MB sebenarnya mengkonsumsi 4MB. Selain itu, Anda tidak dapat mengalokasikan lebih dari 4MB dalam satu panggilan saat menggunakan lowmem.

64-bit benar-benar jawaban yang tepat.

ugoren
sumber
Saya punya pertanyaan terkait jawaban Anda. Untuk ruang memori ini bernama lowmem , apakah ini tempat memori dari panggilan seperti kmalloc dan kzmalloc berasal?
Andrew Falanga
@AndrewFalanga, ya, fungsi-fungsi ini menggunakan lowmem.
ugoren