免费注册 查看新帖 |

Chinaunix

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

[内核模块] 内存映射内核和用户读写数据不同步 [复制链接]

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
1 [报告]
发表于 2014-09-12 08:41 |显示全部楼层
回复 1# 枫露清愁

写完以后flush_cache_all()一下就行了。
其实调用dma_map_single也就是想flush_cache一下而已,本身不是DMA,没有必要调用这种大的一个函数。


   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
2 [报告]
发表于 2014-09-12 09:22 |显示全部楼层
回复 13# 枫露清愁
典型又想马不吃草,又想马跑得好型。


   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
3 [报告]
发表于 2014-09-13 00:05 |显示全部楼层
@arm-linux-gcc@枫露清愁

以前真没留意cache的地址转换模式问题,被你这一说,回来恶补了一下。

1. 对于正常的应用,VIVT是效率最高的。因此不能因为这个特殊需求把整体的性能都降下来了。
2. VIPT的方式只解决了homonyms问题,不能解决aliasing问题。而楼主的问题,主要是aliasing问题导致。因此只有PIPT模式能真正的解决这个问题,但这也是cache最低效率的用法!

相关的结论来自对如下资料Address translation章节的分析:
http://en.wikipedia.org/wiki/CPU_cache

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
4 [报告]
发表于 2014-09-13 19:45 |显示全部楼层
回复 18# arm-linux-gcc

恩,回贴时只看了wiki, 没有去研究代码,ARM Linux对cache alias 确实在软件层面做了处理,令虚拟地址的index一致。在如下代码里arch_get_unmapped_area里就有反映。
  1. #ifdef CONFIG_CPU_V6
  2.         unsigned int cache_type;
  3.         int do_align = 0, aliasing = 0;

  4.         /*
  5.          * We only need to do colour alignment if either the I or D
  6.          * caches alias.  This is indicated by bits 9 and 21 of the
  7.          * cache type register.
  8.          */
  9.         cache_type = read_cpuid(CPUID_CACHETYPE);
  10.         if (cache_type != read_cpuid(CPUID_ID)) {
  11.                 aliasing = (cache_type | cache_type >> 12) & (1 << 11);
  12.                 if (aliasing)
  13.                         do_align = filp || flags & MAP_SHARED;
  14.         }
  15. #else
  16. #define do_align 0
  17. #define aliasing 0
  18. #endif
复制代码
在文件映射或MAP_SHARED共享映射下,都会对返回的虚拟地下做颜色对齐。
要对cache深入了解了不少。{:3_189:}


另外,X86应该是属于VIPT的吧。X86的手册上浏览了一下,没有直接的说明,但下如的网页里有描述:
http://stackoverflow.com/questio ... 64-for-caching-in-t
http://www.motherboardpoint.com/ ... hes-and-mmu.152345/
不知arm-linux-gcc兄能不能找到官方的出处呢。

PPC家里没有手册,没法查。

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
5 [报告]
发表于 2014-09-13 20:31 |显示全部楼层
但发现一个问题,就是Linux会做这个color对齐动作的只在用户态的mmap操作里进行。对内核代码分配出来的内存(包括slab\buddy)就没有这么幸运了,因为内核地址都是线性映射的,做color的对齐操作会出现大量的内存浪费,因此内核分配的地址,只能让内核开发者自己去保证了。vmalloc也没能难逃厄运{:3_184:} 。而楼主这个场景,推测内核就是由内核分配的。
反观内核目前的代码,在内核里头我们经常看到flush cache操作,但在用户态反倒可以不在意cache的问题,从这来看就能于通了。因为文件映射和共享映射都解决了cache alias的问题了。
呵呵,因此结论是,还是老老实实去flush吧。

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
6 [报告]
发表于 2014-09-14 00:08 |显示全部楼层
回复 21# arm-linux-gcc

vipt的data cache就是蛋疼,所以如果有硬件解决aliasing的vipt cache用起来就很方便


要体谅一下做硬件的,从硬件就解决aliasing也很烦。呵呵。RISC麻,能软件做的就软件做,只要对性能不会下降,不然又回到CISC上了。我也做过CPU,很多东西要做软件和硬件简折中。

   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
7 [报告]
发表于 2014-09-14 12:27 |显示全部楼层
本帖最后由 Tinnal 于 2014-09-14 12:35 编辑

回复 24# wLiu2007

cache和MMU在CPU内部是两个独立的硬件。你太过于强调,他们弄成一个整体了。VIPT等的模式,主要是因为(用软件的概念来说):cache有两个入参一个是index, 另一个是tag。他们从那去取的问题,从物理地址去取?不是从虚拟地址去去。这跟两个硬件的间接关系相关,但两个硬件内部的处理,就完全不相关了。因为用PAGE_SIZE和cache size/cache line size去做强相关分析是不对的。你的总体出发点就错了。


下面针对你写的内容做一下说明:
1,如果2个VA映射到同一个PA的话,这个PA可能占用2个不同的cache line,这样就有数据更新不同步的问题;

这个理解是对的。这就是cache aliasing的根因。如arm-linux-gcc兄所说,可以由软件按color对齐(目标是让两个虚拟地址
VA中PFN的后几个比特
一样)去解决;或硬件增加相应的电路去保证。

2,如果2个VA映射到2个不同的PA,映射关系VA1-PA1, VA2-PA2, 访问VA1的时候,有可能取得数据是VA2的数据;因为通过VA1和VA2提取的index是一样的,PA1和PA2的PFN的高几个比特相同,只有最后一个bit不同,但是tag只取高几个bit,所以通过PA1和PA2提取出来的Tag也是一样的;

你应该是指如下的情况:
  1.     |->page shift                   |->page shift
  2.     | |->cache line shift           | |->cache line shift
  3. X001|a|o(虚拟地址)        ->   A000|b|o(物理地址)
  4.     | |                             | |
  5. Y001|a|o                   ->   A111|b|o
复制代码
X001a0和Y001a0两个虚拟地址有相同的index:001a和相同的Tag: A,因此同在一个cache line里头。但他们对应的物理地址并不一样。因此如果X001a0先读,发生cache miss,然后再读Y001a0,将cache命中,并把属于A000bo的内容读进来。

这个问题在http://en.wikipedia.org/wiki/CPU_cache的VIPT节里已经有说明:
VIPT requires more tag bits, as the index bits no longer represent the same address.


另外,对于你所于的解决方面。你要清楚组相关cache,一个SET内部是全相关的,而set间是直接映射的。全相关电路需要的比较器数量是直接映射的需要的比较器不是一个级数的。要不然直接全相关好了,都不用来个组相关的了。这个用多级页表来形容你应该会清楚一点。谁想转换一个地址查半天,但如果用一个表,那就表就实在太大、浪费太多的内存了。



   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
8 [报告]
发表于 2014-09-14 23:33 |显示全部楼层
本帖最后由 Tinnal 于 2014-09-14 23:36 编辑

回复 26# wLiu2007
page color解决不了这类问题,前面我说得不够清楚?

这个问题硬件会通过
VIPT requires more tag bits, as the index bits no longer represent the same address.
来解决。说白了,针对你的案例,只要Tag增加到4位。那两个物理地址的tag就不一样了。一个为1110, 另外一个为1111。
另外,tag和index是两个参数,而且现在甚至连接到不同的源,不要去强调tag+index+offset一定是32位!

这些wiki里已经说得很清楚,请先认直阅读。

当然,我是也是wiki、google里推导的,如果有什么错误,请arm-linux-gcc兄指正。
   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
9 [报告]
发表于 2014-09-15 00:15 |显示全部楼层
回复 22# arm-linux-gcc
让arm-linux-gcc来答吧。


   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
10 [报告]
发表于 2014-09-17 09:54 |显示全部楼层
回复 32# 枫露清愁

用户态直接不能刷,权限不够。
ARM这边有一个__ARM_NR_cacheflush系统调用。x86没有对应的。这不是一个标准系统调用。
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP