linux scull 的内存使用
在介绍读写操作前, 我们最好看看如何以及为什么 scull 进行内存分配. "如何"是需要全 面理解代码, "为什么"演示了驱动编写者需要做的选择, 尽管 scull 明确地不是典型设备.
本节只处理 scull 中的内存分配策略, 不展示给你编写真正驱动需要的硬件管理技能.
其他风味的设备由不同的函数关闭, 因为 scull_open 为每个设备替换了不同的 filp->f_op. 我们在介绍每种风
味时再讨论它们.
scull 使用的内存区, 也称为一个设备, 长度可变. 你写的越多, 它增长越多; 通过使用 一个短文件覆盖设备来进行修整.
scull 驱动引入 2 个核心函数来管理 Linux 内核中的内存. 这些函数,
定义在
<linux/slab.h>, 是:
void
*kmalloc(size_t size, int flags); void kfree(void *ptr);
对 kmalloc 的调用试图分配 size 字节的内存; 返回值是指向那个内存的指针或者如果分 配失败为 NULL. flags 参数用来描述内存应当如何分配; 我们在第 8 章详细查看这些标 志. 对于现在,
我们一直使用 GFP_KERNEL. 分配的内存应当用
kfree 来释放. 你应当从 不传递任何不是从
kmalloc 获得的东西给 kfree. 但是, 传递一个 NULL 指针给 kfree 是合法的.
kmalloc 不是最有效的分配大内存区的方法(见第 8 章), 所以挑选给 scull 的实现不是 一个特别巧妙的. 一个巧妙的源码实现可能更难阅读, 而本节的目标是展示读和写, 不是 内存管理. 这是为什么代码只是使用 kmalloc 和 kfree 而不依靠整页的分配, 尽管这个 方法会更有效.
在 flip 一边, 我们不想限制"设备"区的大小, 由于理论上的和实践上的理由. 理论上,
给在被管理的数据项施加武断的限制总是个坏想法. 实践上,
scull 可用来暂时地吃光你 系统中的内存, 以便运行在低内存条件下的测试. 运行这样的测试可能会帮助你理解系统 的内部. 你可以使用命令 cp /dev/zero /dev/scull0 来用 scull 吃掉所有的真实 RAM, 并且你可以使用 dd 工具来选择贝多少数据给 scull 设备.
在 scull, 每个设备是一个指针链表, 每个都指向一个 scull_dev 结构. 每个这样的结构, 缺省地, 指向最多 4 兆字节, 通过一个中间指针数组. 发行代码使用一个 1000 个指针的 数组指向每个 4000 字节的区域. 我们称每个内存区域为一个量子, 数组(或者它的长度) 为一个量子集. 一个 scull 设备和它的内存区如图一个 scull 设备的布局所示.
选定的数字是这样, 在 scull 中写单个一个字节消耗 8000 或 12,000 KB 内存:
4000 是 量子, 4000 或者 8000 是量子集(根据指针在目标平台上是用 32 位还是
64 位表示). 相 反, 如果你写入大量数据, 链表的开销不是太坏. 每 4 MB 数据只有一个链表元素, 设备 的最大尺寸受限于计算机的内存大小.
为量子和量子集选择合适的值是一个策略问题, 而不是机制, 并且优化的值依赖于设备如 何使用. 因此, scull 驱动不应当强制给量子和量子集使用任何特别的值. 在 scull 中, 用户可以掌管改变这些值, 有几个途径:编译时间通过改变
scull.h 中的宏
SCULL_QUANTUM 和 SCULL_QSET, 在模块加载时设定整数值 scull_quantum 和 scull_qset, 或者使用 ioctl 在运行时改变当前值和缺省值.
使用宏定义和一个整数值来进行编译时和加载时配置, 是对于如何选择主编号的回忆. 我 们在驱动中任何与策略相关或专断的值上运用这个技术.
余下的唯一问题是如果选择缺省值. 在这个特殊情况下, 问题是找到最好的平衡, 由填充 了一半的量子和量子集导致内存浪费, 如果量子和量子集小的情况下分配释放和指针连接 引起开销. 另外, kmalloc 的内部设计应当考虑进去. (现在我们不追求这点, 不过; kmalloc 的内部在第
8 章探索.) 缺省值的选择来自假设测试时可能有大量数据写进
scull, 尽管设备的正常使用最可能只传送几 KB 数据.
我们已经见过内部代表我们设备的
scull_dev 结构. 结构的 quantum 和 qset 分别代表 设备的量子和量子集大小. 实际数据, 但是, 是由一个不同的结构跟踪, 我们称为
struct scull_qset:
struct scull_qset { void **data;
struct
scull_qset *next;
};
下一个代码片段展示了实际中 struct
scull_dev 和 struct scull_qset 是如何被用来持 有数据的. sucll_trim 函数负责释放整个数据区, 由
scull_open 在文件为写而打开时调 用. 它简单地遍历列表并且释放它发现的任何量子和量子集.
int
scull_trim(struct scull_dev *dev)
{
struct
scull_qset *next, *dptr;
int
qset = dev->qset; /* "dev" is not-null */ int i;
for
(dptr = dev->data; dptr; dptr = next)
{
/* all the list items */
if
(dptr->data) {
for
(i = 0; i < qset; i++)
kfree(dptr->data[i]); kfree(dptr->data);
dptr->data
= NULL;
}
next
= dptr->next; kfree(dptr);
}
dev->size = 0;
dev->quantum
= scull_quantum; dev->qset = scull_qset;
dev->data = NULL; return 0;
}
scull_trim 也用在模块清理函数中, 来归还 scull 使用的内存给系统.
linux scull 的内存使用的更多相关文章
- Linux内核笔记--内存管理之用户态进程内存分配
内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...
- Linux内核笔记——内存管理之slab分配器
内核版本:linux-2.6.11 内存区和内存对象 伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现. 如果我们需要请求具有连续物理地址 ...
- Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches
Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches 频繁的文件访问会导致系统的Cache使用量大增 $ free -m total used free shared ...
- Linux安装时内存如何分区的相关问题
Linux系统安装时内存如何分区:Linux系统必须的分区是根分区(/)和swap交换分区.普通用户一般分三个区,一个根分区(/),一个家目录(home分区),一个交换分区(swap分区),以80G的 ...
- Linux C程序内存空间
linux下内存空间布置: 一个典型的Linux C程序内存空间由如下几部分组成: 代码段(.text).这里存放的是CPU要执行的指令.代码段是可共享的,相同的代码在内存中只会有一个拷贝,同时这个段 ...
- Linux驱动之内存映射
本文参考了http://www.cnblogs.com/geneil/archive/2011/12/08/2281222.html.本文作为学习总结,将主要过程简要描述. 很多驱动实现某些功能都要通 ...
- 全面了解 Linux 服务器 - 2. 查看 Linux 服务器的内存使用情况
2. 查看 Linux 服务器的内存使用情况 liuqian@ubuntu:~$ free -m total used free shared buffers cached Mem: 1983 186 ...
- Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式
Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ...
- linux下共享内存mmap和DMA(直接访问内存)的使用 【转】
转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...
随机推荐
- 【php】php开发的前期准备
原文来自:http://www.cnblogs.com/sows/p/6867675.html (博客园的)风马一族 侵犯版本,后果自负 php介绍 什么php? 一种服务器端的 HTML 脚本/编程 ...
- python基础总结篇
''' 数据类型 数值 int: 字符串转int,只能转纯数字组成的字符串 小数,去掉小数部分 bool,true 1 false 0 float: 字符串转float,要么是纯数字的字符串,要么是纯 ...
- 【itsdangerous】的加密解密原理(易懂版)
from itsdangerous import TimedJSONWebSignatureSerializer import time from itsdangerous import Signat ...
- 洛谷2254 BZOJ1499 瑰丽华尔兹题解
洛谷链接 BZ链接 一个很容易想到的做法就是用f[i][j][t]表示t时刻在i,j处的可以滑动的最大值 f[i][j][t]=max(f[i][j][t-1],f[*i][*j][t-1]),这样大 ...
- 微信小程序组件——bindtap和catchtap的区别
了解知识点 DOM模型是一个树形结构,在DOM模型中,HTML元素是有层次的.当一个HTML元素上产生一个事件时,该事件会在DOM树中元素节点与根节点之间按特定的顺序传播,路径所经过的节点都会收到该事 ...
- zabbix概述篇
zabbix监控系统概述 监控系统 决不允许未经监控的业务和服务的上线 基本功能 采样:获取客户端数据(主动和被动模式) 存储 展示 告警 监控通道 ssh/telnet:无agent snmp:简单 ...
- shell日常使用整理
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wzzfeitian/article/details/30995303 基本常识 1.变量命名规则: ...
- 寒哥教你学iOS - 经验漫谈
http://www.jianshu.com/p/cb54054d3add 寒哥教你学iOS - 经验漫谈 字数2848 阅读1896 评论19 喜欢43 顺便来个广告 iOS开发者 群1734993 ...
- HDU-1160_FatMouse's Speed
FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Sp ...
- Python中的生产者消费者模型
---恢复内容开始--- 了解知识点: 1.守护进程: ·什么是守护进程: 守护进程其实就是一个‘子进程’,守护即伴随,守护进程会伴随主进程的代码运行完毕后而死掉 ·为何用守护进程: 当该子进程内的代 ...