linux内核内存分配(一、基本概念)
内存分配是Linux比较复杂也是比较重要的部分,这个和ssd驱动很类似:物理地址和虚拟地址的映射关系。下面总结下最近看到的有关内存分配的内容和自己的理解;
1、一致内存访问和非一致内存访问
上图来自《深入linux设备驱动程序内核机制》
简单的说明下,UMA(一致内存访问 uniform memory access)可以很好的看到所有cpu访问内存的距离都是一样的(其实就是通过总线到内存的速度和距离都是一样的)所以就叫一致内存访问;
很显然右边的NUMA就是非一致内存访问,内存节点0是CPU0的本地内存(虽然其他CPU也可以访问,但是没有CPU0的速度高),所以这样各个CPU访问内存节点都会首先选择本地内存节点,然后再考虑其他内存节点;
2、物理内存和虚拟地址
上图来自《深入linux设备驱动程序内核机制》
首先大概的可以看出左边的mem_map数组中存放的是page结构体元素,中间的是实际的物理内存,右边的是虚拟的地址范围;
他们之间的关系大概是这样的,mem_map数组中的元素和物理内存页联系,page指针指向中间的物理内存中的某个物理页,这个关系是为了系统方便管理内存;
而物理内存页和右边的虚拟地址范围映射,这个是为了操作物理内存,一般右边的虚拟地址由cpu使用(软件上使用的也是虚拟地址,不过该地址最终还是CPU使用)。CPU和MMU之间使用的都是虚拟地址,出了MMU后就转换为实际的物理内存地址,一般有两个地方使用:1、总线上;2、物理内存(可以理解为内存条上);
这里类比下SSD驱动的原理:FTL数组中存放的是pba(lun、block、page、offset),而数组下标为lba,pba是SSD上的实际物理地址,lba则是上层软件使用的逻辑地址;他们通过FTL数组来映射,这样就可以通过修改数组中的pba来实现SSD像硬盘那样覆盖写等硬盘的特有性能;
回到内存分配上,从上面的图中应该可以看出物理内存分为三大区域:ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM;mem_map数组和物理内存页全部一一映射,也会形成三大区域;而在系统初始化期间,会把物理内存区域中ZONE_DMA和ZONE_NORMAL分别和右边的虚拟地址“物理页面直接映射区”(这个虚拟地址区域名称有点怪,其实就是内核地址的0~896M地址范围)建立线性映射,这样就会建立相应的页目录和页表;如果对右边这个虚拟地址范围分配有疑问的可以看看:http://blog.csdn.net/yuzhihui_no1/article/details/46982231,不过这些都是在32位的系统中的,在64位系统中可以说完全不一样,不过有这个概念会好点;
这时候,如果在内核内存ZONE_DMA和ZONE_NORMAL区域分配,则可以直接返回虚拟地址(0~896M)这个虚拟地址的界限不是固定的;如果需要在物理内存ZONE_HIGHMEM分配时,则要复杂些了;简单的步骤为:1、在物理内存ZONE_HIGHMEM中查找一个空闲页;2、在右边的虚拟地址中的动态映射区或固定映射区分配一个虚拟地址;3、建立页目录和页表,使物理页和虚拟地址映射起来;
3、物理页分配接口函数
首先是:alloc_pages(gfp_mask, order)宏,(是不是很奇怪没有先写kmalloc、vmalloc,那是因为他们俩比较复杂,也比较重要,当然最主要的是他们不是分配物理页。后面要用很大的篇幅来分析他们俩);参数 gfp_mask是一个掩码参数,用来控制分配行为(哪个区域分配、是否阻塞分配等);order是表示分配2的order次方个物理页面;
alloc_pages(gfp_mask, order); 调用 alloc_pages_node(); 调用 __alloc_pages();说到底最后工作的还是__alloc_pages(),alloc_pages()和__alloc_pages()都可以分配来自ZONE_HIGHMEM区域的物理页,主要看gfp_mask指定的分配区域; 注意alloc_pages()是宏不是函数;
__get_free_pages(gfp_mask, order);这个分配函数首先是判断gfp_mask,如果指定为ZONE_HIGHMEM分配区域,则失败退出;否则,就调用alloc_pages()函数;由此看出__get_free_pages()函数只能分配ZONE_DMA和ZONE_NORMAL区域的物理页,也就是说不需要修改页表;
简单的分配物理页接口函数就这两个,其他的都是些变种,根据gfp_mask,和order来实现的变种函数;
注意:这是分配多个的连续的物理页的函数接口,kmalloc、vmalloc函数分配的不一定是整个页大小的内存;
转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/47284329
如果讲解的不正确,欢迎指正,谢谢!!
linux内核内存分配(一、基本概念)的更多相关文章
- linux内核内存分配(三、虚拟内存管理)
在分析虚拟内存管理前要先看下linux内核内存的具体分配我開始就是困在这个地方.对内核内存的分类不是非常清晰.我摘录当中的一段: 内核内存地址 ============================ ...
- LINUX内核内存屏障
================= LINUX内核内存屏障 ================= By ...
- linux内核--内存管理(二)
一.进程与内存 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内 ...
- Linux内核-内存回收逻辑和算法(LRU)
Linux内核内存回收逻辑和算法(LRU) LRU 链表 在 Linux 中,操作系统对 LRU 的实现主要是基于一对双向链表:active 链表和 inactive 链表,这两个链表是 Linux ...
- Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo
slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ...
- 模拟linux的内存分配与回收
模拟linux的内存分配与回收 要求 通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码. 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣. (1)掌握内存分配FF,BF ...
- 【转】Linux内核中分配4M以上大内存的方法
在Linux内核中, kmalloc能够分配的最大连续内存为2的(MAX_ORDER-1)次方个page(参见alloc_pages函数, "if (unlikely(order & ...
- linux环境内存分配原理 mallocinfo
Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...
- linux内核内存管理(zone_dma zone_normal zone_highmem)
Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...
随机推荐
- ZOJ - 3483 - Gaussian Prime
先上题目: Gaussian Prime Time Limit: 3 Seconds Memory Limit: 65536 KB In number theory, a Gaussian ...
- Atomic operations on the x86 processors
On the Intel type of x86 processors including AMD, increasingly there are more CPU cores or processo ...
- nginx 、tomcat 集群配置、shiro Session 共享
一.nginx.config 配置 #user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error. ...
- Ajax json 数据格式
ajax : 是么是同步 什么事异步 同步现象:客户端发送请求到服务端,当服务端返回响应之前,客户端都处于等待卡死状态. 异步现象:客户端发送请求到服务器端,无论服务器是否返回,客户端都可以随意做其他 ...
- MEAN框架学习笔记
MEAN框架学习笔记 MEAN开发框架的资料非常少.基本的资料还是来自于learn.mean.io站点上的介绍. 于是抱着一种零基础学习的心态,在了解的过程中,通过翻译加上理解将MEAN框架一点点消化 ...
- Android布局文件经验
1.父控件中含有多个子控件时.往往遵循长子优先的原则,即长子假设非常大可能占满父空间.使次子们出局: 2.如果TableLayout有2行,当中一行未设定列间长度比例.而还有一行设定了,则未设定行可能 ...
- vmware mac 分辨率设置
1.安装vmware tool 2.关闭虚拟机,在设置中找到显示器项 3.选中“加速3D图形” 4.在监视器中,选中 指定监视器设置,使用任意分辨率 5.如果没有可用分辨率,手动输入,例如 1680* ...
- DotNetBar.Bar菜单的使用
DotNetBar.Bar菜单的使用 老帅 在C#中使用控件DevComponents.DotNetBar.Bar时,怎样设计菜单呢? 1.拖放生成一个菜单容器 拖放一个D ...
- [POJ 3345] Bribing FIPA
[题目链接] http://poj.org/problem?id=3345 [算法] 树形背包 [代码] #include <algorithm> #include <bitset& ...
- BZOJ 4262 线段树+期望
思路: 把询问离线下来,查询max和查询min相似,现在只考虑查询max 令sum[l,r,x]表示l到r内的数为左端点,x为右端点的区间询问的答案 那么询问就是sun[l1,r1,r2]-sum[l ...