一、页
内存管理的基本单位:页。
内核中用struct page表示物理页,位于
1)获得页
核心:alloc_pages(gft_t gft_mask,order),连续分配2n个连续物理页,返回至向第一个页page结构体的指针;也有函数返回逻辑地址get_free_page;也可以请求并填充为0。
参数gft_t (
释放页free_page
2) kmalloc
获得字节为单位的一块内核内存 ,kmalloc(size,gft_t flags)
由于连续,因此性能更好
kfree释放由kmalloc申请的地址空间
3)vmalloc
分配的内存虚拟地址连续,而物理地址则无需连续。为把不连续的物理地址在逻辑地址上连续,需建立专门的页表项,且每页都需要一一映射。
声明在
vfree:释放
二、区
内核使用区对相似特性的页进行分组,与体系结构相关。linux的页主要包含于四个区中:
a. ZONE_DMA:执行DMA操作 <16M
b. ZONE_DMA32:只能被32位设备访问、
c. ZONE_NORAL:能正常映射的页
d. ZONE_HIGHEM:高端内存,页不能永久映射到内核地址空间 >896M
永久映射:kmap(page)
临时映射:kmap_atomic(page,type)。使用内核的保留映射来进行临时存放,主要用于上下文不能睡眠的情况来避免阻塞
高端内存一般使用alloc_pages(),返回指向strut page结构的指针,因为可能没有逻辑地址与之对应。
三、slab层(slab分配器)
通用数据结构缓存层
设计:一个或多个物理连续页组成slab,多个slab组成高速缓存。一个高速缓存对应一种对象类型,将不同类型对象划分为高速缓存组,如存放进程描述符的高速缓存组。
slab:包含一些对象成员;slab状态:满、部分、空。
高速缓存kmem_cache包含三个链表full、partial、slabs_empty,链表包含高速缓存中所有slab 。
slab描述符struct slab
管理:
通过在高速缓存的基础上,提供给内核的接口完成对slab层的管理。
创建:kmem_cache_create(name,size,align,flag)
撤销:kmem_cache_destroy(cachep)
分配:kmem_cache_alloc(cachep,flags)
释放:kmem_cache_free(cachep,objp)
四、栈的静态分配
进程的内核栈大小:体系结构&编译选项。一般为1~2页。
内核栈存放进程的调用链;中断栈:可以不必与内核栈共享空间。
节省栈的资源:减小局部变量、静态分配。因为栈溢出时末端的thread_info可能会溢出。
五、CPU分配
CPU数据放在一个数组中,按照处理器号寻找数组中对应的处理器。
CPU接口:percpu 提供简化创建和操作CPU数据的方法。
定义 DEFINE_PER_CPU(type,name) ; 存取变量 get_cpu_var(name)++禁止抢占; put_cpu_var(name)激活抢占;
· 动态分配:alloc_percpu()
使用每个CPU数据:最小化数据上锁,但需要禁止内核抢占。