Jadual Kandungan
3、页分配函数" >3、页分配函数
3.1 alloc_page()和alloc_pages()函数" >3.1 alloc_page()和alloc_pages()函数
3.2 __get_free_pages()系列函数" >3.2 __get_free_pages()系列函数
4、slab缓存" >4、slab缓存
4.1 创建slab缓存区" >4.1 创建slab缓存区
4.2 分配slab缓存函数" >4.2 分配slab缓存函数
4.3 释放slab缓存" >4.3 释放slab缓存
4.4 销毁slab缓存" >4.4 销毁slab缓存
4.5 slab缓存使用举例" >4.5 slab缓存使用举例
5、内存池" >5、内存池
5.1 创建内存池" >5.1 创建内存池
5.2 分配和回收对象" >5.2 分配和回收对象
5.3 销毁内存池" >5.3 销毁内存池
Rumah Operasi dan penyelenggaraan operasi dan penyelenggaraan linux Beberapa fungsi yang berkaitan dengan pengurusan memori linux

Beberapa fungsi yang berkaitan dengan pengurusan memori linux

Apr 10, 2023 pm 04:55 PM
linux

Fungsi berkaitan pengurusan memori Linux: 1. kmalloc(), digunakan untuk peruntukan memori dalam mod kernel 2. vmalloc(), biasanya digunakan untuk fungsi yang hanya wujud dalam perisian (tanpa makna perkakasan yang sepadan) Urutan yang lebih besar; penampan memperuntukkan memori;

Beberapa fungsi yang berkaitan dengan pengurusan memori linux

Persekitaran pengendalian tutorial ini: sistem linux7.3, komputer Dell G3.

Artikel ini menerangkan beberapa fungsi peruntukan memori biasa dalam kernel Linux dan persamaan dan perbezaannya, supaya mempunyai pemahaman yang lebih baik tentang mekanisme peruntukan memori asas Linux.

1. peruntukan memori, yang terakhir digunakan dalam mod pengguna. Fungsi kmalloc() memperuntukkan ruang storan

berterusan dalam memori fizikal Seperti fungsi malloc(), ia tidak akan mengosongkan data asal di dalamnya Jika memori mencukupi, kelajuan peruntukannya adalah sangat cepat. Prototaipnya adalah seperti berikut:


saiz
static inline void *kmalloc(size_t size, gfp_t flags);	/*返回的是虚拟地址*/
Salin selepas log masuk
: Saiz memori yang akan diperuntukkan. Disebabkan oleh mekanisme pengurusan memori Linux, memori hanya boleh diperuntukkan mengikut saiz halaman (biasanya 4KB untuk mesin 32-bit dan 8KB untuk mesin 64-bit Ini menyebabkan sistem masih kembali apabila kita hanya memerlukan beberapa bait). ingatan. Satu halaman ingatan jelas sangat membazir. Oleh itu, tidak seperti malloc, kaedah pemprosesan kmalloc ialah: kernel mula-mula memperuntukkan satu siri kumpulan memori dengan saiz yang berbeza (32B, 64B, 128B,..., 128KB Apabila memori perlu diperuntukkan, sistem akan memperuntukkan kumpulan memori yang lebih besar). daripada atau sama dengan Berikannya kolam memori terkecil yang memerlukan ingatan. Iaitu, memori yang diperuntukkan oleh kmalloc mempunyai minimum 32 bait dan maksimum 128KB. Jika melebihi 128KB, anda perlu mencuba fungsi peruntukan memori lain, seperti vmalloc().
  • bendera: Parameter ini digunakan untuk mengawal kelakuan fungsi yang paling biasa digunakan ialah GFP_KERNEL, yang bermaksud apabila tiada memori yang diperuntukkan pada masa ini, proses pergi ke. tidur dan tunggu sistem menyimpan kandungan penimbal Selepas SWAP ke cakera keras, dapatkan memori yang mencukupi dan kemudian bangunkan proses untuk memperuntukkannya. Lihat gambar di bawah untuk lebih banyak bendera:
  • Apabila menggunakan bendera GFP_ KERNEL untuk memohon ingatan, jika tidak dapat dipuaskan buat sementara waktu, proses akan tidur dan menunggu halaman, yang akan menyebabkan sekatan, jadi ia tidak boleh digunakan dalam konteks gangguan atau Gunakan GFP_KERNE untuk memohon memori apabila memegang kunci putaran. Oleh itu, ia tidak boleh menyekat dalam konteks bukan proses seperti pengendali gangguan, tugasan dan pemasa kernel Dalam kes ini, pemacu harus menggunakan bendera GFP_ATOMIC untuk memohon memori. Apabila menggunakan bendera GFP_ATOMIC untuk memohon ingatan, jika tiada halaman percuma, ia akan kembali terus tanpa menunggu.
    Beberapa fungsi yang berkaitan dengan pengurusan memori linux
  • Selain bendera yang disenaraikan dalam jadual di atas, ia juga termasuk yang berikut
  • :
  • _ _GFP_DMA (diperlukan untuk diperuntukkan dalam kawasan memori berkeupayaan DMA) _ _GFP_HIGHMEM (Menunjukkan bahawa memori yang diperuntukkan boleh ditempatkan dalam memori tinggi)
  • _ _GFP_COLD (Meminta halaman yang sudah lama tidak diakses)
  • _ _GFP_NOWARN (Menghalang kernel daripada mengeluarkan amaran apabila peruntukan tidak dapat dipenuhi)
  • _ _GFP_HIGH (permintaan keutamaan tinggi, membolehkan untuk mendapatkan halaman memori terakhir yang dikhaskan oleh kernel untuk kegunaan kecemasan)
  • _ _GFP_REPEAT (cuba semula usaha terbaik jika peruntukan gagal)
  • _ _GFP_NOFAIL (tanda hanya membenarkan permohonan yang berjaya, tidak digalakkan)
  • _ _GFP_NORETRY (jika permohonan tidak boleh dipohon, menyerah segera)
  • Memori yang digunakan untuk menggunakan kmalloc() hendaklah dikeluarkan menggunakan
  • , penggunaan fungsi ini adalah serupa dengan free() dalam ruang pengguna.
  • kfree()
2. vmalloc()

biasanya digunakan kerana ia hanya wujud dalam perisian (tidak mempunyai makna perkakasan yang sepadan ) untuk memperuntukkan memori daripada penimbal jujukan yang lebih besar Apabila memori tidak mempunyai ruang fizikal berterusan yang cukup besar untuk diperuntukkan, fungsi ini boleh digunakan untuk memperuntukkan memori dengan alamat maya berterusan tetapi alamat fizikal bukan berterusan . Memandangkan jadual halaman baharu perlu dibuat, overhednya jauh lebih besar daripada kmalloc dan fungsi

yang akan dibincangkan kemudian. Dan

tidak boleh digunakan dalam konteks atom kerana pelaksanaan dalamannya menggunakan vmalloc() dengan bendera GFP_KERNEL. Prototaip fungsinya adalah seperti berikut:

void *vmalloc(unsigned long size);
void vfree(const void *addr);
Salin selepas log masuk
  • 使用 vmalloc 函数的一个例子函数是 create_module()系统调用,它利用 vmalloc()函数来获取被创建模块需要的内存空间。
  • 内存分配是一项要求严格的任务,无论什么时候,都应该对返回值进行检测。
  • 在驱动编程中可以使用copy_from_user()对内存进行使用。下面举一个使用vmalloc函数的示例:
static int xxx(...)
{
	...
	cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
	if(!cpuid_entries)
	goto out;
	if(copy_from_user(cpuid_entries, entries, cpuid->nent * sizeof(struct kvm_cpuid_entry)))
		goto out_free;
	for(i=0; i<cpuid->nent; i++){
		vcpuid->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
		...
		vcpuid->arch.cpuid_entries[i].index = 0;
	}
	...
out_free:
	vfree(cpuid_entries);
out:
	return r;
}
Salin selepas log masuk

3、页分配函数

在linux中,内存分配是以页为单位的,32位机中一页为4KB,64位机中,一页为8KB,但具体还有根据平台而定。
根据返回值类型的不同,页分配函数分为两类,一是返回物理页地址,二是返回虚拟地址。虚拟地址和物理地址起始相差一个固定的偏移量。

#define __pa(x) ((x) - PAGE_OFFSET)
static inline unsigned long virt_to_phys(volatile void *address)
{
	return __pa((void *)address);
}

#define __va(x) ((x) + PAGE_OFFSET)
static inline  void* phys_to_virt(unsigned long address)
{
	return __va(address);
}
Salin selepas log masuk

Beberapa fungsi yang berkaitan dengan pengurusan memori linux

根据返回页面数目分类,分为仅返回单页面的函数和返回多页面的函数。

3.1 alloc_page()和alloc_pages()函数

该函数定义在头文件/include/linux/gfp.h中,它既可以在内核空间分配,也可以在用户空间分配,它返回分配的第一个页的描述符而非首地址,其原型为:

#define alloc_page(gfp_mask)  alloc_pages(gfp_mask, 0)
#define alloc_pages(gfp_mask, order) alloc_pages_node(numa_node_id(), gfp_mask, order)  //分配连续2^order个页面
static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order) 
{
	if(unlikely(order >= MAX_ORDER))
		return NULL;
	if(nid < 0)
		nid = numa_node_id();
	return __alloc_pages(gfp_mask, order, noed_zonelist(nid, gfp_mask));
}
Salin selepas log masuk

3.2 __get_free_pages()系列函数

它是kmalloc函数实现的基础,返回一个或多个页面的虚拟地址。该系列函数/宏包括 get_zeroed_page()_ _get_free_page()_ _get_free_pages()。在使用时,其申请标志的值及含义与 kmalloc()完全一样,最常用的是 GFP_KERNEL 和 GFP_ATOMIC。

/*分配多个页并返回分配内存的首地址,分配的页数为2^order,分配的页不清零。
order 允许的最大值是 10(即 1024 页)或者 11(即 2048 页),依赖于具体
的硬件平台。*/
unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
{
	struct page *page;
	page = alloc_pages(gfp_mask, order);
	if(!page)
		return 0;
	return (unsigned long)page_address(page);
}

#define __get_free_page(gfp_mask)  __get_free_pages(gfp_mask, 0)

/*该函数返回一个指向新页的指针并且将该页清零*/
unsigned long get_zeroed_page(unsigned int flags);
Salin selepas log masuk
  • 使用_ _get_free_pages()系列函数/宏申请的内存应使用free_page(addr)free_pages(addr, order)函数释放:
#define __free_page(page) __free_pages((page), 0)
#define free_page(addr) free_pages((addr), 0)

void free_pages(unsigned long addr, unsigned int order)
{
	if(addr != 0){
		VM_BUG_ON(!virt_addr_valid((void*)addr));
		__free_pages(virt_to_page((void *)addr), order);
	}
}

void __free_pages(struct page *page, unsigned int order)
{
	if(put_page_testzero(page)){
		if(order == 0)
			free_hot_page(page);
		else
			__free_pages_ok(page, order);
	}
}
Salin selepas log masuk

free_pages()函数是调用__free_pages()函数完成内存释放的。

4、slab缓存

  • 当在驱动程序中,遇到反复分配、释放同一大小的内存块时(例如,inode、task_struct等),建议使用内存池技术(对象在前后两次被使用时均分配在同一块内存或同一类内存空间,且保留了基本的数据结构,这大大提高了效率)。在linux中,有一个叫做slab分配器的内存池管理技术,内存池使用的内存区叫做后备高速缓存。
  • salb相关头文件在linux/slab.h中,在使用后备高速缓存前,需要创建一个kmem_cache的结构体。

4.1 创建slab缓存区

该函数创建一个slab缓存(后备高速缓冲区),它是一个可以驻留任意数目全部同样大小的后备缓存。其原型如下:

struct kmem_cache *kmem_cache_create(const char *name, size_t size, \
									 size_t align, unsigned long flags,\
									 void (*ctor)(void *, struct kmem_cache *, unsigned long),\
									 void (*dtor)(void *, struct kmem_cache *, unsigned ong)));
Salin selepas log masuk

其中:
name:创建的缓存名;
size:可容纳的缓存块个数;
align:后备高速缓冲区中第一个内存块的偏移量(一般置为0);
flags:控制如何进行分配的位掩码,包括 SLAB_NO_REAP(即使内存紧缺也不自动收缩这块缓存)、SLAB_HWCACHE_ALIGN ( 每 个 数 据 对 象 被 对 齐 到 一 个 缓 存 行 )、SLAB_CACHE_DMA(要求数据对象在 DMA 内存区分配)等);
ctor:是可选的内存块对象构造函数(初始化函数);
dtor:是可选的内存对象块析构函数(释放函数)。

4.2 分配slab缓存函数

一旦创建完后备高速缓冲区后,就可以调用kmem_cache_alloc()在缓存区分配一个内存块对象了,其原型如下:

void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
Salin selepas log masuk

cachep指向开始分配的后备高速缓存,flags与传给kmalloc函数的参数相同,一般为GFP_KERNEL。

4.3 释放slab缓存

该函数释放一个内存块对象:

void *kmem_cache_free(struct kmem_cache *cachep, void *objp);
Salin selepas log masuk

4.4 销毁slab缓存

kmem_cache_create对应的是销毁函数,释放一个后备高速缓存:

int kmem_cache_destroy(struct kmem_cache *cachep);
Salin selepas log masuk

它必须等待所有已经分配的内存块对象被释放后才能释放后备高速缓存区。

4.5 slab缓存使用举例

创建一个存放线程结构体(struct thread_info)的后备高速缓存,因为在linux中涉及频繁的线程创建与释放,如果使用__get_free_page()函数会造成内存的大量浪费,效率也不高。所以在linux内核的初始化阶段就创建了一个名为thread_info的后备高速缓存,代码如下:

/* 创建slab缓存 */
static struct kmem_cache *thread_info_cache;
thread_info_cache = kmem_cache_create("thread_info", sizeof(struct thread_info), \
										SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);

/* 分配slab缓存 */
struct thread_info *ti;
ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);

/* 使用slab缓存 */
...
/* 释放slab缓存 */
kmem_cache_free(thread_info_cache, ti);
kmem_cache_destroy(thread_info_cache);
Salin selepas log masuk

5、内存池

在 Linux 内核中还包含对内存池的支持,内存池技术也是一种非常经典的用于分配大量小对象的后备缓存技术。

5.1 创建内存池

mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, \
 							mempool_free_t *free_fn, void *pool_data);
Salin selepas log masuk

mempool_create()函数用于创建一个内存池,min_nr 参数是需要预分配对象的数目,alloc_fn 和 free_fn 是指向内存池机制提供的标准对象分配和回收函数的指针,其原型分别为:

typedef void *(mempool_alloc_t)(int gfp_mask, void *pool_data); 

typedef void (mempool_free_t)(void *element, void *pool_data);
Salin selepas log masuk

pool_data 是分配和回收函数用到的指针,gfp_mask 是分配标记。只有当_ _GFP_WAIT 标记被指定时,分配函数才会休眠。

5.2 分配和回收对象

在内存池中分配和回收对象需由以下函数来完成:

void *mempool_alloc(mempool_t *pool, int gfp_mask); 
void mempool_free(void *element, mempool_t *pool);
Salin selepas log masuk

mempool_alloc()用来分配对象,如果内存池分配器无法提供内存,那么就可以用预分配的池。

5.3 销毁内存池

void mempool_destroy(mempool_t *pool);
Salin selepas log masuk

mempool_create()函数创建的内存池需由 mempool_destroy()来回收。

相关推荐:《Linux视频教程

Atas ialah kandungan terperinci Beberapa fungsi yang berkaitan dengan pengurusan memori linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Perbezaan antara centos dan ubuntu Perbezaan antara centos dan ubuntu Apr 14, 2025 pm 09:09 PM

Perbezaan utama antara CentOS dan Ubuntu adalah: asal (CentOS berasal dari Red Hat, untuk perusahaan; Ubuntu berasal dari Debian, untuk individu), pengurusan pakej (CentOS menggunakan yum, yang memberi tumpuan kepada kestabilan; Ubuntu menggunakan APT, untuk kekerapan yang tinggi) Pelbagai tutorial dan dokumen), kegunaan (CentOS berat sebelah ke arah pelayan, Ubuntu sesuai untuk pelayan dan desktop), perbezaan lain termasuk kesederhanaan pemasangan (CentOS adalah nipis)

Cara memasang centos Cara memasang centos Apr 14, 2025 pm 09:03 PM

Langkah Pemasangan CentOS: Muat turun Imej ISO dan Burn Bootable Media; boot dan pilih sumber pemasangan; Pilih susun atur bahasa dan papan kekunci; Konfigurasikan rangkaian; memisahkan cakera keras; Tetapkan jam sistem; Buat pengguna root; pilih pakej perisian; Mulakan pemasangan; Mulakan semula dan boot dari cakera keras selepas pemasangan selesai.

CentOS berhenti penyelenggaraan 2024 CentOS berhenti penyelenggaraan 2024 Apr 14, 2025 pm 08:39 PM

CentOS akan ditutup pada tahun 2024 kerana pengedaran hulu, RHEL 8, telah ditutup. Penutupan ini akan menjejaskan sistem CentOS 8, menghalangnya daripada terus menerima kemas kini. Pengguna harus merancang untuk penghijrahan, dan pilihan yang disyorkan termasuk CentOS Stream, Almalinux, dan Rocky Linux untuk memastikan sistem selamat dan stabil.

Apakah kaedah sandaran untuk gitlab di centos Apakah kaedah sandaran untuk gitlab di centos Apr 14, 2025 pm 05:33 PM

Dasar sandaran dan pemulihan Gitlab di bawah sistem CentOS untuk memastikan keselamatan data dan pemulihan, Gitlab pada CentOS menyediakan pelbagai kaedah sandaran. Artikel ini akan memperkenalkan beberapa kaedah sandaran biasa, parameter konfigurasi dan proses pemulihan secara terperinci untuk membantu anda menubuhkan strategi sandaran dan pemulihan GitLab lengkap. 1. Backup Manual Gunakan Gitlab-Rakegitlab: Backup: Buat Perintah untuk Melaksanakan Backup Manual. Perintah ini menyokong maklumat utama seperti repositori Gitlab, pangkalan data, pengguna, kumpulan pengguna, kunci, dan kebenaran. Fail sandaran lalai disimpan dalam direktori/var/opt/gitlab/sandaran. Anda boleh mengubah suai /etc /gitlab

Penjelasan terperinci mengenai Prinsip Docker Penjelasan terperinci mengenai Prinsip Docker Apr 14, 2025 pm 11:57 PM

Docker menggunakan ciri -ciri kernel Linux untuk menyediakan persekitaran berjalan yang cekap dan terpencil. Prinsip kerjanya adalah seperti berikut: 1. Cermin digunakan sebagai templat baca sahaja, yang mengandungi semua yang anda perlukan untuk menjalankan aplikasi; 2. Sistem Fail Kesatuan (Unionfs) menyusun pelbagai sistem fail, hanya menyimpan perbezaan, menjimatkan ruang dan mempercepatkan; 3. Daemon menguruskan cermin dan bekas, dan pelanggan menggunakannya untuk interaksi; 4. Ruang nama dan cgroups melaksanakan pengasingan kontena dan batasan sumber; 5. Pelbagai mod rangkaian menyokong interkoneksi kontena. Hanya dengan memahami konsep -konsep teras ini, anda boleh menggunakan Docker dengan lebih baik.

Cara memasang cakera keras di centos Cara memasang cakera keras di centos Apr 14, 2025 pm 08:15 PM

Centos Hard Disk Mount dibahagikan kepada langkah -langkah berikut: Tentukan nama peranti cakera keras (/dev/sdx); Buat titik gunung (disyorkan untuk menggunakan /mnt /newdisk); laksanakan perintah gunung (mount /dev /sdx1 /mnt /newdisk); Edit fail /etc /fstab untuk menambah konfigurasi gunung tetap; Gunakan perintah UMount untuk menyahpasang peranti untuk memastikan bahawa tiada proses menggunakan peranti.

Cara menggunakan desktop docker Cara menggunakan desktop docker Apr 15, 2025 am 11:45 AM

Bagaimana cara menggunakan desktop Docker? Docktop Docktop adalah alat untuk menjalankan bekas Docker pada mesin tempatan. Langkah -langkah untuk digunakan termasuk: 1. Pasang desktop Docker; 2. Mulakan desktop Docker; 3. Buat imej Docker (menggunakan Dockerfile); 4. Membina imej Docker (menggunakan Docker Build); 5. Jalankan bekas Docker (menggunakan Docker Run).

Apa yang Harus Dilakukan Setelah CentOs Berhenti Penyelenggaraan Apa yang Harus Dilakukan Setelah CentOs Berhenti Penyelenggaraan Apr 14, 2025 pm 08:48 PM

Selepas CentOS dihentikan, pengguna boleh mengambil langkah -langkah berikut untuk menanganinya: Pilih pengedaran yang serasi: seperti Almalinux, Rocky Linux, dan CentOS Stream. Berhijrah ke pengagihan komersial: seperti Red Hat Enterprise Linux, Oracle Linux. Menaik taraf ke CentOS 9 Stream: Pengagihan Rolling, menyediakan teknologi terkini. Pilih pengagihan Linux yang lain: seperti Ubuntu, Debian. Menilai pilihan lain seperti bekas, mesin maya, atau platform awan.

See all articles