但有一个致命的缺限,如果你在启用X-Windows以及一系统大型应用时
从free看出你的物理内存已经很少了,这时采用LKM动态加载内存需求较大的内核模块时
不一定能成功,这非常要命,当不能得到页面时,__get_free_pages会触发VMA将
快速交换,此时大块物理内存被释放,但系统本身却一直与外存持续交换,系统响应变得
很慢,物别是在GUI模式下。即便如此,你再加载LKM时,还是不能成功,这是不可以理解的。
已经有不少朋友在mlist中提出,这必须得将VMA进行修正。
有时,我在init 3/init 1下工作正常,而init 5时,动态加载几乎不成功。
这对于开发而言,是不可思议的 sysenter这种实现我早就知道了,这时一个几年前的东西了, 我也知道他的效率很高.
其实直接操作/dev/mem的事情我很早就用过, 但是对于实际开发来说.
更改所有用户空间的内存管理方法, 直接操作物理内存,你怎么保证系统库能正常运行?如果你不需要系统库, 你编写上层应用程序, 是否要替换所有内存操作代码? 对于分配的所有物理页,你是否要自己管理他的碎片, 等问题? 你是否考虑到了这样的改动对于所有的上层应用程序来说, 有多少附加的工作量?
为什么我用mlock, 只是说把mlock可以用来在用户和内核之间通信使用. 请问,你一次有多少数据量要在用户和内核之间交互? 我现在的使用中都是足够的. 而这种方法的改动是最小的, 效率也不比你提到的低.
对于用户空间任务之间的数据交互, 用线程可以减少很多麻烦. to obrire,
我看了你的做法,觉得不错。
比如,在用户空间malloc()了32M虚拟地址,如何在用户空间知道其物理开始地址并且打开/dev/mem线性操作相应的地址? 另外, 你多次提到有人建议linus修改vma和mm的实现, 能否给出讨论的链接地址, 多谢! to orbire
是不是这样:
m = open("/dev/mem", ...);
lseek(m, 1204, 0);
read(m, buf, sizeof(buf));
write(m, "123456", 6);
直接操作物理内存?
"
在内核空间申请
在用户空间不用mmap
直接open /dev/mem
lseek xxxxx
一切就哪样简单,就像汇编,写进去就行了.
这可是直接物理内存操作呀.
其实在性能要求高的环境,不需要外存的.有些Super Computer就是这样的.
结果直接就通过网络送走了.
" 原帖由 思一克 于 2006-4-14 12:53 发表
to orbire
是不是这样:
m = open("/dev/mem", ...);
lseek(m, 1204, 0);
read(m, buf, sizeof(buf));
write(m, "123456", 6);
直接操作物理内存?
"
在内核空间申请 ...
正是,当你得先知道确切的物理地址, 也就是OFF_SET,一般我的系统分配在0x600000以后.
我采用在/proc/mem_window输出一个地址及尺寸, 然就这样操作了 to orbire,
那你了解read write /dev/mem还要调用copy_fro_user, copy_to_user?
/dev/mem仅仅是一个影射物理内存的字符设备,读写它要通过文件系统的许多调用,最后才调用read_mem, 和write_mem, 然后就是copy_from/to_user,怎么能比mmap快?
原帖由 obrire 于 2006-4-14 16:29 发表
正是,当你得先知道确切的物理地址, 也就是OFF_SET,一般我的系统分配在0x600000以后.
我采用在/proc/mem_window输出一个地址及尺寸, 然就这样操作了 原帖由 思一克 于 2006-4-14 12:30 发表
to obrire,
我看了你的做法,觉得不错。
比如,在用户空间malloc()了32M虚拟地址,如何在用户空间知道其物理开始地址并且打开/dev/mem线性操作相应的地址?
首先,你要得到用户空间地址在内核空间的入口, 用逻辑地址并减去PAGE_OFFSET才能得到物理地址.
与高端内存的关系,你要看看你当前版本的源定义,不一而足
如果纯粹在用户空间用malloc, 并不能保证你能得到性线物理地址.
因此才有我说的,先在内核模块中规划, 然后在用户空间自由使用
所以在用户空间用malloc是无法保证性能和线性的.在VMA中可以保证你看起来是线性的.
但内核实现, 完全可以采用relayfs(2.6.14以后加入)方式,用多组不同大小的页面组来完成映射(list),
只是你在用户空间感觉不到.
如果你想这样使用, 建议你也先在内核空间划出一块来, 然后在用户空间操作.
我是因为我的PCI总线的上设备要求在相关Register置入物理地址, 并要求在块线性空间,才不得不这样呀.
主要是方便DMA传送. 如果全在内核模块中做,有些功能不方便,不如用户空间编程方便,所以行此法.
只是这方面你的代码千万不能越界,如果打开/dev/mem以后,在其它区间写入了数据,
会让系统变得不可思议了.
我所讲的无非三点
1. 方便在用户空间直接操作物理内存
2. 线性读写/块传输
3. 内核模块中实现了DMA传输完成IRQ响应,用户程序完全可以while(1)直接操作
使得编程接口简单高效, 就像实时preview高速视频一样.其它线程编码不受影响
至于同步问题, 用什么机制, 尊重你自己的选择,别让work_queue锁死了.如果有硬时钟就好了
应用层可以多路POOLING,内核层采用中断
回复 27楼 思一克 的帖子
当然不会了,就是不用copy_to_user这类函数了要写什么你直接置入就可以
只是这种管理状态,如有些区域设置同步位,要求自己要有较高的编程管理能力
混合模型: 每次同记录在/proc/mem_window中,锁一打开,应用就读写或刷新.
这不影响系统其它应用,全在你自己的空间,或者同步块标志在这片物理区更好,性能
上更有效一些.
[ 本帖最后由 obrire 于 2006-4-14 16:56 编辑 ] to obrire,
内核中自己的VMA的物理地址是连续的吗?
"所以在用户空间用malloc是无法保证性能和线性的.在VMA中可以保证你看起来是线性的.
但内核实现, 完全可以采用relayfs(2.6.14以后加入)方式,用多组不同大小的页面组来完成映射(list),
只是你在用户空间感觉不到.
"