linux内核协议栈与DPDK

linux内核网络协议栈越来越多的被关注,因为网络流量发生的巨大的变化,每小时的流量相当于过去几天的流量。

linux内核网络协议栈的性能本身就不好,一些内核协议栈的实现瓶颈被发现,因此即使10GE的网卡大量投入使用也没有带来预期的性能提升。

因此一些跳过内核来处理网络包的技术手段应允而生,主要目的是为了实现低延迟,低消耗,高吞吐的网络,典型代表是DPDK。

 

那么DPDK是如何处理报文的呢?在说明这个问题之前,我们先描述下linux内核的协议栈实现。

 

Linux内核收包处理流程:

1,当网卡收到报文后,通过DMA机制将报文放到内存

2,网卡触发中断通知系统有报文到达(一个报文,一个中断),系统分配sk_buff,将报文copy到这块sk_buff中,然后交由协议栈处理

3,经过协议栈处理,将报文上送用户态应用程序处理

从上面的简单描述可以看出,处理越多报文就消耗越多资源(中断,内存等):

a.一个报文一个中断,中断将打断CPU并且涉及上下文切换,将消耗系统资源

b.每个报文都要分配sk_buff,申请分配将消耗很多资源,同时linux为了兼容很多协议将sk_buff设计的过于复杂和庞大,导致处理变得缓慢。

c.其次,当用户态程序需要收发包时涉及多次系统调用和上下文切换,这些切换将消耗大量的系统资源。

为了解决a/b问题,Linux在2.6版本开始支持NAPI,大体原理如下:

网卡首先工作在中断模式,首包到达后中断处理程序处理报文,然后关闭网卡中断然后进入轮询模式,轮询检查网卡收包队列然后收包。

其中轮询模式处理函数由网卡驱动实现,初始化过程中挂接即可。

 

DPDK如何解决这些问题:

上图左侧表示内核处理报文流程,右侧表示DPDK处理报文流程。DPDK模式网卡完全由DPDK库接管。

DPDK通过将kernel bypass规避了内核处理报文的瓶颈,并且通过轮询模式,hugepage,线程的CPU亲和性,代码实现关注cache利用率,代码设计尽量减少互斥操作,代码设计尽量减少上下文切换等技术要点实现了高吞吐量,低延迟。

 

posted on 2018-04-15 20:44  llc_no1  阅读(1126)  评论(0编辑  收藏  举报

导航