[dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)
接续前节:[dpdk] 熟悉SDK与初步使用 (一)(qemu搭建实验环境)
程序逻辑:
运行参数:
关键API:
入口函数:
int rte_eal_init(int argc, char **argv)
内存池函数:
rte_pktmbuf_pool_create。 它是函数 rte_mempool_create 的一个封装。
struct rte_mempool *
rte_pktmbuf_pool_create(const char *name, unsigned n,
unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
int socket_id)
name是内存池名字。为了获得更好的性能,n应该为2的幂减1 。
网卡操作函数:
rte_eth_dev_configure() 设置网卡设备。在其他操作之前,应该先调用这个函数进行设置。
rte_eth_rx_queue_setup() 申请并设置一个收包队列。
关键参数:
struct rte_mempool *mp; 由前文创建的pool
rte_eth_tx_queue_setup() 同上。
rte_eth_dev_start() 就是设置好了之后就启动啊,该收的收,该发的发。
rte_eth_promiscuous_enable() 启动混杂模式,不解释。
收发包函数:
rte_eth_rx_burst() 收一大批包
该接口不提供任何错误检测功能,上层应用可以在返回包数为零时,去主动检测link状态来完成接口异常及错误检测机制。
关键参数:
struct rte_mbuf** rx_pkts; 一个指针数组,数组中的每一个指针指向收取到的一个包,具体的包结构查看下文的数据结构章节。指针所指向的内存空间为queue_setup(mpool) 函数中的参数pool提供。
const uint16_t nb_pkts; 简单来说,就是数组大小。
返回值:
收到的报数,数组中被填充的item个数。
当返回值== nb_pkts时,隐含说明,收包性能已经跟不上了。
当返回值== 0 时,应该启动异常检测,查看接口状态等。
rte_eth_tx_burst() 发一大批包
rte_pktmbuf_free() 收到了但是没有被发出去的包,应该将其free,即还给mpool。咦,不过为什么会有没发出去的呢?奇怪
其他函数:
rte_eth_dev_count():
返回可以被dpdk使用的网口个数。即(加载了UIO驱动,或VFIO ??) rte_eal_init 之后就可以用了。
rte_socket_id():
返回CPU sock 的ID,即命令参数中指定的lcore所属的CPU socket。
回过头来,对比一下Helloworld。在helloworld里多使用了一个函数
rte_eal_remote_launch() 用于在多个核上启动多线程,原例子中用法如下:
/* call lcore_hello() on every slave lcore */
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
}
/* call it on master lcore too */
// lcore_hello(NULL);
lcore_id = rte_lcore_id();
printf("hello from master core %u\n", lcore_id);
主线程,跑着编号最小的那个核上,不知道是否可修改。
[root@dpdk ~]# ps -eLF |grep -E "UID|helloworld"
UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD
root : pts/ :: ./helloworld -l4,,,
root : pts/ :: ./helloworld -l4,,,
root : pts/ :: ./helloworld -l4,,,
root : pts/ :: ./helloworld -l4,,,
root : pts/ :: ./helloworld -l4,,,
root : pts/ :: grep --color=auto -E UID|helloworld
[root@dpdk ~]#
数据结构:
struct rte_mbuf {}
gdb之: 去掉 -O3
设断点:
(gdb) info b
Num Type Disp Enb Address What
breakpoint keep y 0x0000000000435829 in lcore_main at /root/src/sdk/@dpdk/dpdk-stable-16.07./examples/skeleton/basicfwd.c:
breakpoint already hit time
(gdb) l
for (;;) {
/*
140 * Receive packets on a port and forward them on the paired
141 * port. The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc.
142 */
for (port = ; port < nb_ports; port++) { /* Get burst of RX packets, from first port of pair. */
struct rte_mbuf *bufs[BURST_SIZE];
const uint16_t nb_rx = rte_eth_rx_burst(port, ,
(gdb)
debug一个包:
包格式如下:
进入断点,看数据结构,如下:
(gdb) p bufs[]
$ = (struct rte_mbuf *) 0x7fffd9791b00
(gdb) p *bufs[]
$ = {cacheline0 = 0x7fffd9791b00, buf_addr = 0x7fffd9791b80, buf_physaddr = , buf_len = , rearm_data = 0x7fffd9791b12 "\200", data_off = , {
refcnt_atomic = {cnt = }, refcnt = }, nb_segs = '\001', port = '\000', ol_flags = , rx_descriptor_fields1 = 0x7fffd9791b20, {packet_type = , {
l2_type = , l3_type = , l4_type = , tun_type = , inner_l2_type = , inner_l3_type = , inner_l4_type = }}, pkt_len = , data_len = , vlan_tci = ,
hash = {rss = , fdir = {{{hash = , id = }, lo = }, hi = }, sched = {lo = , hi = }, usr = }, seqn = , vlan_tci_outer = , cacheline1 = 0x7fffd9791b40, {
userdata = 0x0, udata64 = }, pool = 0x7fffd64436c0, next = 0x0, {tx_offload = , {l2_len = , l3_len = , l4_len = , tso_segsz = , outer_l3_len = ,
outer_l2_len = }}, priv_size = , timesync = }
(gdb) x/42xb (bufs[].buf_addr + )
0x7fffd9791c00: 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00
0x7fffd9791c08: 0x00 0x01 0x00 0x01 0x08 0x06 0x00 0x01
0x7fffd9791c10: 0x08 0x00 0x06 0x04 0x00 0x01 0x00 0x00
0x7fffd9791c18: 0x00 0x01 0x00 0x01 0x01 0x01 0x01 0x01
0x7fffd9791c20: 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x01
0x7fffd9791c28: 0x01 0x02
(gdb) where
回调函数和CPU cycle
例子 rxtx_callback 在 skeleton 的基础之上增加了两个回调函数,在回调函数中做了cpu cycles的计算。
rte_eth_add_tx_callback()
关于CPU cycles可以参见另一篇博 [daily]使用rdtsc指令,测量程序的运行速度 [转]
[dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)的更多相关文章
- [dpdk] 熟悉SDK与初步使用 (四)(L3 Forwarding源码分析)
接续前节:[dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析) 前文中的最后一个问题,搁置,并没有找到答案.所以继续阅读其他例子的代码,想必定能在其他位置看到答案. ...
- Spring Environment(二)源码分析
Spring Environment(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Envi ...
- Spring PropertyResolver 占位符解析(二)源码分析
Spring PropertyResolver 占位符解析(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) ...
- Spring 循环引用(二)源码分析
Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环引用相关文章: & ...
- Spring Boot REST(二)源码分析
Spring Boot REST(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...
- Alink漫谈(二十二) :源码分析之聚类评估
Alink漫谈(二十二) :源码分析之聚类评估 目录 Alink漫谈(二十二) :源码分析之聚类评估 0x00 摘要 0x01 背景概念 1.1 什么是聚类 1.2 聚类分析的方法 1.3 聚类评估 ...
- [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)
对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...
- Android事件分发机制浅谈(二)--源码分析(ViewGroup篇)
上节我们大致了解了事件分发机制的内容,大概流程,这一节来分析下事件分发的源代码. 我们先来分析ViewGroup中dispatchTouchEvent()中的源码 public boolean dis ...
- [dpdk] 熟悉SDK与初步使用 (一)(qemu搭建实验环境)
搭建实验环境: troubleshoot 第一步加载驱动 第二步切换驱动 使用了所有qemu支持的卡 [tong@T7:~/VM/dpdk] % cat start.sh sudo qemu-syst ...
随机推荐
- 无密钥登录的自动脚本实现(ssh-copy-id、expect免交互输入脚本)
感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正! 如有转载,请保留源作者博客信息. Better Me的博客:blog.csdn.net/tantexian 如需 ...
- ios显示或隐藏导航栏的底线
根据产品需求要求把这个界面导航栏的底线去掉,下个控制器还需要有底线. 使用下面的代码实现 //在页面出现的时候就将黑线隐藏起来 -(void)viewWillAppear:(BOOL)animated ...
- 全选、取消、2级 checkbox的选中切换
需求:点击父级checkbox的时候,子级出现全选或全取消:点击子级时,如:子级都是在未选中时,点击某一个子级,则父级选中:如:子级中只有一个选中状态(其他子级都是未选中),点击该子级,则父级也改为未 ...
- 【转】Caffe初试(六)激活层及参数
在激活层中,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的.从bottom得到一个blob数据输入,运算后,从top输入一个blob数据.在运算过程中,没有改变数据的大小,即输入 ...
- C#学习笔记---Dispose(),Finalize(),SuppressFinalize
http://www.cnblogs.com/eddyshn/archive/2009/08/19/1549961.html 在.NET的对象中实际上有两个用于释放资源的函数:Dispose和Fina ...
- Expression: is_block_type_valid(header->block_use)
VS2015 用 openmesh read_mesh 读取网格时,这样一段代码 void CPathFace::test2() { string file = ".\\data\\fa ...
- CLR VIA C# 学习笔记
第19章 可空类型 1)使用Nullable<T>可将int32的值类型设置为Null,CLR会在Null时默认赋值为0; 如:Nullable<T> x=null; //使用 ...
- [leetcode] 题型整理之查找
1. 普通的二分法查找查找等于target的数字 2. 还可以查找小于target的数字中最小的数字和大于target的数字中最大的数字 由于新的查找结果总是比旧的查找结果更接近于target,因此只 ...
- java线程池ThreadPoolExecutor使用简介
一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...
- Java(Helloworld.java)
public class A{ public static void main(String args[]){ System.out.println("Hello world!") ...