DPDK关键技术

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

DPDK关键技术赵剑川2014.11.26概要DPDK是INTEL提供的提升数据面报文快速处理速率的应用程序开发包,它主要利用以下几个方面的支持特点来优化报文处理过程,从而加快报文处理速率:1、使用大页缓存支持来提高内存访问效率。2、利用UIO支持,提供应用空间下驱动程序的支持,也就是说网卡驱动是运行在用户空间的,减下了报文在用户空间和应用空间的多次拷贝。3、利用LINUX亲和性支持,把控制面线程及各个数据面线程绑定到不同的CPU核,节省了线程在各个CPU核来回调度。4、提供内存池和无锁环形缓存管理,加快内存访问效率。整个DPDK系统由许多不同组件组成,各组件为应用程序和其它组件提供调用接口,其结构图如下图所示:Dpdk各系统组件结构图Pci驱动Igb_uioHugepageKNIPciUiodevicememsegKNIlibSchedlibMemzoneMempoollibMalloclibPmddriverlibMastercoreSlavecoreintlogpipeCpufeaturePmde1000libPmdpcaplibNetprototollibarlarmPer-careandSharevariableDpdkapplicationblacklistNonepciTimerlibTailqueuedebugRinglibmbuflibPmdixgbelibPmdvirtiolibPmdringlibHash/LpmlibNoneDpdkapplicationtimerAB:表示模块A用到模块Bmeter/power1、环境抽象层:为DPDK其它组件和应用程序提供一个屏蔽具体平台特性的统一接口,EAL提供的功能主要有:DPDK加载和启动;支持多核或多线程执行类型;CPU核亲和性处理;原子操作和锁操作接口;时钟参考;PCI总线访问接口;跟踪和调试接口;CPU特性采集接口;中断和告警接口等。2、堆内存管理组件(Malloclib):堆内存管理组件为应用程序提供从大页内存分配堆内存的接口。当需要分配大量内存小块时(如用于存储列表中每个表项指针的内存),使用这些接口可以减少TLB缺页。3、环缓冲区管理组件:环缓冲区管理组件为应用程序和其它组件提供一个无锁的多生产者多消费者FIFO队列API。4、内存池管理组件:为应用程序和其它组件提供分配内存池的接口,内存池是一个由固定大小的多个内存块组成的内存容器,可用于存储相同对像实体,如报文缓存块等。内存池由内存池的名称(一个字符串)来唯一标识,它由一个环缓中区和一组核本地缓存队列组成,每个核从自已的缓存队列分配内存块,当本地缓存队列减少到一定程度时,从内存环缓冲区中申请内存块来补充本地队列。5、网络报文缓存块管理组件:提供应用程序创建和释放用于存储报文信息的缓存块的接口,这些MBUF存储在一内存池中。提供两种类型的MBUF,一种用于存储一般信息,一种用于存储报文数据。6、定时器组件:提供一些异步周期执行的接口(也可以只执行一次),可以指定某个函数在规定的时间异步的执行,就像LIBC中的timer定时器,但是这里的定时器需要应用程序在主循环中周期调用rte_timer_manage来使定时器得到执行,使用起来没有那么方便。定时器组件的时间参考来自EAL层提供的时间接口。除了以上六个核心组件外,DPDK还提供以下功能:1、以太网轮询模式驱动(PMD)架构:把以太网驱动从内核移到应用层,采用同步轮询机制而不是内核态的异步中断机制来提高报文的接收和发送效率。2、报文转发算法支持:Hash库和LPM库为报文转发算法提供支持。3、网络协议定义和相关宏定义:基于FreeBSDIP协议栈的相关定义如:TCP、UDP、SCTP等协议头定义。4、报文QOS调度库:支持随机早检测、流量整形、严格优先级和加权随机循环优先级调度等相关QOS功能。5、内核网络接口库(KNI):提供一种DPDK应用程序与内核协议栈的通信的方法,类似普通LINUX的TUN/TAP接口,但比TUN/TAP接口效率高。每个物理网口可以虚拟出多个KNI接口。以下分章节对各个组件单元进行详细分析。日志系统篇:1、全局日志变量rte_logsstructrte_logsrte_logs={.type=~0,.level=RTE_LOG_DEBUG,.file=NULL,};该变量用于存储日志文件的的FILE指针、日志打印级别、要记录的日志类型。2、日志类型:/*系统内部日志类型*/#defineRTE_LOGTYPE_EAL0x00000001/**Logrelatedtoeal.*/#defineRTE_LOGTYPE_MALLOC0x00000002/**Logrelatedtomalloc.*/#defineRTE_LOGTYPE_RING0x00000004/**Logrelatedtoring.*/#defineRTE_LOGTYPE_MEMPOOL0x00000008/**Logrelatedtomempool.*/#defineRTE_LOGTYPE_TIMER0x00000010/**Logrelatedtotimers.*/#defineRTE_LOGTYPE_PMD0x00000020/**Logrelatedtopollmodedriver.*/#defineRTE_LOGTYPE_HASH0x00000040/**Logrelatedtohashtable.*/#defineRTE_LOGTYPE_LPM0x00000080/**LogrelatedtoLPM.*/#defineRTE_LOGTYPE_KNI0x00000100/**LogrelatedtoKNI.*/#defineRTE_LOGTYPE_ACL0x00000200/**LogrelatedtoACL.*/#defineRTE_LOGTYPE_POWER0x00000400/**Logrelatedtopower.*/#defineRTE_LOGTYPE_METER0x00000800/**LogrelatedtoQoSmeter.*/#defineRTE_LOGTYPE_SCHED0x00001000/**LogrelatedtoQoSportscheduler.*//*用户可自定义的日志类型*/#defineRTE_LOGTYPE_USER10x01000000/**User-definedlogtype1.*/#defineRTE_LOGTYPE_USER20x02000000/**User-definedlogtype2.*/#defineRTE_LOGTYPE_USER30x04000000/**User-definedlogtype3.*/#defineRTE_LOGTYPE_USER40x08000000/**User-definedlogtype4.*/#defineRTE_LOGTYPE_USER50x10000000/**User-definedlogtype5.*/#defineRTE_LOGTYPE_USER60x20000000/**User-definedlogtype6.*/#defineRTE_LOGTYPE_USER70x40000000/**User-definedlogtype7.*/#defineRTE_LOGTYPE_USER80x80000000/**User-definedlogtype8.*/3、日志级别/*:Can'tuse0,asitgivescompilerwarnings*/#defineRTE_LOG_EMERG1U/**Systemisunusable.*/#defineRTE_LOG_ALERT2U/**Actionmustbetakenimmediately.*/#defineRTE_LOG_CRIT3U/**Criticalconditions.*/#defineRTE_LOG_ERR4U/**Errorconditions.*/#defineRTE_LOG_WARNING5U/**Warningconditions.*/#defineRTE_LOG_NOTICE6U/**Normalbutsignificantcondition.*/#defineRTE_LOG_INFO7U/**Informational.*/#defineRTE_LOG_DEBUG8U/**Debug-levelmessages.*/4、改写系统日志文件/***@paramf*文件流指针,可以是NULL,如果是NULL,系统使用默认日志文件流,如串口或syslog.rte_eal_log_init(constchar*id,intfacility)初始化时,已经把默认日专文件流设置为syslog*@return*-0onsuccess.*-Negativeonerror.*/intrte_openlog_stream(FILE*f);5、设计日志打印级别voidrte_set_log_level(uint32_tlevel);6、使能某个日志类型,使能之后,可以记录该类型的日志信息。voidrte_set_log_type(uint32_ttype,intenable);7、取得当前核中刚刚处理的日志消息类型和级别每个核处理日志消息时,会记录本该消息的类型和级别到一个变量中。intrte_log_cur_msg_loglevel(void);intrte_log_cur_msg_logtype(void);8、使能LOG存储记录voidrte_log_set_history(intenable);9、存储或显示历史记录,这个接口,日志是在标准输出中显示的intrte_log_add_in_history(constchar*buf,size_tsize);voidrte_log_dump_history(void);10、打印一条日志,这里会根据类型和级别,判断是否打印,如果打印,则打印到初始化时所设定的文件中。#defineRTE_LOG(l,t,...)\(void)(((RTE_LOG_##l=RTE_LOG_LEVEL)&&\(RTE_LOG_##l=rte_logs.level)&&\(RTE_LOGTYPE_##t&rte_logs.type))?\rte_log(RTE_LOG_##l,\RTE_LOGTYPE_##t,#t:__VA_ARGS__):\0)11、日志打印机制:#defineRTE_LOG(l,t,...)\(void)(((RTE_LOG_##l=RTE_LOG_LEVEL)&&\(RTE_LOG_##l=rte_logs.level)&&\(RTE_LOGTYPE_##t&rte_logs.type))?\rte_log(RTE_LOG_##l,\RTE_LOGTYPE_##t,#t:__VA_ARGS__):\0)上面调用先判断类型和级别,看是否需要记录,如果不需要,就什么都不做,如果需要就调用:rte_log(uint32_tlevel,uint32_tlogtype,constchar*format,...)-----rte_vlog(__attribute__((unused))uint32_tlevel,__attribute__((unused))uint32_tlogtype,constchar*format,va_listap){intret;FILE*f=rte_logs.file;unsignedlcore_id;/*记录正在打印的日志的类型和级别*/lcore_id=rte_lcore_id();log_cur_msg[lcore_id].loglevel=level;log_cur_msg[lcore_id].logtype=logtype;ret=vfprint

1 / 27
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功