发明内容
针对现有技术在零拷贝网络报文发送、接收过程中需要将内存地址进行转换、网卡硬件在进行DMA操作时数据报文长度受页面大小限制、占用CPU资源的问题,本发明的目的是提供一种零拷贝网络报文发送、接收方法和装置,以解决上述问题中的至少之一。
为实现上述目的,根据本发明的一个方面,提供了一种零拷贝网络报文发送方法,包括下列步骤:使用内存分配函数在网卡驱动程序中不断地申请特定大小的连续内存直至网卡驱动程序中空闲的内存空间不足够申请;从申请到的连续内存中确定一块连续内存地址空间;以及使用连续内存地址空间进行网络报文发送。其中,从申请到的连续内存中确定一块连续内存地址空间的具体步骤包括:将申请到的每片连续内存的首地址存储到地址数组;将地址数组中的连续内存的首地址根据大小进行排序;在地址数组中根据排序后的首地址确定一块连续内存地址空间。
根据本发明,特定大小是指内存分配函数所能申请的连续内存的最大值;连续内存地址空间大于或等于用户指定的发送报文DMA缓冲区的大小;地址数组包括用于存储小于4G的首地址的低端地址数组和用于存储4G以上的首地址的高端地址数组,排序是根据连续内存的首地址的大小,在确定连续内存地址空间时首先选择在低端地址数组中进行。
根据本发明,在确定了连续内存空间之后将连续内存地址空间的首地址及大小保存至网卡驱动程序中,并按照页面大小将连续内存地址空间标记为保留页面,将其他申请的未使用的连续内存释放。
相应地,本发明提供了一种零拷贝网络报文发送装置,包括:申请模块,用于在网卡驱动程序中申请连续内存;确定模块,用于从申请到的连续内存中确定一块连续内存地址空间;以及发送模块,用于使用连续内存地址空间进行网络报文发送。其中,确定模块包括:地址数组模块,用于存储申请到的连续内存的首地址;排序模块,用于对首地址进行排序;以及查找模块,用于查找连续内存地址空间。
根据本发明的另一个方面,提供了一种零拷贝网络报文接收方法,包括下列步骤:使用内存分配函数在网卡驱动程序中不断地申请特定大小的连续内存直至网卡驱动程序中空闲的内存空间不足够申请;从申请到的连续内存中确定一块连续内存地址空间;以及使用连续内存地址空间进行网络报文接收。其中,从申请到的连续内存中确定一块连续内存地址空间的具体步骤包括:将申请到的每片连续内存的首地址存储到地址数组;将地址数组中的连续内存的首地址根据大小进行排序;在地址数组中根据排序后的首地址确定一块连续内存地址空间。
根据本发明,特定大小是指内存分配函数所能申请的连续内存的最大值;连续内存地址空间大于或等于用户指定的接收报文DMA缓冲区的大小;地址数组包括用于存储小于4G的首地址的低端地址数组和用于存储4G以上的首地址的高端地址数组;在确定连续内存地址至间时首先选择在低端地址数组中进行。
根据本发明,在确定了连续内存空间之后将连续内存地址空间的首地址及大小保存至网卡驱动程序中,并按照页面大小将连续内存地址空间标记为保留页面,将其他申请的未使用的连续内存释放.
相应地,本发明提供了一种零拷贝网络报文接收装置,包括:申请模块,用于在网卡驱动程序中申请连续内存;确定模块,用于从申请到的连续内存中确定一块连续内存地址空间;以及接收模块,用于使用连续内存地址空间进行网络报文接收。其中,确定模块包括:地址数组模块,用于存储申请到的连续内存的首地址;排序模块,用于对首地址进行排序;以及查找模块,用于查找连续内存地址空间。
本发明的零拷贝网络报文发送方法和装置,通过在网卡驱动程序中申请连续内存,发送的数据报文连续存储在报文DMA缓冲区中,因此网卡硬件在进行DMA操作时不受页面大小限制,网卡不需要采用中断方式通知网卡驱动程序数据报文发送完成的情况,不占用CPU资源。
本发明的零拷贝网络报文接收方法和装置,通过在网卡驱动程序中申请连续内存,接收的数据报文连续存储在报文DMA缓冲区中,不需要将用户空间内存地址按页面大小转换成DMA操作所需的物理地址,因此网卡硬件在进行DMA操作时不受页面大小限制,即使接收大流量64字节短数据报文也不会出现报文丢弃现象,而且网卡驱动程序也不需要采用中断或轮询方式接收数据报文,不占用CUP资源。
具体实施方式
参见图1所示,本实施例的一种零拷贝网络报文发送方法,具体包括以下操作步骤:S110,使用内存分配函数在网卡驱动程序中不断地申请特定大小的连续内存直至网卡驱动程序中空闲的内存空间不足够申请;S120,从申请到的连续内存中确定一块连续内存地址空间;以及S130,使用连续内存地址空间进行网络报文发送。
在步骤S110中,特定大小是指内存分配函数所能申请的最大的连续内存的值,举例来说,在某些Linux操作系统中,利用内存分配函数能申请的最大连续内存为4M字节,内存分配函数不断地在网卡驱动程序中进行申请直至网卡驱动程序中空闲的内存空间小于内存分配函数所要申请的最大的连续内存,也即直至内存分配函数返回错误值时停止申请,在这个过程中内存分配函数会申请到多片连续内存。
在步骤S120中,从申请到的多片连续内存中确定一块连续内存地址空间,连续内存地址空间大于或等于用户指定的发送报文DMA缓冲区的大小。当需要确定的一块连续内存地址空间较小时,可能只需要一片申请到的连续内存即可,但是当需要确定的一块连续内存地址空间较大时,就会需要多片申请到的连续内存才能满足。
在步骤S130中,使用连续内存地址空间进行网络报文发送是指,网卡硬件将接收到的数据报文连续地存储在连续内存地址空间中,用户编写的应用程序通过接口函数接收存储在连续内存地址空间中的数据报文.
参见图2所示,从申请到的多片连续内存中确定一块连续内存地址空间具体包括以下步骤:
S120A,将申请到的每片连续内存的首地址存储到地址数组;
S120B,将地址数组中的连续内存的首地址根据大小进行排序;
S120C,在地址数组中根据排序后的首地址确定一块连续内存地址空间。
在步骤S120A中,每片连续内存的首地址是以数值形式表示,地址数组分为低端地址数组和高端地址数组,首地址小于4G的存储到低端地址数组,首地址大于或等于4G的存储到高端地址数组。低端地址数组和高端地址数组的划分,是因为Linux内核以4G为界将内存空间分为低端内存区域和高端内存区域。
在步骤S120B中,在多片连续内存的首地址存储到地址数组中之后,在地址数组中根据每片连续内存的首地址的大小将首地址进行排序。对首地址进行排序的目的是便于确定连续内存地址空间,因为所申请的每片连续内存大小是一样的,每个首地址对应一片连续内存,在连续内存地址空间的大小确定了之后也就确定了所需要的连续内存的片数。
当然在其他的实施例中,也可以在多片连续内存的首地址存储到地址数组过程中,边进行存储,边进行排序,排序不是等到存储结束之后才进行。过程虽然稍有差异,但效果是一样的,都可以方便确定连续内存地址空间。
在确定了连续内存地址空间之后,将需要用到的连续内存地址空间的首地址及大小保存至网卡驱动程序中,并按照页面大小将连续内存地址空间标记为保留页面。之所以将连续内存地址空间标记为保留页面,是因为在计算机操作系统内是按照页面大小来管理内存空间的。然后,将其他申请的而未使用的内存释放。在确定连续内存地址空间时首先选择在低端地址数组中确定,只有当低端地址数组对应的全部连续内存仍不足时才继续选择在高端地址数组中确定。由于Linux内核针对高端内存区域,需要建立映射表来完成物理地址和虚拟地址之间的映射。软、硬件都需要直接对连续内存地址空间进行操作,因此低端数组能更好地满足需求。
参见图3所示,本发明的一种零拷贝网络报文发送装置包括:申请模块210,用于在网卡驱动程序中申请连续内存;确定模块220,用于从申请模块210所申请到的连续内存中确定一块连续内存地址空间;以及发送模块230,用于使用确定模块220确定的连续内存地址空间进行网络报文发送。具体地说,网卡硬件将接收到的数据报文连续地存储在连续内存地址空间中,用户编写的应用程序通过接口函数接收存储在连续内存地址空间中的数据报文。其中,确定模块220具体包括:地址数组模块220-1,用于存储从申请模块210申请到的连续内存的首地址;排序模块220-2,用于对申请模块210申请到的连续内存的首地址进行排序;以及查找模块220-3,用于查找连续内存地址空间。
申请模块210在网卡驱动程序中申请特定大小的连续内存直至剩余的内存空间不足申请。
在确定模块220中,地址数组模块220-1储存申请到的多片连续内存的每一片连续内存的首地址,排序模块220-2对地址数组模块220-1中的首地址根据大小进行排序,查找模块220-3根据用户指定的发送报文DMA缓冲区的大小在地址数组模块220-1中查找一片或多片连续内存作为连续地址内存空间,连续地址内存空间大于或等于用户指定的发送报文DMA缓冲区的大小.
因为本发明的零拷贝网络报文发送方法和装置都是在网卡驱动程序中申请连续内存,从而使发送的数据报文连续存储在报文DMA缓冲区中,因此不需要将内存地址按页面大小转换成DMA操作所需的物理地址,网卡硬件在进行DMA操作时不受页面大小限制,网卡也不需要采用中断方式通知网卡驱动程序数据报文发送完成的情况,不占用CPU资源。
参见图4所示,本实施例的一种零拷贝网络报文接收方法,具体包括以下操作步骤:S310,使用内存分配函数在网卡驱动程序中不断地申请特定大小的连续内存直至网卡驱动程序中空闲的内存空间不足够申请;S320,从申请到的连续内存中确定一块连续内存地址空间;S330,使用连续内存地址空间进行网络报文接收。
在步骤S310中,特定大小是指内存分配函数所能申请的最大的连续内存的值,举例来说,在某些Linux操作系统中,利用内存分配函数能申请的最大连续内存为4M字节,内存分配函数不断地在网卡驱动程序中进行申请直至网卡驱动程序中空闲的内存空间小于内存分配函数所要申请的最大的连续内存,也即直至内存分配函数返回错误值时停止申请,在这个过程中内存分配函数会申请到多片连续内存。
在步骤S320中,从申请到的连续内存中确定一块连续内存地址空间,连续内存地址空间大于或等于用户指定的接收报文DMA缓冲区的大小。当需要确定的一块连续内存地址空间较小时,可能只需要一片申请到的连续内存即可,但是当需要确定的一块连续内存地址空间较大时,就会需要多片申请到的连续内存才能满足。
在步骤S330中,使用连续内存地址空间进行网络报文接收是指,用户编写的应用程序通过接口函数将预发送的数据报文连续地存储在连续内存地址空间中。当需要进行报文发送时,应用程序通过接口函数通知网卡硬件进行报文发送。
从申请到的多片连续内存中确定一块连续内存地址空间具体步骤如下:将申请到的每一片连续内存的首地址(实际上是以数值形式表示)存储到地址数组,地址数组分为低端地址数组和高端地址数组,首地址小于4G的存储到低端地址数组,首地址大于或等于4G的存储到高端地址数组;将地址数组中的连续内存的首地址根据大小进行排序,对首地址进行排序的目的是便于确定一块连续内存地址空间,因为所申请的每片连续内存大小是一样的,每个首地址对应一片连续内存,在需要确定的连续内存地址空间的大小确定了之后,也就确定了所需要的连续内存的片数;在低端地址数组中根据排序后首地址确定一块连续内存地址空间。
在确定了连续内存地址空间之后,将需要用到的连续内存地址空间的首地址及大小保存至网卡驱动程序中,并按照页面大小将连续内存地址空间标记为保留页面,并且将将其他申请的未使用的内存释放。在确定连续内存地址空间时首先选择在低端地址数组中确定,只有当低端地址数组对应的全部连续内存仍不足时才继续选择在高端地址数组中确定。由于Linux内核针对高端内存区域,需要建立映射表来完成物理地址和虚拟地址之间的映射。软、硬件都需要直接对连续内存地址空间进行操作,因此低端数组能更好地满足需求。
当然在其他的实施例中,也可以在多片连续内存的首地址存储到地址数组过程中,边进行存储,边进行排序,排序不是等到存储结束之后才进行.过程虽然稍有差异,但效果是一样的,都可以方便确定连续内存地址空间.
而在另外一个实施例中,从申请到的连续内存中确定一块连续内存地址空间的具体步骤包括:将连续内存作为报文DMA缓冲区,将报文DMA缓冲区的首地址和尾地址写入网卡相关寄存器中。网卡相关寄存器是64位大小的寄存器。
参见图5所示,本实施例的零拷贝网络报文接收装置包括:申请模块410,用于在网卡驱动程序中申请多块连续内存;确定模块420,用于从申请模块410所申请到的多片连续内存中确定一块连续内存地址空间;以及接收模块430,用于使用确定模块420确定的连续内存地址空间进行网络报文接收。
其中,确定模块420具体包括:地址数组模块420-1,用于存储从申请模块410申请到的连续内存的首地址;排序模块420-2,用于对首地址进行排序;以及查找模块420-3,用于查找连续内存地址空间。
申请模块410在网卡驱动程序中申请特定大小的连续内存直至剩余的内存空间不足申请。
在确定模块420中,地址数组模块420-1储存申请到的多片连续内存的每一片连续内存的首地址,排序模块420-2对地址数组模块420-1中的首地址根据大小进行排序,查找模块420-3根据用户指定的接收报文DMA缓冲区的大小在地址数组模块420-1中查找一片或多片连续内存作为连续地址内存空间,连续地址内存空间大于或等于用户指定的接收报文DMA缓冲区的大小。
因为本发明的零拷贝网络报文接收方法和装置都是在网卡驱动程序中申请连续内存,接收的数据报文连续存储在报文DMA缓冲区中,所以不需要将用户空间内存地址按页面大小转换成DMA操作所需的物理地址,因此网卡硬件在进行DMA操作时不受页面大小限制,这样即使进行大流量64字节短数据报文接收也不会出现报文丢弃的情况,而且网卡驱动程序不需要采用中断或轮询方式接收数据报文,不占用CUP资源。
以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。