linux vmalloc 和 其友
我们展示给你的下一个内存分配函数是 vmlloc, 它在虚拟内存空间分配一块连续的内存 区. 尽管这些页在物理内存中不连续 (使用一个单独的对 alloc_page 的调用来获得每个 页), 内核看它们作为一个一个连续的地址范围. vmalloc 返回 0 ( NULL 地址 ) 如果发 生一个错误, 否则, 它返回一个指向一个大小至少为 size 的连续内存区.
我们这里描述 vmalloc 因为它是一个基本的 Linux 内存分配机制. 我们应当注意, 但是, vmalloc 的使用在大部分情况下不鼓励. 从 vmalloc 获得的内存用起来稍微低效些, 并 且, 在某些体系上, 留给 vmalloc 的地址空间的数量相对小. 使用 vmalloc 的代码如果 被提交来包含到内核中可能会受到冷遇. 如果可能, 你应当直接使用单个页而不是试图使 用 vmalloc 来掩饰事情.
让我们看看 vmalloc 如何工作的. 这个函数的原型和它相关的东西(ioremap, 严格地不 是一个分配函数, 在本节后面讨论)是下列:
#include <linux/vmalloc.h>
void *vmalloc(unsigned long size); void vfree(void * addr);
void *ioremap(unsigned long offset, unsigned long size);
void iounmap(void * addr);
NUMA (非统一内存存取) 计算机是多处理器系统, 这里内存对于特定的处理器组("节点")是"局部的". 对局部内
存的存取比存取非局部内存更快. 在这样的系统, 在当前节点分配内存是重要的. 驱动作者通常不必担心 NUMA 问题, 但是.
值得强调的是 kmalloc 和 _get_free_pages 返回的内存地址也是虚拟地址. 它们的实际 值在它用在寻址物理地址前仍然由 MMU (内存管理单元, 常常是 CPU 的一部分)管理.[31]31 vmalloc 在它如何使用硬件上没有不同, 不同是在内核如何进行分配任务上.
kmalloc 和 get_free_pages 使用的(虚拟)地址范围特有一个一对一映射到物理内存, 可能移位一个常量 PAGE_OFFSET 值; 这些函数不需要给这个地址范围修改页表. vmalloc 和 ioremap 使用的地址范围, 另一方面, 是完全地合成的, 并且每个分配建立(虚拟)内 存区域, 通过适当地设置页表.
这个区别可以通过比较分配函数返回的指针来获知. 在一些平台(例如, x86), vmalloc 返回的地址只是远离 kmalloc 使用的地址. 在其他平台上(例如, MIPS, IA-64, 以及 x86_64 ), 它们属于一个完全不同的地址范围. 对 vmalloc 可用的地址在从 VMALLOC_START 到 VAMLLOC_END 的范围中. 2 个符号都定义在 <asm/patable.h> 中.
vmalloc 分配的地址不能用于微处理器之外, 因为它们只在处理器的 MMU 之上才有意义. 当一个驱动需要一个真正的物理地址(例如一个 DMA 地址, 被外设硬件用来驱动系统的总 线), 你无法轻易使用 vmalloc. 调用 vmalloc 的正确时机是当你在为一个大的只存在于 软件中的顺序缓冲分配内存时. 重要的是注意 vamlloc 比 get_free_pages 有更多开 销, 因为它必须获取内存并且建立页表. 因此, 调用 vmalloc 来分配仅仅一页是无意义 的.
在内核中使用 vmalloc 的一个例子函数是 create_module 系统调用, 它使用 vmalloc 为在创建的模块获得空间. 模块的代码和数据之后被拷贝到分配的空间中, 使用 copy_from_user. 在这个方式中, 模块看来是加载到连续的内存. 你可以验证, 同过看
/proc/kallsyms, 模块输出的内核符号位于一个不同于内核自身输出的符号的内存范围.
使用 vmalloc 分配的内存由 vfree 释放, 采用和 kfree 释放由 kmalloc 分配的内存的 相同方式.
如同 vmalloc, ioremap 建立新页表; 不同于 vmalloc, 但是, 它实际上不分配任何内存. ioremap 的返回值是一个特殊的虚拟地址可用来存取特定的物理地址范围; 获得的虚拟地 址应当最终通过调用 iounmap 来释放.
ioremap 对于映射一个 PCI 缓冲的(物理)地址到(虚拟)内核空间是非常有用的. 例如, 它可用来存取一个 PCI 视频设备的帧缓冲; 这样的缓冲常常被映射在高端物理地址, 在 内核启动时建立的页表的地址范围之外. PCI 问题在 12 章有详细解释.
由于可移植性, 值得注意的是你不应当直接存取由 ioremap 返回的地址好像是内存指针. 你应当一直使用 readb 和 其他的在第 9 章介绍的 I/O 函数. 这个要求适用因为一些平 台, 例如 Alpha, 无法直接映射 PCI 内存区到处理器地址空间, 由于在 PCI 规格和 Alpha 处理器之间的在数据如何传送方面的不同.
实际上, 一些体系结构定义"虚拟"地址为保留给寻址物理内存. 当这个发生了,
Linux 内核利用这个特性, 并且
kernel 和 get_free_pages 地址都位于这些地址范围中的一个.
这个区别对设备驱动和其他的不直接包含到内存管理 内核子系统中的代码是透明的.
ioremap
和 vmalloc 是面向页的(它通过修改页表来工作); 结果, 重分配的或者分配的 大小被调整到最近的页边界. ioremap 模拟一个非对齐的映射通过"向下调整"被重映射的
地址以及通过返回第一个被重映射页内的偏移.
vmalloc
的一个小的缺点在于它无法在原子上下文中使用, 因为, 内部地, 它使用 kmalloc(GFP_KERNEL) 来获取页表的存储, 并且因此可能睡眠. 这不应当是一个问题
-- 如果 get_free_page 的使用对于一个中断处理不足够好, 软件设计需要一些清理.
linux vmalloc 和 其友的更多相关文章
- linux vmalloc和kmalloc
kmalloc是内核低端内存的分配,而vmalloc对应内核高端内存的分配.kmalloc()分配的内存处于3GB-high_memory之间,这一段内核空间与物理内存的映射. kmalloc保证分配 ...
- Memory Allocation API In Linux Kernel && Linux Userspace、kmalloc vmalloc Difference、Kernel Large Section Memory Allocation
目录 . 内核态(ring0)内存申请和用户态(ring3)内存申请 . 内核态(ring0)内存申请:kmalloc/kfree.vmalloc/vfree . 用户态(ring3)内存申请:mal ...
- 高端内存映射之vmalloc分配内存中不连续的页--Linux内存管理(十九)
1 内存中不连续的页的分配 根据上文的讲述, 我们知道物理上连续的映射对内核是最好的, 但并不总能成功地使用. 在分配一大块内存时, 可能竭尽全力也无法找到连续的内存块. 在用户空间中这不是问题,因为 ...
- linux内存管理之malloc、vmalloc、kmalloc的区别
kmalloc kzalloc vmalloc malloc 和get_free_page()的区别 一.简述 1. kmalloc申请的是较小的连续的物理内存,虚拟地址上也是连续的.kmalloc和 ...
- Linux设备驱动程序 之 vmalloc
vmalloc()函数的工作方式类似于kmalloc(),只不过在前者分配的内存虚拟地址是连续的,而物理地址则无须连续:这也是用户空间分配函数的工作方式:由malloc()返回的页在进程的虚拟地址空间 ...
- Linux 设备驱动 Edition 3
原文网址:http://oss.org.cn/kernel-book/ldd3/index.html Linux 设备驱动 Edition 3 By Jonathan Corbet, Alessand ...
- linux系统内核流转浅析
SJTUBEAR 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 我们通过简单 ...
- 《Linux及安全》期中总结&《Linux内核分析》期终总结
[5216 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK NINE ...
- linux 使用/proc文件系统 实现用户空间与内核模块之间通信
项目中可能会用到用户态和内核模块之间进行通信的功能.想到linux系统本身很多通信都是通过/proc文件系统来的,比如修改网络中连接跟踪表连接数限制/proc/sys/net/netfilter/nf ...
随机推荐
- 遗传算法MATLAB实现(1):工具箱下载及安装
到官网下载谢菲尔德大学的GA工具箱:http://codem.group.shef.ac.uk/index.php/ga-toolbox(其实蛮不懂为什么有人把这个传到某个网上还需要积分才能下载,人家 ...
- Directx11教程(57) 环境映射
原文:Directx11教程(57) 环境映射 建好skydome后,如果我们想让其中的某个物体,比如那个球体来映射出周围环境的蓝天白云(不包括自己附近的物体),该怎么做呢?此时可以把这个 ...
- Directx11教程(13) D3D11管线(1)
原文:Directx11教程(13) D3D11管线(1) 从本篇教程开始,我们暂停代码的学习,先来了解一下D3D11的管线,这些管线不涉及具体的硬件,而是着重于理解能够支持D3D11的管 ...
- iOS 9开发小技巧
http://www.cocoachina.com/ios/20151217/14733.html 前言 "小黄鸭"法不仅适用于debug,也适用于学习新知识.表达是最好的吸收.本 ...
- 洛谷 P2568 GCD(莫比乌斯反演)
题意:$\sum_{i=1}^{n}\sum_{j=1}^{n}[gcd(i,j)\epsilon prime]$. 对于这类题一般就是枚举gcd,可得: =$\sum_{d\epsilon prim ...
- python世界里的局部变量和全局变量: 潜规则太重要了!!!
python世界里的局部变量和全局变量: 潜规则太重要了!!! 先上代码: def fun(): def test_global(): ''' 内层和外层都需要声明为global, 才能彻底打通变量名 ...
- HDU 5584 LCM Walk【搜索】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5584 题意: 分析: 这题比赛的时候卡了很久,一直在用数论的方法解决. 其实从终点往前推就可以发现, ...
- iOS iOS8注册通知
http://blog.csdn.net/apple_app/article/details/39228221 极光推送 action设置 http://docs.jpush.cn/display/d ...
- Vue.js 第2章 钩子函数&自定义指令&过滤器&计算属性&侦听器
目标 钩子函数 自定义指令 自定义过滤器 计算属性 监听属性 局部自定义指令 为什么需要自定义指令 为了复用,为了代码的灵活 指令的分类:全局指令,局部指令 在vm外面创建的指令 通过Vue.dire ...
- Pytorch - GPU ID 指定 pytorch gpu 指定
PyTorch 关于多 GPUs 时的指定使用特定 GPU. PyTorch 中的 Tensor,Variable 和 nn.Module(如 loss,layer和容器 Sequential) 等可 ...