当前位置:文档之家› chp12 操作系统复习讲义

chp12 操作系统复习讲义

例:
struct felis *ptr; ptr = kmalloc(sizeof(struct felis),
GFP_KERNEL); if (ptr == NULL)
/* Handle error */
gfp_mask标志
Action修饰符
__GFP_WAIT: 分配器可以睡眠 __GFP_HIGH: 分配器可以访问紧急事件缓冲池. __GFP_IO: 分配器可以启动磁盘I/O. __GFP_FS: 分配器能够启动文件系统I/O. __GFP_REPEAT: 失败时重新分配. __GFP_NOFAIL: 失败时一直重新分配,直到成功. __GFP_NORETRY: 分配器不重试.
kfree()
void kfree(const void *ptr)
释放由kmalloc()分配的内存. 每次kmalloc()只能有一次.
例如:
char *buf; buf = kmalloc(BUF_SZ, GFP_KERNEL); if (buf == NULL)
/* deal with error */ /* Do something with buf */ kfree(buf);

区反映了硬件的限制
内存的哪一部分可由DMA访问?
物理地址空间 > 虚地址空间?
i386 体系结构中的Linux区 :

描述
ZONE_DMA
可用于DMA操作的页
ZONE_NORMAL 可用于正常映射
ZONE_HIGHMEM 动态映射的页
物理地址 0-16M 16-896M >896M
分配页
struct page *alloc_pages(mask, order)
alloc_pages().
默认
kmalloc()
不需要连续的页.
vmalloc()
内存管理
ห้องสมุดไป่ตู้
主要内容
1. 物理内存 2. 分配内存 3. Slab分配器
物理页
MMU以页为单位管理内存
32位: 4K 64位:8K
每一个物理页有一个struct page
flags: 脏,加锁等. count: 使用计数,通过page_count()访问 virtual: 虚地址
mem_map数组 相当于物理内 存的一个缩影
分配2order 个连续物理页. 返回一个指针,指向第1个页的page struct,错误时返回
NULL. 转为逻辑地址: page_address(struct page *page)
如果不用page struct,可使用下面函数
__get_free_pages:仅仅返回逻辑地址 alloc_page: 仅分配一页 __get_free_page: 得到一页的逻辑地址 get_zeroed_page: 同上,但清除页的内容.
释放页
• void __free_pages(struct page *page, unsigned int order)
• void freepages(unsigned long addr, unsigned int order)
• void free_page(unsigned int order)
Slab分配器组织
每种对象类型有一个cache. Cache包含一个或多个slab. Slab可能会占有一个或多个连续的内存页.
Slab状态
Full
没有自由的对象.
Partial
部分自由. 从这里分配.
Empty
含有未分配的对象
Slab 算法
1. 为特定的对象类型选择合适的cache.
– 减少了内部碎片.
外碎片
问题
自由的页框分散于整个内存. 如何分配大块的连续页框内存?
解决方法
跟踪连续的页框块,避免将大块连续的页框块变 小.
Zone 分配器
伙伴系统
• 维护11个自由页框链表
– 每个链表包含一组2n 个页框, n=0..10
• 分配k个页框的分配算法
– 从第k个链表分配. – 如果第k个链表不可用,将第(k+1)个链表中的
vmalloc()
void *vmalloc(unsigned long size) 分配虚拟连续的内存. 物理上可能连续也可能不连续. 只有硬件设备需要物理连续.
Slab分配器
一种策略,用于缓存内核对象. Object: 经常使用的数据结构,例如inode Cache: 存储某种类型的对象. Slab: 包含有缓存的对象.
一个一分为二,分配一个,将另一个放在第k个 链表.
• 释放算法大小为 k个页框的块
– 找到其伙伴. – 如果连续则将其合并,放入第k+1个链表;否
则放入第k个链表.
kmalloc()
void *kmalloc(size_t size, int flags)
以字节为单位,而不是页. 返回指向分配的内存的指针. 错误时,返回NULL.
mem_map[]
page0 page1 page2 page3 page4 page5 page6
.....
每个物理页框,使用一个struct page表示,它们组织在mem_map数组中
.........
physical memory
struct page
• struct page {
page_flag_t flags;//页的状态;脏,锁定等 atomic_t _count; //引用计数 atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual;//页的虚地址 }
2. 从cache中的第一个部分满的slab分配对 象.
– 减少了页的分配和释放.
3. 如果没有部分满的slab, 从空的slab分配. 4. 如果没有空的slab,给cache分配新的
slab.
使用哪种方法分配
频繁分配和释放.
Slab分配器.
需要以页为单位分配内存.
alloc_pages()
从高端内存分配.
Zone修饰符
__GFP_DMA __GFP_HIGHMEM
gfp_mask类型标志
行为修饰符与区修饰符的组合 GFP_ATOMIC: 不能睡眠时使用. GFP_NOIO: 可以阻塞,但不启动io. GFP_NOFS: 用于文件系统中的部分代码. GFP_KERNEL:常规分配,可能阻塞.首选 GFP_USER: 常规分配,可能阻塞. GFP_HIGHUSER: 从高端内存分配,可能阻塞. GFP_DMA: 从DMA区分配.
相关主题