mem_init()
原本由bootmem管理的内存在mem_init函数中交由伙伴系统管理。
1.free_unused_memmap_node
相邻的membank间可能存在空洞,但在bootmem阶段这些空洞页也分配了page结构体。该函数的作用是找到这些page结构体所占用的内存并且释放掉。
static void __init free_unused_memmap_node(int node, struct meminfo *mi)
-->unsigned long bank_start; //前一个membank的结束地址
-->unsigned long prev_bank_end ;//后一个membank的起始地址
-->free_memmap(node, prev_bank_end, bank_start);
-->struct page *start_pg = pfn_to_page(prev_bank_end);
-->struct page *end_pg = pfn_to_page(bank_start);
-->unsigned long pg = PAGE_ALIGN(__pa(start_pg));
-->unsigned long pgend = __pa(end_pg) & PAGE_MASK;
-->free_bootmem_node(NODE_DATA(node), pg, pgend - pg);
2.移交bootmem分配剩余的空闲页到伙伴系统
该函数返回的是返回给伙伴系统的空闲页数。
unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
{
register_page_bootmem_info_node(pgdat);
return free_all_bootmem_core(pgdat->bdata);
}
空闲页保存在全局变量totalram_pages中
/*mm/page_alloc.c*/
unsigned long totalram_pages __read_mostly;
totalram_pages += free_all_bootmem_node(pgdat);
2.1该函数的核心是free_all_bootmem_core(pgdat->bdata)
static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
-->__free_pages_bootmem(pfn_to_page(start), order);
-->释放掉bdata->node_bootmem_map所占用的内存,彻底废弃bootmem分配器
释放页到伙伴系统底层调用的两个函数是
void __free_pages(struct page *page, unsigned int order)
#define __free_page(page) __free_pages((page), 0)
可以看到,最终调用的还是__free_pages函数
void __free_pages(struct page *page, unsigned int order)
{
if (put_page_testzero(page)) {
if (order == )
free_hot_page(page);
else
__free_pages_ok(page, order);
}
}
free_hot_page流程如下
free_hot_page(page);
-->free_hot_cold_page(page, );
-->struct zone *zone = page_zone(page);
-->struct per_cpu_pages *pcp = &zone_pcp(zone, get_cpu())->pcp;
-->if (cold)
list_add_tail(&page->lru, &pcp->list);/*冷页插入队列末尾*/
else
list_add(&page->lru, &pcp->list);/*热页插入队列首*/
-->pcp->count++;
-->if (pcp->count >= pcp->high)
-->free_pages_bulk(zone, pcp->batch, &pcp->list, );
-->从队列末尾开始删除pcp->batch个页
-->__free_one_page(page, zone, order);/*把删除的页释放到伙伴系统*/
__free_pages_ok流程如下:
static void __free_pages_ok(struct page *page, unsigned int order)
-->free_one_page(page_zone(page), page, order);
-->__free_one_page(page, zone, order);
可以看出,最终调用相同的底层函数__free_one_page,这个函数的实现可以说是伙伴系统的精髓。
这里注意空闲页加入伙伴系统后要做如下的设置。
set_page_order(page, order);
-->set_page_private(page, order);/*设置page->private*/
-->__SetPageBuddy(page);/*设置page->flags*/
list_add(&page->lru,&zone->free_area[order].free_list[migratetype]);
zone->free_area[order].nr_free++;
mem_init()的更多相关文章
- 内存管理 初始化(四)mem_init bootmem 迁移至伙伴系统
mm_init中执行mem_init,将原通过bootmem分配器管理的低端内存 及 通过meminfo得知的高端内存释放到伙伴系统中,最后bootmem位图本身占用的低端内存物理页也被释放进伙伴系 ...
- MMU工作原理
MMU的工作原理就是把虚拟地址转换成物理地址. 虚拟地址:由编译器和连接器在定位程序时分配. 物理地址:用来访问实际的主存硬件模块. 使用虚拟存储器的系统都使用一种称为分页(paging).虚拟地址空 ...
- MIT 6.828 JOS学习笔记17. Lab 3.1 Part A User Environments
Introduction 在这个实验中,我们将实现操作系统的一些基本功能,来实现用户环境下的进程的正常运行.你将会加强JOS内核的功能,为它增添一些重要的数据结构,用来记录用户进程环境的一些信息:创建 ...
- MIT 6.828 JOS学习笔记16. Lab 2.2
Part 3 Kernel Address Space JOS把32位线性地址虚拟空间划分成两个部分.其中用户环境(进程运行环境)通常占据低地址的那部分,叫用户地址空间.而操作系统内核总是占据高地址的 ...
- MIT 6.828 JOS学习笔记15. Lab 2.1
Lab 2: Memory Management lab2中多出来的几个文件: inc/memlayout.h kern/pmap.c kern/pmap.h kern/kclock.h kern/k ...
- Linux内存管理之bootmem分配器
为什么要使用bootmem分配器,内存管理不是有buddy系统和slab分配器吗?由于在系统初始化的时候需要执行一些内存管理,内存分配的任务,这个时候buddy系统,slab分配器等并没有被初始化好, ...
- Linux0.11内核--内存管理之1.初始化
[版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5597705.html ] Linux内核因为使用了内存分页机制,所以相对来说好理解些.因为内存 ...
- (三)内存 SDRAM 驱动实验 (杨铸 130 页)(勉强能懂个大概)
SDRAM 芯片讲解: 地址: 行地址 (A0-A12) 列地址 (A0-A8) 片选信号(BA0 BA1)(L-BANK)(因为SDRAM有 4片) 两片SDRAM 连线唯一区别在 UDQM ...
- Linux启动过程详述
http://www.ibm.com/developerworks/cn/linux/kernel/startup/index.html Linux启动第1步:引导内核 Linux启动第2步:内核部分 ...
随机推荐
- linux php 安装xdebug
我的环境是PHP 5.2.5,下载的xdebug是Xdebug v2.2.1 源码包 PHP 5.3.20用的是Xdebug v2.1.0 {版本一定要匹配} 下载地址为:http://xdebug ...
- Python3基础(5)常用模块:time、datetime、random、os、sys、shutil、shelve、xml处理、ConfigParser、hashlib、re
---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ 1 ...
- NeatUpload 的使用
1 <httpModules> 2 <add name="UploadHttpModule" type="Brettle.Web.NeatUpload. ...
- 解决Maven依赖下载不全的问题
背景描述 在日常学习过程中使用Maven构建SpringBoot+SpringCloud服务时,有时会使用非正式版的SpringBoot和SpringCloud(非正式版是指不是最终发布的版本,而是测 ...
- 从零开始的全栈工程师——js篇2.14(表单与计时器)
一.表单 Form input select textarea type=”radio/checkbox/password/button/text/submit/reset/” 表单的事件 oncha ...
- js数字滑动时钟
js数字滑动时钟: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- Vue.js(2.x)之计算属性
昨天看完大神的文章后,深感惭愧,硬着头皮继续看官网文档,然而这真的没是没办法,介绍的实在有些敷衍: 1).计算属性:也不说下computed是计算属性关键词,vm实例是可以像代理data一样代理com ...
- python3应用例子01(进度条)
#!/usr/bin/env python# -*- coding:utf-8 -*- import sysimport time def bar(num, total): rate = num / ...
- (转) HTTP Request header
HTTP Request header 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基 ...
- hdu-1556 Color the ball---树状数组+区间修改单点查询
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1556 题目大意: Problem Description N个气球排成一排,从左到右依次编号为1,2 ...