Pages
- 物理頁(yè)是內(nèi)核管理內(nèi)存的基本單元刺洒。
- <linux/mm_type.h> struct page 表示一個(gè)物理page
struct page {
unsigned long flags;
atomic_t _count;
atomic_t _mapcount;
unsigned long private;
struct address_space *mapping;
pgoff_t index;
struct list_head lru;
void *virtual;
}
- flags
<linux/page-flags.h>里定義黄痪,標(biāo)示是否dirty, locked in memory等 - _count
引用計(jì)數(shù)誉察。一個(gè)page可能被page cache使用(mapping字段指向跟這個(gè)page關(guān)聯(lián)的 address_space), 也可能被一個(gè)進(jìn)程使用(page table 虛內(nèi)存mapping到物理內(nèi)存)域帐。 - virtual
這個(gè)page的虛擬地址痒谴。high memory可能為null
注意page表示物理內(nèi)存, 每個(gè)物理內(nèi)存頁(yè)對(duì)應(yīng)一個(gè)稚铣,內(nèi)核需要知道這個(gè)page是空閑的還是page cache在使用等箱叁。
Zones
因?yàn)橛布南拗疲瑑?nèi)核不能等同對(duì)待所有物理頁(yè)惕医。內(nèi)核把pages分成zones耕漱。特別的有這兩種硬件跟內(nèi)存訪問相關(guān):
- 一些硬件可以DMA(direct memory access)固定內(nèi)存地址
- 一些體系可以物理尋址的內(nèi)存比虛擬內(nèi)存多(什么情況?)抬伺。所以一些內(nèi)存沒有被永久的映射到內(nèi)核地址空間螟够。
Linux有4種主要的內(nèi)存zones:
- ZONE_DMA
- ZONE_DMA32
與上類似,只被32位設(shè)備訪問 - ZONE_NORMAL
normal, regularly mapped, pages - ZONE_HIGHMEM
This zone contains “high memory,” which are pages not perma-
nently mapped into the kernel’s address space.
實(shí)際內(nèi)存的zones布局是跟體系相關(guān)的峡钓。比如有的體系設(shè)備可以直接訪問0~16M,那這部位就做為ZONE_DMA妓笙。x86-64沒有ZONE_HIGHMEM。
Getting Pages
kmalloc()
類似用戶空間的malloc(), 內(nèi)核分配byte-sized chunks能岩。
在<linux/slab.h>里申明
void * kmalloc(size_t size, gfp_t flags)
分配的是物理連續(xù)的寞宫,返回起始地址。
使用實(shí)例:
struct dog *p;
p = kmalloc(sizeof(struct dog), GFP_KERNEL);
if (!p)
/* handle error ... */
gfp_mask Flags
有Action Modifiers, Zones Modifiers, Type Flags組成
ptr = kmalloc(size, __GFP_WAIT | __GFP_IO | __GFP_FS);
kfree()
與kmalloc()相反
vmalloc()
分配的連續(xù)的虛擬內(nèi)存
Slab Layer
管理分配相同大小對(duì)象的拉鹃。
Statically Allocating on the Stack
內(nèi)核態(tài)的棧大小是固定的辈赋,每個(gè)進(jìn)程2個(gè)page大小。每個(gè)進(jìn)程都有用戶態(tài)的棧跟內(nèi)核態(tài)的棧膏燕。
Per-CPU Allocations
一般數(shù)據(jù)對(duì)應(yīng)一個(gè)cpu個(gè)數(shù)大小的數(shù)據(jù)炭庙,每個(gè)對(duì)應(yīng)一個(gè)cpu,注意這樣不需要加鎖,只需要訪問的時(shí)候禁掉搶占煌寇。為什么需要禁掉搶占焕蹄,想下如果獲取這個(gè)變量準(zhǔn)備做修改,這是后搶占跑了另外一個(gè)進(jìn)程阀溶,這個(gè)進(jìn)程也獲取修改這個(gè)變量就有問題了(雖然都是跑的同一個(gè)cpu)腻脏, 重新調(diào)度后本身這個(gè)進(jìn)程也可能跑在了另一個(gè)cpu了。禁掉搶占的開銷比加鎖的開銷小得多银锻。
- 避免鎖
- reduce cache invalidation