免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: bripengandre
打印 上一主题 下一主题

基于NETLINK的内核与用户空间共享内存的实现 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-05-27 10:29 |只看该作者
原帖由 thomas_ar 于 2009-5-27 10:23 发表
而且 2.6.26 就增加了默认禁止访问/dev/mem的选项

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ae531c26c5c2a28ca1b35a75b39b3b256850f2c8

+config NONPROMISC_DEVMEM ...

默认禁止,可能是出于安全的考虑吧,窃以为,后门很多时候都还是会开的~~

论坛徽章:
0
22 [报告]
发表于 2009-05-27 11:23 |只看该作者

回复 #1 bripengandre 的帖子

static int init_mem_pool(void)
{
    int map_fd;
    void *map_addr;
   
    map_fd = open("/dev/mem", O_RDWR);
    if(map_fd < 0)
    {
        SHM_ERR("init_mem_pool::open %s error: %s\n", "/dev/mem", strerror(errno));
        return (-1);
    }
      
    map_addr = mmap(0, glb_para.shm_para.mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, glb_para.shm_para.mem_addr);
    if(map_addr == NULL)
    {
        SHM_ERR("init_mem_pool::mmap error: %s\n", strerror(errno));
        return (-1);
    }
    glb_para.shm_para.mem_addr = (uint32_t)map_addr;
    return (0);
}

在楼主这段代码中,你对mmap过来的内存,没有取消mmap,你是怎么考虑的呢?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
23 [报告]
发表于 2009-05-27 11:41 |只看该作者
在楼主这段代码中,你对mmap过来的内存,没有取消mmap,你是怎么考虑的呢?

应该在程序退出的时候取消。这个地方应该是LZ遗漏了。

论坛徽章:
0
24 [报告]
发表于 2009-05-27 11:52 |只看该作者
原帖由 Godbach 于 2009-5-27 11:41 发表

应该在程序退出的时候取消。这个地方应该是LZ遗漏了。


那就是在用户进程退出前这个mmap是一直保存的吧:)

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
25 [报告]
发表于 2009-05-27 12:53 |只看该作者
原帖由 weily0000 于 2009-5-27 11:52 发表


那就是在用户进程退出前这个mmap是一直保存的吧:)


应该是的。

论坛徽章:
0
26 [报告]
发表于 2009-05-27 15:27 |只看该作者
原帖由 weily0000 于 2009-5-27 11:52 发表


那就是在用户进程退出前这个mmap是一直保存的吧:)


这里没有munmap确实是遗漏了,但程序退出时,这个映射关系自然解除:
摘自man:
The munmap() system call deletes the mappings for the specified address range, and causes further references to
       addresses  within  the  range to generate invalid memory references.  The region is also automatically unmapped
       when the process is terminated.  On the other hand, closing the file descriptor does not unmap the region.
对我这样一个对内核不了解的人来说,mmap就是把一段共用的东西映射到进程用户地址空间,即mmap时,这段共用的东东会增加一个引用,用户程序退出时,地址映射等都会被正常回收,所以自动解除了映射(我这程序里的描述符就没有显示关闭)。
     如果你要问内核部分分配的那部分供共享的内存什么时候释放?那遵循“解铃还需系铃人”的原则,释放也由内核部分负责即可,本示例程序中就在rmmod shm_k.ko时进行~~
    anyway,非常感谢你指出我的不细心~~

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
27 [报告]
发表于 2009-05-27 15:37 |只看该作者
恩。个人觉得程序中自己申请的东东,还是自己显示的释放比较好。

论坛徽章:
0
28 [报告]
发表于 2009-05-27 15:57 |只看该作者
原帖由 bripengandre 于 2009-5-27 15:27 发表


这里没有munmap确实是遗漏了,但程序退出时,这个映射关系自然解除:
摘自man:
The munmap() system call deletes the mappings for the specified address range, and causes further references to
  ...


哥们太细心了。。我最近在做的一个小东西也用了NETLINK进行内存共享,做的事情和你差不多,我在内核里面申请了一段内存空间进行缓存,如果缓存满了就会通过netlink将缓存地址和缓存大小通知用户态进程去读取数据。在用户态我会做一个映射,如下:

  1. map_addr = mmap(0, buffer_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, buffer_addr);
  2. memcpy(buff_pos, map_addr, buffer_size);                              /* copy kernel data to user buffer, wait for transmiting */
  3. munmap(map_addr, buffer_size);
复制代码


看了你的代码后,我有了一些启发,我想我这个有点多余了,因为缓存从一申请开始它的大小和地址就应该不变了,所以只用到退出程序时接触映射就够了,而我这样效率更低了。
另外我有一个问题就是,我采用这种方式,如果当内核里面往缓存写数据速度太快时候,用户进程读取速度过慢,这样就会有数据的丢失的情况有时候会发生,我现在能做的就是增大内核缓存的申请,这种方法可能还是有一个限制,不知道大家有没有什么好的解决方法,谢谢了。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
29 [报告]
发表于 2009-05-27 16:11 |只看该作者
另外我有一个问题就是,我采用这种方式,如果当内核里面往缓存写数据速度太快时候,用户进程读取速度过慢,这样就会有数据的丢失的情况有时候会发生,我现在能做的就是增大内核缓存的申请,这种方法可能还是有一个限制,不知道大家有没有什么好的解决方法,谢谢了。

恩,用get_free_pages申请的连续内存大小是有限制的。你要最多写多少数据啊?

论坛徽章:
0
30 [报告]
发表于 2009-05-27 21:36 |只看该作者
原帖由 Godbach 于 2009-5-27 16:11 发表

恩,用get_free_pages申请的连续内存大小是有限制的。你要最多写多少数据啊?


我做的和raid1有点像,会把写的数据都存起来做一个备份,如果用户写一个100M的文件,我就要写100M的数据。。这个量不是我所能预测的,实际情况下,如果系统写得太多太快,会丢失大量的数据,而且我在内核里面用了多缓冲,这个还是有问题。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP