- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
零拷貝技术研究与实现
零拷贝技术研究与实现2007-09-12 13:52作者:梁健(firstdot)E-MAIL:firstdot@163.com感谢王超、史晓龙的共同研究与大力帮助一.基本概念零拷贝(zero-copy)基本思想是:数据报从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,实现CPU的零参与,彻底消除 CPU在这方面的负载。实现零拷贝用到的最主要技术是DMA数据传输技术和内存区域映射技术。如图1所示,传统的网络数据报处理,需要经过网络设备到操作系统内存空间,系统内存空间到用户应用程序空间这两次拷贝,同时还需要经历用户向系统发出的系统调用。而零拷贝技术则首先利用DMA技术将网络数据报直接传递到系统内核预先分配的地址空间中,避免CPU的参与;同时,将系统内核中存储数据报的内存区域映射到检测程序的应用程序空间(还有一种方式是在用户空间建立一缓存,并将其映射到内核空间,类似于linux系统下的kiobuf技术),检测程序直接对这块内存进行访问,从而减少了系统内核向用户空间的内存拷贝,同时减少了系统调用的开销,实现了真正的“零拷贝”。图1 传统数据处理与零拷贝技术之比较二.实现在redhat7.3 上通过修改其内核源码中附带的8139too.c完成零拷贝的试验,主要想法是:在8139too网卡驱动模块启动时申请一内核缓存,并建立一数据结构对其进行管理,然后试验性的向该缓存写入多个字符串数据,最后通过proc文件系统将该缓存的地址传给用户进程;用户进程通过读proc文件系统取得缓存地址并对该缓存进行地址映射,从而可以从其中读取数据。哈哈,为了偷懒,本文只是对零拷贝思想中的地址映射部分进行试验,而没有实现DMA数据传输(太麻烦了,还得了解硬件),本试验并不是一个IDS产品中抓包模块的一部分,要想真正在IDS中实现零拷贝,除了DMA外,还有一些问题需考虑,详见本文第三节的分析。以下为实现零拷贝的主要步骤,详细代码见附录。步骤一:修改网卡驱动程序a.在网卡驱动程序中申请一块缓存:由于在linux2.4.X内核中支持的最大可分配连续缓存大小为2M,所以如果需要存储更大量的网络数据报文,则需要分配多块非连续的缓存,并使用链表、数组或hash表来对这些缓存进行管理。#define PAGES_ORDER 9unsigned long su1_2su1_2 = __get_free_pages(GFP_KERNEL,PAGES_ORDER);b. 向缓存中写入数据:真正IDS产品中的零拷贝实现应该是使用DMA数据传输把网卡硬件接收到的包直接写入该缓存。作为试验,我只是向该缓存中写入几个任意的字符串,如果不考虑DMA而又想向缓存中写入真正的网络数据包,可以在8139too.c的rtl8139_rx_interrupt()中调用 netif_rx()后插入以下代码://put_pkt2mem_n++; //包个数//put_mem(skb-data,pkt_size);其中put_pkt2mem_n变量和put_mem函数见附录。c. 把该缓存的物理地址传到用户空间:由于在内核中申请的缓存地址为虚拟地址,而在用户空间需要得到的是该缓存的物理地址,所以首先要进行虚拟地址到物理地址的转换,在linux系统中可以使用内核虚拟地址减3G来获得对应的物理地址。把缓存的地址传到用户空间需要在内核与用户空间进行少量数据传输,这可以使用字符驱动、proc文件系统等方式实现,在这里采用了proc文件系统方式。int read_procaddr(char *buf,char **start,off_t offset,int count,int *eof,void *data){???? sprintf(buf,%u\n,__pa(su1_2));???? *eof = 1;???? return 9;}create_proc_read_entry(nf_addr,0,NULL,read_procaddr,NULL);步骤二:在用户程序中实现对共享缓存的访问a.读取缓存地址:通过直接读取proc文件的方式便可获得。char addr[9];int fd_procaddr;unsigned long ADDR;fd_procaddr = open(/proc/nf_addr,O_RDONLY);read(fd_procaddr,addr,9);ADDR = atol(addr);b.把缓存映射到用户进程空间中:在用户进程中打开/dev/mem设备(相当于物理内存),使用mmap把网卡驱动程序申请的缓存映射到自己的进程空间,然后就可以从中读取所需要的网络数据包了。char *su1_2;int fd;fd=open(/dev/mem,O_RDWR);????su1
您可能关注的文档
最近下载
- 《电气工程及其自动化专业导论》课程教学大纲.docx VIP
- 一种能模拟任意非线性激活函数的量子系统.pdf VIP
- 小学数学与信息技术教育的跨学科课程融合策略研究教学研究课题报告.docx
- 卡特彼勒3512C发动机零件图册 英文版.pdf VIP
- 临床复用医疗器械集中管理率、职业爆发率、包装合格率等消毒供应中心质控指标体系指标要点.doc VIP
- 地质灾害应急演练脚本.pdf VIP
- 【开学第一课】高三开学第一课(生物)(共28张PPT).pptx VIP
- 提钒炼钢厂点检维护作业区专职点检绩效考核实施细则.doc VIP
- 加油站管理者的领导与团队建设.pptx VIP
- 劳动防护用品基础知识.ppt VIP
文档评论(0)