vmalloc与mmap
mmap()系统调用是在用户进程与内核之间共享内存区域的常用方法。我们最近有个程序,需要应用进程能够读取内核驱动获取的数据,经过简单的调研,决定采用mmap方式。实现起来不难,在驱动中注册一个字符设备,实现该设备的mmap()方法即可。但这其中有一点小曲折。
在实现设备的mmap()方法时,需要将物理内存映射到应用程序通过mmap()系统调用传下来的vma中。vma代表的是进程的一段虚拟地址空间。在第一版里,考虑的不全面,利用alloc_pages()将整个内存段申请为一段连续的物理地址空间。然后通过remap_pfn_range()函数将这段连续的物理内存映射到vma中。经过长时间的测试,没有发现问题。直到今天,在部署一个老集群时,遇到了问题。这个集群中有很多老机器,内存只有十多个G,而且长时间运行后产生了大量的内存碎片。从而导致,我们无法获得足够的连续物理内存。没办法,只好重新调整驱动中分配内存的方式,改用vmalloc获取地址空间。
在kernel里,通常有3种申请内存的方式:vmalloc, kmalloc, alloc_pages。kmalloc与alloc_pages类似,均是申请连续的地址空间。而vmalloc则可以申请一段不连续的物理地址空间,并将其映射到连续的线性地址上。每次vmalloc之后,内核会创建一个vm_struct,用以映射分配到的不连续的内存区域。vm_struct类似vma,但是又不是一回事。vma是将物理内存映射到进程的虚拟地址空间。而vm_struct是将物理内存映射到内核的线性地址空间。
既然vmalloc拿到的不是连续的物理内存,那么将这些内存映射到vma时,就不能直接利用remap_pfn_range()了。
此时可以采用两种方法,一种是实现vm_operations_struct的fault()方法,用以在缺页时再映射需要的页。此方法操作起来较为麻烦。
另一种方法是直接使用remap_vmalloc_range()函数。该函数的原型为:
int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
unsigned long pgoff)
其中参数vma是mmap使用调用传下来的,addr即为vmalloc()所分配内存的起始地址。而pgoff则为mmap()系统调用里的偏移参数,可以通过vma->vm_pgoff获得。该函数成功执行后,返回值为0。如果返回值为负数,则说明出错了。通常是由于所传的参数不正确。
需要注意的是,需要映射到用户空间的内存段,不能直接利用vmalloc()分配,而应该使用vmalloc_user()函数。该函数除了分配内存之外,还会将相应的vm_struct结构标记为VM_USERMAP。否则,remap_vmalloc_range将返回错误。
在这个项目中碰到的教训是,永远不要假设系统中一定会有超过一个页的连续物理内存。
不过较新的内核具有compact机制,可以整理内存碎片。但是,目前至少有一大部分机器不支持,或未开启此机制。
vmalloc与mmap相关推荐
- linux精华文章汇总
这里总结下linux相关的一些技术文章,涉及内存,进程,驱动,调试调优等方面,为了方便读者的查阅,后续会持续更新. linux 内存管理 告别"一页障目" Linux的内存初始化 ...
- Linux - 内存管理
引用文章 Linux阅马场 初探Linux内核态--通过proc文件系统作快速问题定位 linux通过meminfo 与 slab 定位内存泄漏 曾文斌: /proc/meminfo之谜完全揭秘 vm ...
- Linux内存管理基础
系统启动之Linux内存管理基础 Keywords 非一致内存访问(NUMA)模型.节点(node).内存管理区(Zone).一致内存访问(UMA)模型.内核页表.内存管理区分配器(伙伴系统Buddy ...
- kmalloc,vmalloc,malloc,mmap
kmalloc cat /proc/slabinfo kmalloc也是基于slab机制,按照2^order创建对个slab描述符.在系统启动时通过函数 create_kmalloc_caches进行 ...
- 【Linux 内核 内存管理】内存管理架构 ④ ( 内存分配系统调用过程 | 用户层 malloc free | 系统调用层 brk mmap | 内核层 kmalloc | 内存管理流程 )
文章目录 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) 二.内存管理流程 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) " 堆内存 " ...
- ioremap 与 mmap【转】
转自:http://blog.csdn.net/junllee/article/details/7415732 内存映射 对于提供了MMU(存储管理器,辅助操作系统进行内存管理,提供虚实地址转换等硬件 ...
- 内存映射MMAP和DMA【转】
转自:http://blog.csdn.net/zhoudengqing/article/details/41654293 版权声明:本文为博主原创文章,未经博主允许不得转载. 这一章介绍Linux内 ...
- Linux内存管理和分析vmalloc使用的地址范围
From: http://www.cnblogs.com/dubingsky/archive/2010/04/20/1716158.html Vmalloc可以获得的地址在VMALLOC_START到 ...
- 内核空间:kmalloc vmalloc 用户空间:malloc ptmalloc
一.地址映射流程 二.内核空间 在内核空间,通过malloc类似的两个系统调用来进行内存的分配,它们分别是kmalloc和vmalloc 1.kmalloc kmalloc用于为内核空间的直接内存映 ...
- linux mmap 函数详解,Linux之mmap函数简介
本文主要讲述mmap 函数的使用,与驱动中 mmap 函数的实现 mmap 怎么使用,怎么实现,为什么 mmap 可以减少额外的拷贝? 下面简单详情. 一. mmap 的使用#include void ...
最新文章
- SAP Classification(物料特性)
- Android应用与系统安全防御
- 项目移植,项目环境问题
- 一款简约多类PHP导航源码
- __attribute__((visibility()))
- 将xml转为txt_HZ文章转短视频工具v1.0 快速将文章转为短视频 自动配音 配字幕 配图...
- Razor语法(三)
- JavaScript事件---事件入门
- 基础集合论笔记 目录
- 《英语语法新思维 基础版1》读书笔记(二)
- 能上QQ不能上浏览器处理方法(win11版)
- 腾讯云轻量应用服务器免费升级2核4G8M升级4核4G8M不花钱
- Gitter---高颜值GitHub小程序客户端诞生记,2021年安卓社招面试题精选
- 查询失败,后台服务器运行错误,添加网络打印机错误?怎么处理?Windows 无法连接到打印机。 服务器打印后台处理程序服务没有运行。...
- ios11修改微信步数_你会时常去看他的微信步数吗?
- python之路--生成器
- IDEA代码以及注释格式化,行宽设置,以及自动换行
- 非期望产出的sbm模型_兼顾非期望产出的工业用地效率测度、分异与溯因 ——以东北三省为例...
- 解决win10系统下Elasticsearch闪退问题
- 蓝牙怎么区分单模和双模_蓝牙中的单模、双模是什么,它们有何不同