get_free_page

如果模块需要分配大块的内存,使用面向页的分配会有很多优点;

分配页面可使用下面的函数:

 unsigned long get_zeroed_page(gfp_t gfp_mask)

返回指向新页面的指针并将页面清零;

 unsigned long __get_free_page(gfp_t gfp)

返回指向新页面的指针,不清零页面;

 unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

分配若干(物理连续的)页面,并返回指向该内存区域第一个字节的指针,不清零页面;其中order是要分配的页面数以2为底的对数,例如,0表示一个页面,3表示8个页面;get_order函数使用一个整数参数,可根据宿主平台的大小返回order值,可允许的最大的order值是10或者11(对应于1024或者2048个页),这依赖于体系结构;

当程序不需要使用页面时,可以使用下面的函数之一来释放它们;

 void free_page(unsigned long addr)

 void free_pages(unsigned long addr, unsigned int order)

如果试图释放和先前分配数目不等的页面,内存映射关系就会被破坏,随后系统就会出错;

只要符合和kmalloc同样的规则,get_free_pages和其他函数都可以在任何时间调用;某些情况下函数会分配内存失败,特别是子啊使用了GFP_ATOMIC的时候,因此必须在分配出错时提供相应的处理;

尽管kmalloc(GFP_KERNEL)在没有空闲内存时有时会失败,但内核会尽可能满足这个内存分配请求;因此,分配太多的内存,系统响应性能就很容易下来;系统为满足kmalloc分配请求而试图换出尽可能多的内存页时,就会变慢;甚至无法为解决这个问题而生成新的进程;

基于页的分配策略的优点实际不在速度上,而在于更有效的使用内存;按页分配不会浪费内存空间,而kmalloc函数则会因分配力度的原因而浪费一定数量的内存;并且当分配的页面完全属于我们自己时,可以通过适当的调整页表把它们合并成一个线性区域,例如允许用户进程对这些单一互不相关的内存区域进行mmap;

alloc_pages

struct page是内核用来描述单个内存页的数据结构;内核在很多地方使用page结构,尤其是在需要高端内存(高端内存在内核空间没有对应不变的地址)的地方;

Linux页分配器的核心代码称为alloc_pages_node函数;

 struct page *alloc_pages_node(int nid, gfp_t gfp_mask,
unsigned int order)

这个函数具有两个变种,大多数情况下我们使用这两个宏;

 #define alloc_pages(gfp_mask, order)
#define alloc_page(gfp_mask)

alloc_pages_node要求传入三个参数,nid是NUMA节点的ID号,表示要在其中分配内存,mask是通常的GFP_分配标志,order是要分配的内存大小;该函数的返回值指向一个page结构(可能返回多个页)的指针,它描述了已分配的内存;或者而在失败时返回NULL;

alloc_pages通过在当前的NUMA节点上分配内存而简化了alloc_pages_node函数,它将numa_node_id的返回值nid参数而调用了alloc_pages_node函数,另外,alloc_page函数显然忽略了order参数而只分配单个页面;

为了释放通过上述途径分配的页面,我们应该使用下面的函数:

 #define __free_page(page) __free_pages((page), 0)
void __free_pages(struct page *page, unsigned int order)
void free_hot_cold_page(struct page *page, bool cold)

在知道某个页面的内容是否在处理器告诉缓存中时,则应该使用free_hot_cold_page来和内核通信,这个信息可以帮助内存分配器优化内存使用;

Linux设备驱动程序 之 get_free_page的更多相关文章

  1. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  2. linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

    原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...

  3. 【转】linux设备驱动程序中的阻塞机制

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...

  4. Linux设备驱动程序 第三版 读书笔记(一)

    Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...

  5. 教你写Linux设备驱动程序:一个简短的教程

    教你写Linux设备驱动程序:一个简短的教程 http://blog.chinaunix.net/uid-20799298-id-99675.html

  6. linux设备驱动程序_hello word 模块编译各种问题集锦

    在看楼经典书籍<linux设备驱动程序>后,第一个程序就是编写一个hello word 模块. 原以为非常easy,真正弄起来,发现问题不少啊.前两天编过一次,因为没有记录,今天看的时候又 ...

  7. Linux设备驱动程序学习----1.设备驱动程序简介

    设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介   Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...

  8. Linux设备驱动程序学习----2.内核模块与应用程序的对比

    内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...

  9. Linux设备驱动程序学习----3.模块的编译和装载

    模块的编译和装载 更多内容请参考Linux设备驱动程序学习----目录 1. 设置测试系统 第1步,要先从kernel.org的镜像网站上获取一个主线内核,并安装到自己的系统中,因为学习驱动程序的编写 ...

随机推荐

  1. A*算法与8数字谜题(参见《算法》P226习题2.5.32)

    A*算法的目的是找到一条从起始状态到最终状态的最短路径. 在A*算法中,需要在每个点计算启发函数:f(S) = g(S) + h(S),其中g(S)是从起点到S点的距离,h(S)是对从S点到终点的最短 ...

  2. 安装mysql时出现 mysql Install/Remove of the Service Denied! 错误的解决办法

    用cmd在mysql的bin目录下面执行: mysqld --install 命令,出现错误: mysql Install/Remove of the Service Denied! 解决方法:以管理 ...

  3. Element-ui-Basic

    一.Layout 布局 1.基础布局 <el-row> <el-col :span="24"><div class="grid-conten ...

  4. 嵌套的页面——自适应高度与跨越操作DOM

    <div id="myIframeId"> <iframe ref="myIframe" name="odpIframeName&q ...

  5. yml格式的在线转换工具

    工具1: https://www.toolfk.com/tool-format-yaml 工具2: https://www.toyaml.com/index.html https://www.cnbl ...

  6. hashCode 及hashcode与equals的区别

    1.hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值 详细了解请 参考 [1]  public int hashCode()返回该对象的哈希码值.支持此方法是为了提高哈 ...

  7. Python处理异常

    异常操作: 1.错误的定义和特征 什么是错误:错误是由于逻辑和语法等导致一个程序无法正常执行的问题 错误的特征:有些错误无法预知 2.异常的定义 异常是程序错误时表示的一种状态 异常发生时,程序不会再 ...

  8. springmvc模式下的上传和下载

    接触了springmvc模式后,对上一次的上传与下载进行优化, 上次请看这里. 此处上传的功能依旧是采用表格上传.文件格式依旧是 <form action="${pageContext ...

  9. js面向对象篇(一)

    Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类). ----摘 ...

  10. spark not serializable异常分析及解决方案

    转载自: http://bigdataer.net/?p=569 1.背景 在使用spark开发分布式数据计算作业过程中或多或少会遇到如下的错误: Serialization stack: objec ...