免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5268 | 回复: 17

[文件系统] 内核态下的direct IO,烦请大神们帮忙! [复制链接]

论坛徽章:
0
发表于 2014-10-08 17:31 |显示全部楼层
在用户态下打开文件时,指定O_DIRECT便可以轻松实现direct IO,direct IO也是针对用户态程序的。
请问内核态下如何绕过内核cache,实施direct IO呢?

需求是这样的:
我有一个加密卡,按照指定格式写入就会自动加密,再读出来的数据就是加密的,我打算在内核态下进行操作(用户态下已测可以正常加密)。
目前现象是内核态下读出来的数据仍然是加密前的。如果在内核态进行写入,在用户态进行读出,或者反过来,都是可以正常加密的,因此可以确定是内核缓存问题。
如果强行加上O_DIRECT标识,那么会发生读写错误,通过分析源码,发现层层调用最终会调用到__blockdev_direct_IO --> do_direct_IO --> dio_get_page --> get_user_pages_fast,direct IO针对的是用户空间,所以我们使用的内核地址不能正常工作。

一个不能算是解决方案的解决方案是:
不用O_DIRECT,利用call_usermodehelper调用用户态程序,该程序进行清缓存操作:echo 3 > /proc/sys/vm/drop_caches
经测试,读出来的数据就是加密后的,但是清缓存对性能影响很大。并且我的加密卡针对网络数据包,频率超乎想象,所以……可行性几乎是0……

烦请各路大神帮帮忙!

论坛徽章:
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
发表于 2014-10-08 22:24 |显示全部楼层
回复 1# dreamzen


  看看这个邮件列表,可能会给你一点帮助:
https://lkml.org/lkml/2014/7/2/132

论坛徽章:
0
发表于 2014-10-09 10:17 |显示全部楼层
回复 2# Tinnal
谢谢!
认真看了一下,感觉很有用,一个方案是在用户空间申请缓存供内核使用,一个方案是每次写操作之后通过invalidate_inode_pages2_range丢掉加载的cache(不知道会不会写回呢?)。
我都试一下吧,有结果了会及时反馈~

   

论坛徽章:
0
发表于 2014-10-09 22:05 |显示全部楼层
回复 3# dreamzen


    问题成功解决!非常感谢@Tinnal!
    具体如下:
    利用上面邮件列表中提到的“Allocate user-space memory with vm_mmap()”,我在Ubuntu(3.2.0)下测试的,使用do_mmap申请用户空间缓冲区,再使用O_DIRECT进行文件读写,成功读取出了加密后的内容。
    代码片段如下:
  1.    
  2.     //Some code ahead ...

  3.     struct file *filp = NULL;
  4.     mm_segment_t old_fs;
  5.     ssize_t ret;
  6.     MY_DATA *in = NULL;
  7.     MY_DATA *out = NULL;

  8.     unsigned long addr;
  9.     unsigned long len;
  10.     unsigned long prot;
  11.     unsigned long flag;
  12.     unsigned long offset;

  13.     addr = 0;
  14.     len = 1024;
  15.     prot = PROT_READ | PROT_WRITE;
  16.     flag = MAP_SHARED;
  17.     offset = 0;

  18. //Open the file
  19.     filp = filp_open(FILE_DIR, O_RDWR, 0);
  20.     filp->f_flags |= O_DIRECT;

  21. //Mmap
  22.     in = do_mmap_pgoff(NULL, addr, len, prot, flag, offset);
  23.     out = do_mmap_pgoff(NULL, addr, len, prot, flag, offset);

  24.     old_fs = get_fs();
  25.     set_fs(get_ds());

  26. //Write data into device
  27.     filp->f_op->llseek(filp,0,0);
  28.     ret = filp->f_op->write(filp, (char *)in, 512, &filp->f_pos);
  29.     filp->f_op->fsync(filp, 0, 512, 0);

  30. //Read data from device(encrypted)
  31.     filp->f_op->llseek(filp,0,0);
  32.     ret = filp->f_op->read(filp, out, 512, &filp->f_pos);

  33. //More code ...
复制代码

论坛徽章:
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
发表于 2014-10-09 22:30 |显示全部楼层
恭喜恭喜。希望以后你遇到问题后,要先google。就你这个问题,我也就就是google出来的。

论坛徽章:
0
发表于 2014-10-10 16:03 |显示全部楼层
回复 5# Tinnal


    多谢指点!其实我也google了,可能搜索方法不对,没有看到这条,谢谢~

论坛徽章:
0
发表于 2014-10-16 09:24 |显示全部楼层
dreamzen 发表于 2014-10-09 22:05
回复 3# dreamzen
能不能把完整代码贴出来啊,呵呵,我们看看学习下,顺便也帮你看看代码有没有值得完善的地方。

论坛徽章:
0
发表于 2014-10-16 15:15 |显示全部楼层
dreamzen 发表于 2014-10-09 22:05
回复 3# dreamzen

in = do_mmap_pgoff(NULL, addr, len, prot, flag, offset)

这句仅仅找到了一段用户态的线性地址空间区域:0-0+len区域
关键是这块区域可能还没和实际物理内存建立映射关系,这种情况下直接调用

ret = filp->f_op->write(filp, (char *)in, 512, &filp->f_pos); 从用户态的0-0+len区域往该加密卡上写数据, 内核会不会出错。

难道上面函数的具体调用过程中,会发生用户态的0-0+len区域和实际物理内存的映射吗??

大家谁知道啊,说下啊。

论坛徽章:
0
发表于 2014-10-16 15:28 |显示全部楼层
buhui912 发表于 2014-10-16 15:15
in = do_mmap_pgoff(NULL, addr, len, prot, flag, offset)

这句仅仅找到了一段用户态的线性地址空间区 ...

还有用户态的0-0+len区域里面会实际存放些什么东西啊,我们知道用户态的指针为NULL时,如果读写时会发生错误。
这也说明用户态的0地址处的东西不能读写。

我的内核知识浅薄,请大家指导下。

论坛徽章:
0
发表于 2014-10-16 15:36 |显示全部楼层
buhui912 发表于 2014-10-16 15:28
还有用户态的0-0+len区域里面会实际存放些什么东西啊,我们知道用户态的指针为NULL时,如果读写时会发生错 ...

刚大概看过内核代码do_mmap_pgoff的实现,原来do_mmap_pgoff返回时,
可能会对addr做些调整,in可能不等于addr,这样申请到用户态地址区间就到合法的区域里去了吧,至少不会去0-0+len区域。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP