接续前节:[dpdk] 熟悉SDK与初步使用 (一)(qemu搭建实验环境)

程序逻辑:

运行参数:

关键API:

入口函数:

  int rte_eal_init(int argc, char **argv)

内存池函数:

  rte_pktmbuf_pool_create。  它是函数 rte_mempool_create 的一个封装。

  1. struct rte_mempool *
  2. rte_pktmbuf_pool_create(const char *name, unsigned n,
  3. unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
  4. 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()   用于在多个核上启动多线程,原例子中用法如下:

  1. /* call lcore_hello() on every slave lcore */
  2. RTE_LCORE_FOREACH_SLAVE(lcore_id) {
  3. rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
  4. }
            /* call it on master lcore too */
    //      lcore_hello(NULL);

  5.         
           lcore_id = rte_lcore_id();

  6.        printf("hello from master core %u\n", lcore_id);

主线程,跑着编号最小的那个核上,不知道是否可修改。

  1. [root@dpdk ~]# ps -eLF |grep -E "UID|helloworld"
  2. UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD
  3. root : pts/ :: ./helloworld -l4,,,
  4. root : pts/ :: ./helloworld -l4,,,
  5. root : pts/ :: ./helloworld -l4,,,
  6. root : pts/ :: ./helloworld -l4,,,
  7. root : pts/ :: ./helloworld -l4,,,
  8. root : pts/ :: grep --color=auto -E UID|helloworld
  9. [root@dpdk ~]#

数据结构:

  1. struct rte_mbuf {}

gdb之: 去掉 -O3

设断点:

  1. (gdb) info b
  2. Num Type Disp Enb Address What
  3. breakpoint keep y 0x0000000000435829 in lcore_main at /root/src/sdk/@dpdk/dpdk-stable-16.07./examples/skeleton/basicfwd.c:
  4. breakpoint already hit time
  5. (gdb) l
  6. for (;;) {
  7. /*
  8. 140 * Receive packets on a port and forward them on the paired
  9. 141 * port. The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc.
  10. 142 */
  11. for (port = ; port < nb_ports; port++) {
  12.  
  13. /* Get burst of RX packets, from first port of pair. */
  14. struct rte_mbuf *bufs[BURST_SIZE];
  15. const uint16_t nb_rx = rte_eth_rx_burst(port, ,
  16. (gdb)

debug一个包:

包格式如下:

进入断点,看数据结构,如下:

  1. (gdb) p bufs[]
  2. $ = (struct rte_mbuf *) 0x7fffd9791b00
  3. (gdb) p *bufs[]
  4. $ = {cacheline0 = 0x7fffd9791b00, buf_addr = 0x7fffd9791b80, buf_physaddr = , buf_len = , rearm_data = 0x7fffd9791b12 "\200", data_off = , {
  5. refcnt_atomic = {cnt = }, refcnt = }, nb_segs = '\001', port = '\000', ol_flags = , rx_descriptor_fields1 = 0x7fffd9791b20, {packet_type = , {
  6. l2_type = , l3_type = , l4_type = , tun_type = , inner_l2_type = , inner_l3_type = , inner_l4_type = }}, pkt_len = , data_len = , vlan_tci = ,
  7. hash = {rss = , fdir = {{{hash = , id = }, lo = }, hi = }, sched = {lo = , hi = }, usr = }, seqn = , vlan_tci_outer = , cacheline1 = 0x7fffd9791b40, {
  8. userdata = 0x0, udata64 = }, pool = 0x7fffd64436c0, next = 0x0, {tx_offload = , {l2_len = , l3_len = , l4_len = , tso_segsz = , outer_l3_len = ,
  9. outer_l2_len = }}, priv_size = , timesync = }
  10. (gdb) x/42xb (bufs[].buf_addr + )
  11. 0x7fffd9791c00: 0xff 0xff 0xff 0xff 0xff 0xff 0x00 0x00
  12. 0x7fffd9791c08: 0x00 0x01 0x00 0x01 0x08 0x06 0x00 0x01
  13. 0x7fffd9791c10: 0x08 0x00 0x06 0x04 0x00 0x01 0x00 0x00
  14. 0x7fffd9791c18: 0x00 0x01 0x00 0x01 0x01 0x01 0x01 0x01
  15. 0x7fffd9791c20: 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x01
  16. 0x7fffd9791c28: 0x01 0x02
  17. (gdb) where

回调函数和CPU cycle

  例子 rxtx_callback 在 skeleton 的基础之上增加了两个回调函数,在回调函数中做了cpu cycles的计算。

  rte_eth_add_rx_callback()

  rte_eth_add_tx_callback()

  关于CPU cycles可以参见另一篇博 [daily]使用rdtsc指令,测量程序的运行速度 [转]  

[dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)的更多相关文章

  1. [dpdk] 熟悉SDK与初步使用 (四)(L3 Forwarding源码分析)

    接续前节:[dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析) 前文中的最后一个问题,搁置,并没有找到答案.所以继续阅读其他例子的代码,想必定能在其他位置看到答案. ...

  2. Spring Environment(二)源码分析

    Spring Environment(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Envi ...

  3. Spring PropertyResolver 占位符解析(二)源码分析

    Spring PropertyResolver 占位符解析(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) ...

  4. Spring 循环引用(二)源码分析

    Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环引用相关文章: & ...

  5. Spring Boot REST(二)源码分析

    Spring Boot REST(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...

  6. Alink漫谈(二十二) :源码分析之聚类评估

    Alink漫谈(二十二) :源码分析之聚类评估 目录 Alink漫谈(二十二) :源码分析之聚类评估 0x00 摘要 0x01 背景概念 1.1 什么是聚类 1.2 聚类分析的方法 1.3 聚类评估 ...

  7. [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)

    对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...

  8. Android事件分发机制浅谈(二)--源码分析(ViewGroup篇)

    上节我们大致了解了事件分发机制的内容,大概流程,这一节来分析下事件分发的源代码. 我们先来分析ViewGroup中dispatchTouchEvent()中的源码 public boolean dis ...

  9. [dpdk] 熟悉SDK与初步使用 (一)(qemu搭建实验环境)

    搭建实验环境: troubleshoot 第一步加载驱动 第二步切换驱动 使用了所有qemu支持的卡 [tong@T7:~/VM/dpdk] % cat start.sh sudo qemu-syst ...

随机推荐

  1. [教程] 【玩转终端1:apt-get】

    进来工作比较清闲,所以写点东西,给喜欢折腾的朋友.本文及后面将要介绍的一些终端命令,其实对于玩过linux的人来说,是很基础的东西,我可能是班门弄斧了(拍砖的请轻点,有愿意补充/纠正的,本人求知不得) ...

  2. Eclipse 的单步调试

    1.设置断点在程序里面放置一个断点,也就是双击需要放置断点的程序左边的栏目上. 2.调试(1)点击"打开透视图"按钮,选择调试透视图,则打开调试透视图界面,然后先设置断点,按调试按 ...

  3. 没有活动事务 链接服务器的 OLE DB 访问接口 "SQLNCLI" 无法启动分布式事务

    在windows2003下执行分布式事务的时候出现如下情况. 一. 问题现象在执行分布式事务时,在sql server 2005下收到如下错误: 链接服务器"xxxxxxx"的 O ...

  4. 使用EmBitz开发STM32项目的环境配置

    一.EmBitz软件获取与安装 1.EmBitz软件的获取 EmBitz原名Em::Blocks,是基于Code::Blocks开发的,面向嵌入式的C/C++集成开发环境.支持J-Link和ST-Li ...

  5. 【数据采集】VBA数据采集可用 COM 组件

    windows 中提供了4个COM组件都可以进行数据采集. Wininet WinHttp XmlHttp MSHTML https://msdn.microsoft.com/en-us/librar ...

  6. sqlserver数据以及日志文件的设置小结

    1.1:增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情况下有一个主数据文件(MDF)就够了,但是有些大型的数据库,由于信息很多,而且查询频繁,所以为了提高 ...

  7. 小议ARM寄存器

    ARM微处理器一共有37个32位寄存器,其中包括31个通用寄存器和6个状态寄存器,但是这些寄存处不能同时访问.但是通用寄存器R14 - R0 ,程序计数器PC(即R15),程序状态寄存器都是可以任何时 ...

  8. 【Mybatis框架】查询缓存(二级缓存)

    继上一篇博客,我们讲述了mybatis的一级缓存,接下来,我们来学习一下mybatis的二级缓存 博客链接地址: http://blog.csdn.NET/liweizhong193516/artic ...

  9. Ecplise真机调试(Android)

    手机连电脑: 利用豌豆荚等工具安装驱动: 安卓手机打开开发人员选项,usb调试: 可以在cmd中执行sdk文件夹中的adb查看是否连接成功://adb devices 可将adb.exe所在文件路径加 ...

  10. mysql导入导出,及错误记录

    进入mysql的bin目录,如果mysql的bin添加了环境变量则不用. 导出,不指定编码则默认为:utf8mb4.: mysqldump -u root -h 127.0.0.1 -P 3307 - ...