免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1011 | 回复: 0
打印 上一主题 下一主题

ulk_ch8_内存管理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-06 09:52 |只看该作者 |倒序浏览

本章分三部分讲解内核如何给自己分配动态内存dynamic memory。
连续物理内存区(页框管理、内存区管理),非连续内存区(非连续内存区管理)。
主要涉及内容:内存管理区、内核映射、伙伴系统、slab高速缓存和内存池。

RAM的某些部分永久分配给内核,存放内行代码和静态内核数据结构。RAM其余的部分称为动态内存。

1. 页框管理
涉及数据结构:
页描述符struct page、节点描述符、管理区描述符、管理区描述符指针数组zonelist

页框的状态信息保存在类型为page的页描述符中。
所有的页描述符存放在mem_map数组中。
macro:    virt_to_page(addr)         pfn_to_page(pfn)

NUMA中,物理内存被划分为几个节点node。一个单独的节点内,任一给定CPU访问页面所需时间相同。每个节点都有一个类型为pg_data_t的描述符,所有节点的描述符存放在链表pgdat_list中。

UMA模型中,虽然对NUMA的支持没有编译进内核,linux仍然使用节点,不过只有一个节点,它包含了所有的物理内存。80x86中这样处理是为了可移植性。

每个节点的物理内存又可以划分为3个内存管理区zone。
在80x86 UMA体系结构中为:ZONE_DMA     ZONE_NORMAL   ZONE_HIGHMEM

其中,ZONE_DMA和ZONE_NORMAL,通过线性映射到线性地址空间的第4个GB,内核就可以直接访问。
ZONE_HIGHMEM包含的内存页不能由内核直接访问,尽管它们也线性映射到线性空间的第4个GB。
64位体系结构上ZONE_HIGHMEM区总是空的。

每个zone都有自己的管理区描述符,其中
unsigned long free_pages字段是管理区中空闲页的数目,
struct free_area[] free_area字段标识出管理区的空闲页框块(伙伴系统算法)

The Pool of Reserved Page Frames
The Zoned Page Frame Allocator分区页框分配器
图中的管理区分配器(Zone allocator)部分接受动态内存分配和释放的请求。

alloc_pages(gfp_mask, order)                     返回第一个页框描述符地址
alloc_page(gfp_mask)
__get_free_pages(gfp_mask, order)     返回第一个页的线性地址地址
__get_free_page(gfp_mask)
get_zeroed_page(gfp_mask)                返回线性地址
__get_dma_pages(gfp_mask, order)

__free_pages(page, order)                   page指向页描述符
free_pages(addr, order)                       addr为线性地址
__free_page(page)
free_page(addr)

与高端内存的始端(即直接映射的物理内存末端)所对应的线性地址存放在high_memory变量中,该变量被设为896MB。

896MB以上的页框不映射在第4个GB,所以内核不能直接访问。
所以,返回所分配页框线性地址的页分配器函数不适用于高端内存(即不适用于ZONE_HIGHMEM管理区内的页框)。
(两种方法:只能使用alloc_pages()和alloc_page();内核线性地址空间的最后128MB的高端内存映射区)

内核有3种机制将页框映射到高端内存:永久内核映射、临时内核映射、非连续内存分配
page_address_htable散列表
page_address_map

kmap()
kunmap()

enum km_type
kmap_atomic(struct page * page, enum km_type type)
kunmap_atomic()

外碎片external fragmentation
(页框管理,分配一组连续的页框)
buddy system(页框作为基本内存区)

每个管理区使用不同的buddy system。80x86中有3种:DMA、NORMAL、HIGHMEM。
每个buddy system使用的主要数据结构:mem_map数组、free_area数组。
即前边提到的struct free_area[] free_area;11个free_area类型元素的数组,每个元素对应一种块大小。
2. 内存区管理 memory area
内碎片internal fragmentation
(内存区管理,具有连续的物理地址和任意长度的内存单元序列)
分配小内存区如几十字节
slab分配器(同一页框中分配小内存区)
slab分配器模式最早用于SUN的Solaris 2.4 OS中。

高速缓存描述符kmem_cache_t
高速缓存分两种:
普通:只由slab allocator用于自己的目的
专用:由内核其余部分使用

系统初始化时:kmem_cache_init() && kmem_cache_sizes_init()建立普通高速缓存

kmem_cache_create()创建专用高速缓存
kmem_cache_destroy()

slab描述符
Interfacing the Slab Allocator with the Zoned Page Frame Allocator
void * kmem_getpages(kmem_cache_t *cachep, int flags)
void kmem_freepages(kmem_cache_t *cachep, void *addr)

给高速缓存分配、释放slab
cache_grow()
slab_destroy()

对象描述符kmem_bufctl_t
分配、释放slab的对象
kmem_cache_alloc()
kmem_cache_free()

通用对象
void * kmalloc(size_t size, int flags);
void kfree()

内存池memory pool,由mempool_t对象描述

3.      非连续内存区管理
内存区映射到连续的页框:能充分利用告诉缓存
通过连续的线性地址访问非连续的页框:优点能避免外碎片,缺点是必须打乱内核页表(适用于对内存区请求不太频繁的情况)

为活动的交换区分配数据结构、为模块分配空间、为某些I/O驱动程序分配缓冲区。
0xc0000000
非连续内存区线性地址空间:VMALLOC_START          ----         VMALLOC_END
非连续内存区之间插入4KB的安全区。
每个非连续内存区对应着一个vm_struct描述符

其中,flags字段标示了映射的内存类型:
VM_ALLOC          使用vmalloc()得到的页
VM_MAP              使用vmp()映射的已经被分配的页
VM_IOREMAP      使用ioremap()映射的硬件设备的板上内存

get_vm_area()
分配、释放非连续内存区
void * vmalloc(unsigned long size);
void vfree();


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74638/showart_1108932.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP