Linux Kernel 記憶體分配方式

2021-05-04 01:21:58 字數 1986 閱讀 3782

頁分配

unsigned long __get_free_pages

(gfp_t

gfp_mask, unsigned int order

)直接從buddy系統中獲得原始頁。最原始的分配方式。

slab分配器
1. 通用 cache

void *kmalloc

(size_t

size

, gfp_t

flags

)kmalloc 基於以下幾種size的mem cache:32, 64, 128, 256, 512, 1,024, 2,048, 4,096,

8,192, 16,384, 32,768, 65,536 和 131,072 bytes。其本質也是呼叫kmem_cache_alloc來分配

object。所以kmalloc一次最大可分配的size為128kb。kmalloc分配速度很快,在分配時需注意gfp flag

引數:在不interrupt上下文(isr, softirq, tasklet)及不可睡眠上下文使用gfp_atomic。

核心還增加了記憶體清零的分配函式:kzalloc。

2. 專用 cache

kmem_cache_create

()void *kmem_cache_alloc

(struct kmem_cache

*cachep, gfp_t

flags

)如果你需要頻繁的分配和釋放某個結構,建議不要採用kmalloc,而是自己在slab系統中建立memory cache。

指定該結構的object size。分配時使用kmem_cache_alloc。同樣的slab object大小也有限制,一般情況

下乙個max_obj_order是5,也就是32個頁,128kb。

非連續記憶體分配
void *vmalloc

(unsigned long size

)超過128kb的記憶體顯然不能使用slab分配,並且當申請的連續記憶體大小不能在buddy系統中得到滿足,那麼

就需要使用vmalloc。vmalloc為了把物理的非連續頁乙個個對映,從而導致比直接記憶體對映大的多的

後援緩衝區抖動。除非需要特別大的記憶體,否則盡量不要使用vmalloc。

基於dma 分配

void * 

dma_alloc_coherent

(struct device

*dev

, size_t

size

, dma_addr_t

*handle

, gfp_t

gfp)

在某些arch中,可以使用dma_alloc_coherent來分配dma專用記憶體。列入在arch/arm/mm/consistent.c

中,該函式先分配最小可滿足size的2^order記憶體,然後釋放2^order-size多餘的頁給buddy。而arch/i386/

kernel/pci-dma.c中,則直接分配2^order塊記憶體。

直接對映分配

ioremap

(unsigned long phys_addr

, size_t

size

)int remap_pfn_range

(struct vm_area_struct

*vma, unsigned long addr

, unsigned long pfn, unsigned long size

, pgprot_t

prot)

在某些體系結構中,我們可以保留memory map段上的某乙個區域,作為dma或其他裝置的專有記憶體。

這段記憶體並不在kernel buddy的控制之下(沒有被放入mem_maps),你也無法從以上幾種分配方式中得到

這些記憶體。這個時候,你可以用ioremap和remap_pfn_range將這段記憶體直接對映到vm上。

Linux kernel 記憶體子系統

理論概述 核心把物理頁作為記憶體管理的基本單位 使用struct page結構來描述當前機器上的每乙個物理頁 比如核心支援4kb的頁大小,機器上有1gb物理記憶體,那麼意味著會有262144個struct page 核心把物理頁劃分為不同的區 同一區內的記憶體具有相似的特徵 一般會有zone dma...

Linux kernel 記憶體損壞漏洞

漏洞名稱 linux kernel 記憶體損壞漏洞 cnnvd編號 cnnvd 201310 143 2013 10 11 2013 10 11 危害等級 中危漏洞型別 緩衝區溢位 威脅型別 遠端 本地 cve編號 cve 2013 4387 linux kernel是美國linux 會發布的一款作...

Linux kernel 記憶體屏障在RCU上的應用

記憶體屏障主要解決的問題是編譯器的優化和cpu的亂序執行。編譯器在優化的時候,生成的彙編指令可能和c語言程式的執行順序不一樣,在需要程式嚴格按照c語言順序執行時,需要顯式的告訴編譯不需要優化,這在linux下是通過barrier 巨集完成的,它依靠volidate關鍵字和memory關鍵字,前者告訴...