内存分配是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内核内存分配(一、基本概念)的更多相关文章

  1. linux内核内存分配(三、虚拟内存管理)

    在分析虚拟内存管理前要先看下linux内核内存的具体分配我開始就是困在这个地方.对内核内存的分类不是非常清晰.我摘录当中的一段: 内核内存地址 ============================ ...

  2. LINUX内核内存屏障

    =================                          LINUX内核内存屏障                          ================= By ...

  3. linux内核--内存管理(二)

    一.进程与内存     所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内 ...

  4. Linux内核-内存回收逻辑和算法(LRU)

    Linux内核内存回收逻辑和算法(LRU) LRU 链表 在 Linux 中,操作系统对 LRU 的实现主要是基于一对双向链表:active 链表和 inactive 链表,这两个链表是 Linux ...

  5. Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo

    slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ...

  6. 模拟linux的内存分配与回收

    模拟linux的内存分配与回收 要求 通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码. 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣. (1)掌握内存分配FF,BF ...

  7. 【转】Linux内核中分配4M以上大内存的方法

    在Linux内核中, kmalloc能够分配的最大连续内存为2的(MAX_ORDER-1)次方个page(参见alloc_pages函数,     "if (unlikely(order & ...

  8. linux环境内存分配原理 mallocinfo

    Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...

  9. linux内核内存管理(zone_dma zone_normal zone_highmem)

    Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...

随机推荐

  1. ZOJ - 3483 - Gaussian Prime

    先上题目: Gaussian Prime Time Limit: 3 Seconds      Memory Limit: 65536 KB In number theory, a Gaussian ...

  2. Atomic operations on the x86 processors

    On the Intel type of x86 processors including AMD, increasingly there are more CPU cores or processo ...

  3. nginx 、tomcat 集群配置、shiro Session 共享

    一.nginx.config 配置 #user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error. ...

  4. Ajax json 数据格式

    ajax : 是么是同步 什么事异步 同步现象:客户端发送请求到服务端,当服务端返回响应之前,客户端都处于等待卡死状态. 异步现象:客户端发送请求到服务器端,无论服务器是否返回,客户端都可以随意做其他 ...

  5. MEAN框架学习笔记

    MEAN框架学习笔记 MEAN开发框架的资料非常少.基本的资料还是来自于learn.mean.io站点上的介绍. 于是抱着一种零基础学习的心态,在了解的过程中,通过翻译加上理解将MEAN框架一点点消化 ...

  6. Android布局文件经验

    1.父控件中含有多个子控件时.往往遵循长子优先的原则,即长子假设非常大可能占满父空间.使次子们出局: 2.如果TableLayout有2行,当中一行未设定列间长度比例.而还有一行设定了,则未设定行可能 ...

  7. vmware mac 分辨率设置

    1.安装vmware tool 2.关闭虚拟机,在设置中找到显示器项 3.选中“加速3D图形” 4.在监视器中,选中 指定监视器设置,使用任意分辨率 5.如果没有可用分辨率,手动输入,例如 1680* ...

  8. DotNetBar.Bar菜单的使用

    DotNetBar.Bar菜单的使用 老帅     在C#中使用控件DevComponents.DotNetBar.Bar时,怎样设计菜单呢?      1.拖放生成一个菜单容器      拖放一个D ...

  9. [POJ 3345] Bribing FIPA

    [题目链接] http://poj.org/problem?id=3345 [算法] 树形背包 [代码] #include <algorithm> #include <bitset& ...

  10. BZOJ 4262 线段树+期望

    思路: 把询问离线下来,查询max和查询min相似,现在只考虑查询max 令sum[l,r,x]表示l到r内的数为左端点,x为右端点的区间询问的答案 那么询问就是sun[l1,r1,r2]-sum[l ...