免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4464 | 回复: 8
打印 上一主题 下一主题

[内存管理] ioremap的疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-07-16 13:13 |只看该作者 |倒序浏览
接触linux不久,对ioremap的返回空间有些疑问。。。


环境arm, linux2.6
在设备上察看vmallocinfo,结果如下:

[root@FriendlyARM /proc]# cat vmallocinfo
0xc4808000-0xc480a000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc480c000-0xc480e000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4810000-0xc4812000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4814000-0xc4816000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4818000-0xc481a000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc481c000-0xc481e000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4820000-0xc4822000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4824000-0xc4826000    8192 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4a00000-0xc4b01000 1052672 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4c00000-0xc4d01000 1052672 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc4e00000-0xc4f01000 1052672 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc5000000-0xc5101000 1052672 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc5200000-0xc5301000 1052672 __arm_ioremap_pfn+0x78/0x330 ioremap
0xc5400000-0xc5501000 1052672 __arm_ioremap_pfn+0x78/0x330 ioremap
[root@FriendlyARM /proc]#

其中红色部分,就是连续执行了addr1=ioremap(0x20000000,4); addr2=ioremap(0x20000004,4);的结果。

问题:
1、个人理解,既然是只分配4个字节,那么ioremap返回一个page就够了阿。为什么会返回8K空间(2个page)呢?
2、addr1和addr2分别是0xc4810000,0xc4814000。既然每个地址空间的分配只占了8K,那中间间隔的那8K呢,做什么用?比如从0xc4812000到0xc4814000这段空间,空闲着吗?为什么不是连续分配给addr1和addr2呢?
3、实际上addr1和addr2 map的物理空间是连续的,那么如果访问addr1+4是否就等于访问addr2呢?

多谢各位!

论坛徽章:
0
2 [报告]
发表于 2012-07-17 09:36 |只看该作者
大家都放假去了吗?~

目前个人还是没想明白,还请大家给个分析!

多谢!

论坛徽章:
1
拜羊年徽章
日期:2015-03-03 16:15:43
3 [报告]
发表于 2012-07-17 11:27 |只看该作者
回复 1# arm_zwinger

先查查你的PAGE_SHIFT是多少?  会不会你的系统页面大小就是8K?
   

论坛徽章:
0
4 [报告]
发表于 2012-07-17 15:32 |只看该作者
不会啊,arm的页面都是4K啊,而且查看相关的定义,PAGE_SHIFT是4K阿。。。
配置中,CONFIG_MMU也有定义。。。


/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT                12
#define PAGE_SIZE                (1UL << PAGE_SHIFT)
#define PAGE_MASK                (~(PAGE_SIZE-1))

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
5 [报告]
发表于 2012-07-17 17:20 |只看该作者
本帖最后由 瀚海书香 于 2012-07-17 21:39 编辑

回复 1# arm_zwinger
1、个人理解,既然是只分配4个字节,那么ioremap返回一个page就够了阿。为什么会返回8K空间(2个page)呢?
2、addr1和addr2分别是0xc4810000,0xc4814000。既然每个地址空间的分配只占了8K,那中间间隔的那8K呢,做什么用?比如从0xc4812000到0xc4814000这段空间,空闲着吗?为什么不是连续分配给addr1和addr2呢?
3、实际上addr1和addr2 map的物理空间是连续的,那么如果访问addr1+4是否就等于访问addr2呢?

1. 这个问题从ioremap的源代码中跟踪一下,就可以看到了。ioremap--...-->__get_vm_area_node 在这个函数中,对所有的请求大小都加上一个PAGE_SIZE,用来作为一个gap使用,所以申请4个字节,对应的实际大小就是 PAGE_ALIGN(4)+PAGE_SIZE = 8K
2. 这个应该是随机的,操作系统选择一个可用的虚拟地址空间使用,不会刻意的去分隔开8K的,可能是这段地址空间恰好被使用了等等。
3. addr1+4K会进入gap,操作系统会捕获这个异常的,不会访问到另一个vm。

其实你的这个问题与ioremap关系不大,主要是VM部分的操作。

希望对你有帮助!

   

论坛徽章:
0
6 [报告]
发表于 2012-07-18 12:40 |只看该作者
本帖最后由 arm_zwinger 于 2012-07-18 12:46 编辑

回复 5# 瀚海书香


万分感谢!真是有求必应!

对于问题2,我还是有些不解。
自己做了个测试:不停的ioremap,直到VM_END,系统会返回失败,因为已经到了最后的虚拟地址空间。程序判断如果返回的地址是0xdeffe000或者0xdeffc000,那么就打印出来。结果发现只有0xdeffe000打印出来了,说明相连的8k(0xdeffc000)没有被ioremap操作过。不清楚为什么要跨这8k,而且这8K也永远不会被ioremap了。

一般系统也不会这么多的ioremap操作,可能是操作到了VM_END,就不再回头找是否有空用的空间了?猜测而已。。。

不管怎样,还是非常感谢“瀚海书香 ”!


   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
7 [报告]
发表于 2012-07-18 13:14 |只看该作者
回复 6# arm_zwinger
对于问题2,我还是有些不解。
自己做了个测试:不停的ioremap,直到VM_END,系统会返回失败,因为已经到了最后的虚拟地址空间。程序判断如果返回的地址是0xdeffe000或者0xdeffc000,那么就打印出来。结果发现只有0xdeffe000打印出来了,说明相连的8k(0xdeffc000)没有被ioremap操作过。不清楚为什么要跨这8k,而且这8K也永远不会被ioremap了。

我这边在只有一个2410的板子是arm的,其他的都是X86的。我在这边测试的情况是没有出现你所说的问题。下面是在suse 11(x86_64)上的测试结果:
tingw:~/program/x86/kernel/ioremap # cat /proc/vmallocinfo > /root/info.old
tingw:~/program/x86/kernel/ioremap # insmod ioremap.ko
tingw:~/program/x86/kernel/ioremap # cat /proc/vmallocinfo > /root/info.new
tingw:~/program/x86/kernel/ioremap # diff /root/info.old /root/info.new
25a26,27
> 0xffffc90010232000-0xffffc90010234000    8192 hello_init+0x29/0x4c [ioremap] phys=14000 ioremap
> 0xffffc9001025e000-0xffffc90010260000    8192 hello_init+0x13/0x4c [ioremap] phys=12000 ioremap
47a50
> 0xffffffffa004e000-0xffffffffa0050000    8192 load_module+0x5f4/0x1130 pages=1 vmalloc N0=1

从输出来看,vmalloc选择应该没有刻意的预留固定的8K大小。

   

论坛徽章:
0
8 [报告]
发表于 2012-07-18 15:48 |只看该作者
回复 7# 瀚海书香

从你的结果看起来,的确应当是OS自己选择了一段vm去map的,看不出来有什么特别的规律。

难道是我这个版本的linux的实现上的问题?linux2.6.29.4

看来得再看看这个里面的实现。


   

论坛徽章:
0
9 [报告]
发表于 2012-07-20 15:27 |只看该作者
学术氛围很浓厚啊,受教了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP