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. springboot启动流程(十二)springboot事务自动配置

    所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 在上一篇文章中,我们简单了解了aop的处理过程.代理增强之前,先生成Advisor,然后 ...

  2. KVM之配置桥接网卡

    配置桥接网卡 添加桥接网卡br0,注释掉已有的eth0配置 [root@ubuntu01 ~]# vi /etc/network/interfaces # This file describes th ...

  3. Computer Vision_33_SIFT:SAR-SIFT: A SIFT-LIKE ALGORITHM FOR SAR IMAGES——2015

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  4. DAY2新手选品原则及供应商选择

    一.新手选品原则(主要是为了起量) 1.净利润率高(容易起量) 2.发货方便,售后方便(发货,打包方便,不易破损,退货率低) 3.具有细分市场优势(衣服->古代衣服,论文排版) 4.市场规模够大 ...

  5. 《形式化分析工具Scyther性能研究》------摘抄整理

    本篇论文的主要创新点在--------使用 Scyther工具发现对部分 KCI攻击搜索出现漏报的现象,并给出了存在的原因, 介绍了 形式化分析工具   AVispa全称是   Automated V ...

  6. Liunx-tail命令

    1. 实时刷新tail -f /var/log/messages 2. 实时刷新最新500条log tail -500f  /var/log/messages 3. tail -n 20 catali ...

  7. JAVA连接Derby数据库

    其实,JAVA连接Derby数据库也很简单,和一般的数据库操作一样:1.加载驱动2.获取连接3.进行数据库操作4.记得关闭连接 示例如下: import java.sql.ResultSet; imp ...

  8. Red Hat Enterprise Linux 7.0

    简介 Red Hat Enterprise Linux是Red Hat公司的Linux发行版,面向商业市场,包括大型机.红帽公司从Red Hat Enterprise Linux 5开始对企业版LIN ...

  9. linux bash环境变量简单总结

    来源链接:http://www.178linux.com/8005 原创文章,如有转载,请注明原文地址 一.环境变量简介 Linux是一个多用户的操作系统.每个用户登录系统后,都会有一个专用的运行环境 ...

  10. Docker常用命令行

    原文出处:https://blog.csdn.net/qq_29303759/article/details/87639016 启动docker 启动docker systemctl start do ...