免费注册 查看新帖 |

Chinaunix

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

[FreeBSD] freebsd内核模块中只能分配<80M内存,有何办法? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-01-09 11:00 |只看该作者
是啊,看来以后最好搬到5.X上做了。
我现在网关位置做连接跟踪(在比较大的局域网总出口,可能同时有1万以上的人在上网)之类的工作,也就是说要记录通过网管的每一个网络连接(TCP连接或者UDP/icmp虚拟连接),也就是说只要有网络连接产生,我就要跟踪。目前,每个连接占用64字节内存,如果该连接有附加信息,则要占更多。而这种网络环境下,通常至少要维持200~300万个连接,每秒要新建5万/销毁5万个连接,这样占用的内存要相当多。因为要做流量限速、各种访问控制等,因此又必须在内核态来做。
内核中分配内存,必须先定义一个类型---据说内核用来做统计工作,而同一类型的内存分配有个上限,为82M,超过了这个限制,无论你有多少空余内存内核都返回NULL。
我现在就要想法突破这个限制。请教各位大侠,具体怎么办呢?

论坛徽章:
0
12 [报告]
发表于 2007-01-09 11:09 |只看该作者
有一些黑客的技巧,比如:
你有2G内存,但是告诉内核,只有1G;然后将剩下的1G通过ioremap(这个是linux函数,在bsd上的我不太清楚)之类的函数映射到虚拟空间,由自己管理。
但是这种可能要改动内核,或者是修改启动参数,而且根本没有可移植性。

我认为最好的方法就是修改算法,将你的程序用一个守护进程实现,而不是在内核。

论坛徽章:
0
13 [报告]
发表于 2007-01-09 11:26 |只看该作者
原帖由 ktrudger 于 2007-1-9 11:00 发表
而同一类型的内存分配有个上限,为82M ...


这个82M你是怎么“碰”出来的?

论坛徽章:
0
14 [报告]
发表于 2007-01-09 12:37 |只看该作者
申请内存超过这个81M后,会返回NULL。用vmstat -m命令可以看到这个限制。

论坛徽章:
0
15 [报告]
发表于 2007-01-09 12:47 |只看该作者
另外可以看看vm/vm_kern.c里面的kmem_alloc也许有用。

论坛徽章:
2
技术图书徽章
日期:2013-09-04 15:21:51酉鸡
日期:2013-11-01 21:20:20
16 [报告]
发表于 2007-01-09 17:31 |只看该作者
原帖由 ktrudger 于 2007-1-9 11:00 发表
是啊,看来以后最好搬到5.X上做了。
我现在网关位置做连接跟踪(在比较大的局域网总出口,可能同时有1万以上的人在上网)之类的工作,也就是说要记录通过网管的每一个网络连接(TCP连接或者UDP/icmp虚拟连接), ...

繁重的网络处理最好使用6.x吧。4.x只能只用polling获取较好的性能,6.x可以使用中断方式了
在4.x,你可以尝试KVA_PAGES这个参数提高kernel内存,这需要小心调整,我调崩过几次。

论坛徽章:
0
17 [报告]
发表于 2007-01-09 17:36 |只看该作者
原帖由 mirnshi 于 2007-1-9 17:31 发表

繁重的网络处理最好使用6.x吧。4.x只能只用polling获取较好的性能,6.x可以使用中断方式了
在4.x,你可以尝试KVA_PAGES这个参数提高kernel内存,这需要小心调整,我调崩过几次。

我也想用6.x,可惜经测试,发现6.0/6.1的网络性能非常差,CPU占用很高。是不是6.X的中断线程机制太耗费性能?没有测试过5.X,不知道能否好点。

论坛徽章:
0
18 [报告]
发表于 2007-01-09 17:52 |只看该作者
装了个4.11才发现,从4.11到6.1,不但内核代码变了,连vmstat -m的输出格式也变了。。。

看了一下4.11的代码,vmstat -m输出信息中的“Limit”一列给出的实际上是malloc_type.ks_limit的值,这个值在malloc_init()函数中被初始化为(vm_kmem_size/2),可以从这里入手。

论坛徽章:
0
19 [报告]
发表于 2007-01-09 20:40 |只看该作者
FreeBSD4.11的kern_malloc.c的kmeminit()函数:

  1.         /*
  2.          * Try to auto-tune the kernel memory size, so that it is
  3.          * more applicable for a wider range of machine sizes.
  4.          * On an X86, a VM_KMEM_SIZE_SCALE value of 4 is good, while
  5.          * a VM_KMEM_SIZE of 12MB is a fair compromise.  The
  6.          * VM_KMEM_SIZE_MAX is dependent on the maximum KVA space
  7.          * available, and on an X86 with a total KVA space of 256MB,
  8.          * try to keep VM_KMEM_SIZE_MAX at 80MB or below.
  9.          *
  10.          * Note that the kmem_map is also used by the zone allocator,
  11.          * so make sure that there is enough space.
  12.          */
  13.         vm_kmem_size = VM_KMEM_SIZE;
  14.         mem_size = cnt.v_page_count * PAGE_SIZE;

  15. #if defined(VM_KMEM_SIZE_SCALE)
  16.         if ((mem_size / VM_KMEM_SIZE_SCALE) > vm_kmem_size)
  17.                 vm_kmem_size = mem_size / VM_KMEM_SIZE_SCALE;
  18. #endif

  19. #if defined(VM_KMEM_SIZE_MAX)
  20.         if (vm_kmem_size >= VM_KMEM_SIZE_MAX)
  21.                 vm_kmem_size = VM_KMEM_SIZE_MAX;
  22. #endif

  23.         /* Allow final override from the kernel environment */
  24.         TUNABLE_INT_FETCH("kern.vm.kmem.size", &vm_kmem_size);
复制代码

因此,全局变量vm_kmem_size最终依据的是内核参数kern.vm.kmem.size。我的4.11虚拟机默认情况下的vmstat -m的输出信息是:

  1. Memory statistics by type                          Type  Kern
  2.         Type  InUse MemUse HighUse  Limit Requests Limit Limit Size(s)
  3.         linux     8     1K      1K 25970K        8    0     0  32
  4.      atkbddev     2     1K      1K 25970K        2    0     0  32
  5.    uc_devlist    30     3K      3K 25970K       30    0     0  16,2K
复制代码

在/boot/loader.conf文件中添加如下一行(将kern.vm.kmem.size设置为缺省值的两倍):

  1. kern.vm.kmem.size="106373120"
复制代码

重启系统后的vmstat -m的输出信息是:

  1. Memory statistics by type                          Type  Kern
  2.         Type  InUse MemUse HighUse  Limit Requests Limit Limit Size(s)
  3.         linux     8     1K      1K 51940K        8    0     0  32
  4.      atkbddev     2     1K      1K 51940K        2    0     0  32
  5.    uc_devlist    30     3K      3K 51940K       30    0     0  16,2K
  6. ......
复制代码

这样做至少解决了你所说的“好像不能用sysctl调节?”的问题,前提是此limit即彼limit。至于在实际分配中是否有效,只有等你自己去验证了!^_^


[ 本帖最后由 雨丝风片 于 2007-1-10 07:59 编辑 ]

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
20 [报告]
发表于 2007-01-09 21:19 |只看该作者
期待有人总结此方经验。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP