linux内核设计与实现读书笔记——内存管理

一、页

内存管理的基本单位:页。

内核中用struct page表示物理页,位于,属性包括flag页状态、count页的引用计数,virtual页虚拟地址。目的在于描述物理内存本身而非其中的数据。

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),。用在高端内存中为永久映射,解出 kunmap

临时映射: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数据:最小化数据上锁,但需要禁止内核抢占。

你可能感兴趣的:(linux)