Apa perbedaan antara vmalloc dan kmalloc?

113

Saya telah mencari-cari di Google dan menemukan kebanyakan orang menganjurkan penggunaan kmalloc, karena Anda dijamin mendapatkan blok memori fisik yang berdekatan. Namun, tampaknya juga kmallocdapat gagal jika blok fisik yang berdekatan yang Anda inginkan tidak dapat ditemukan.
Apa keuntungan memiliki blok memori yang berdekatan? Secara khusus, mengapa saya perlu memiliki blok fisik memori yang berdekatan dalam panggilan sistem ? Apakah ada alasan mengapa saya tidak bisa begitu saja menggunakan vmalloc?
Akhirnya, jika saya mengalokasikan memori selama penanganan panggilan sistem, haruskah saya menentukan GFP_ATOMIC? Apakah panggilan sistem dijalankan dalam konteks atom?

GFP_ATOMIC
Alokasi ini berprioritas tinggi dan tidak tidur. Ini adalah bendera untuk digunakan pada penangan interupsi, bagian bawah dan situasi lain di mana Anda tidak bisa tidur.

GFP_KERNEL Ini adalah alokasi normal dan mungkin memblokir. Ini adalah bendera untuk digunakan dalam kode konteks proses saat aman untuk tidur.

FreeMemory
sumber
Artikel bagus tentang vmalloc dan kmalloc http://learnlinuxconcepts.blogspot.in/2014/02/linux-memory-management.html
JIN007
4
Artikel tersebut mengklaim omong kosong seperti: "Umumnya arsitektur 32 bit memiliki ukuran halaman 4KB dan arsitektur 64 bit memiliki ukuran halaman 8KB". Saya belum sepenuhnya membacanya, tetapi saya tidak akan menyebutnya "baik", atau bahkan memercayai sepatah kata pun darinya.
Alexandro Sánchez
1
Catatan (semi terkait): vmalloclebih cepat dengan Kernel 5.2 (Q2 2019)
VonC

Jawaban:

96

Anda hanya perlu khawatir tentang penggunaan memori yang berdekatan secara fisik jika buffer akan diakses oleh perangkat DMA pada bus yang dialamatkan secara fisik (seperti PCI). Masalahnya adalah banyak panggilan sistem tidak memiliki cara untuk mengetahui apakah buffer mereka pada akhirnya akan diteruskan ke perangkat DMA: setelah Anda meneruskan buffer ke subsistem kernel lain, Anda benar-benar tidak dapat mengetahui kemana perginya. Bahkan jika kernel tidak menggunakan buffer untuk DMA saat ini, pengembangan di masa mendatang mungkin akan melakukannya.

vmalloc sering kali lebih lambat dari kmalloc, karena mungkin harus memetakan ulang ruang buffer menjadi rentang yang hampir bersebelahan. kmalloc tidak pernah memetakan ulang, meskipun jika tidak dipanggil dengan GFP_ATOMIC kmalloc dapat memblokir.

kmalloc dibatasi dalam ukuran buffer yang dapat disediakannya: 128 KBytes *) . Jika Anda membutuhkan buffer yang sangat besar, Anda harus menggunakan vmalloc atau mekanisme lain seperti menyimpan memori tinggi saat boot.

*) Ini berlaku untuk kernel sebelumnya. Pada kernel baru-baru ini (saya mengujinya pada 2.6.33.2), ukuran maksimal satu kmalloc hingga 4 MB! (Saya menulis posting yang cukup rinci tentang ini .) - kaiwan

Untuk panggilan sistem Anda tidak perlu meneruskan GFP_ATOMIC ke kmalloc (), Anda dapat menggunakan GFP_KERNEL. Anda bukan penangan interupsi: kode aplikasi memasuki konteks kernel melalui sebuah perangkap, ini bukan sebuah interupsi.

DGentry
sumber
1
Saya pikir panggilan sistem dimasukkan dengan memicu int $ 0x80? (yaitu interupsi)?
FreeMemory
2
int $ 0x80 adalah interupsi perangkat lunak, juga disebut jebakan. Yang dimaksud dengan penangan interupsi adalah interupsi perangkat keras, seperti saat pengguna menekan suatu tombol atau memindahkan suatu jurus.
Branan
Panggilan sistem adalah untuk transisi ruang pengguna ke ruang kernel ... kmalloc hanya digunakan dalam konteks kernel ??
AIB
3
@FreeMemory: int $ 0x80 adalah khusus x86, dan kemudian, ini juga merupakan metode lama yang digantikan oleh sysenter / syscall (pada x86).
jørgensen
18

Jawaban singkatnya: unduh Linux Device Drivers dan baca bab tentang manajemen memori.

Serius, ada banyak masalah halus terkait dengan manajemen memori kernel yang perlu Anda pahami - Saya menghabiskan banyak waktu untuk men-debug masalah dengannya.

vmalloc () sangat jarang digunakan, karena kernel jarang menggunakan memori virtual. kmalloc () adalah yang biasanya digunakan, tetapi Anda harus tahu apa konsekuensi dari flag yang berbeda dan Anda membutuhkan strategi untuk menangani apa yang terjadi jika gagal - terutama jika Anda berada dalam penangan interupsi, seperti yang Anda sarankan.

Mike Heinz
sumber
1
"karena kernel jarang menggunakan memori virtual", mengapa demikian?
Trey
Karena pada umumnya Anda tidak menginginkan blok kernel saat menunggu kernel menukar memori masuk atau keluar dari penyimpanan disk ...
Mike Heinz
Tidak, memori kernel yang dialokasikan dengan vmalloc tidak pernah ditukar. Hanya memori ruang pengguna yang dapat ditukar. Ruang alamat kernel tidak dapat ditukar, dan vmalloc mengalokasikan di ruang alamat kernel.
pengguna2679859
13

Pengembangan Kernel Linux oleh Robert Love (Bab 12, halaman 244 dalam edisi ke-3) menjawab ini dengan sangat jelas.

Ya, memori yang berdekatan secara fisik tidak diperlukan dalam banyak kasus. Alasan utama kmalloc digunakan lebih dari vmalloc di kernel adalah kinerja. Buku tersebut menjelaskan, ketika potongan memori besar dialokasikan menggunakan vmalloc, kernel harus memetakan potongan (halaman) yang tidak bersebelahan secara fisik ke dalam satu wilayah memori virtual yang berdekatan. Karena memori secara virtual berdekatan dan secara fisik tidak bersebelahan, beberapa pemetaan alamat virtual-ke-fisik harus ditambahkan ke tabel halaman. Dan dalam kasus terburuk, akan ada (ukuran buffer / ukuran halaman) jumlah pemetaan yang ditambahkan ke tabel halaman.

Ini juga menambah tekanan pada TLB (entri cache yang menyimpan pemetaan alamat virtual ke fisik terbaru) saat mengakses buffer ini. Ini bisa menyebabkan meronta - ronta .

codetwiddler
sumber
11

The kmalloc()& vmalloc()functions adalah antarmuka sederhana untuk mendapatkan memori kernel dalam potongan berukuran byte.

  1. The kmalloc()Fungsi menjamin bahwa halaman fisik berdekatan (dan hampir berdekatan).

  2. The vmalloc()fungsi bekerja dengan cara yang sama untuk kmalloc(), kecuali mengalokasikan memori yang hanya hampir berdekatan dan belum tentu berdekatan secara fisik.

Yogeesh HT
sumber
4

Apa keuntungan memiliki blok memori yang berdekatan? Secara khusus, mengapa saya perlu memiliki blok fisik memori yang berdekatan dalam panggilan sistem? Apakah ada alasan mengapa saya tidak bisa menggunakan vmalloc begitu saja?

Dari "Saya Lagi Beruntung" dari Google di vmalloc:

kmalloc adalah cara yang disukai, selama Anda tidak membutuhkan area yang terlalu luas. Masalahnya adalah, jika Anda ingin melakukan DMA dari / ke beberapa perangkat keras, Anda harus menggunakan kmalloc, dan Anda mungkin membutuhkan potongan yang lebih besar. Solusinya adalah mengalokasikan memori sesegera mungkin, sebelum memori terfragmentasi.

Dark Shikari
sumber
Lihat, saya membacanya, dan itu tidak masuk akal bagi saya. Saya mengerti menggunakan kmalloc untuk besar daerah; tetapi untuk alokasi kecil, mengapa tidak menggunakan vmalloc untuk menghindari fragmentasi memori fisik?
FreeMemory
Karena Anda harus mempercayai kernel untuk melakukan yang terbaik; jika menurutnya mengalokasikan satu bagian lebih baik, itu akan melakukannya. vmalloc hanya untuk saat Anda benar - benar harus memiliki bagian yang berdekatan.
Dark Shikari
Saya rasa itu masuk akal, tetapi tampaknya berlawanan dengan intuisi. kmalloc terdengar seperti itu harus digunakan ketika kinerja sangat memprihatinkan (yaitu saya tidak dapat diganggu oleh disk IO). Selain itu, bagaimana dengan GFP_ATOMIC?
FreeMemory
2

Pada sistem 32-bit, kmalloc () mengembalikan alamat logis kernel (meskipun ini adalah alamat virtual) yang memiliki pemetaan langsung (sebenarnya dengan offset konstan) ke alamat fisik. Pemetaan langsung ini memastikan bahwa kami mendapatkan potongan fisik RAM yang berdekatan. Cocok untuk DMA di mana kami hanya memberikan penunjuk awal dan mengharapkan pemetaan fisik yang berdekatan setelahnya untuk operasi kami.

vmalloc () mengembalikan alamat virtual kernel yang pada gilirannya mungkin tidak memiliki pemetaan yang berdekatan pada RAM fisik. Berguna untuk alokasi memori yang besar dan dalam kasus di mana kami tidak peduli bahwa memori yang dialokasikan untuk proses kami juga berkelanjutan di RAM Fisik.

a.saurabh
sumber
1

Salah satu perbedaan lainnya adalah kmalloc akan mengembalikan alamat logis (jika tidak, Anda menentukan GPF_HIGHMEM). Alamat logis ditempatkan di "memori rendah" (dalam gigabyte pertama memori fisik) dan langsung dipetakan ke alamat fisik (gunakan makro __pa untuk mengubahnya). Properti ini menyiratkan memori kmalloced adalah memori berkelanjutan.

Di sisi lain, Vmalloc mampu mengembalikan alamat virtual dari "memori tinggi". Alamat ini tidak dapat diubah dalam alamat fisik secara langsung (Anda harus menggunakan fungsi virt_to_page).

Jérôme Pouiller
sumber