接续前节:[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      2671  2531  2671 99    5 274512 3668   4 18:44 pts/0    00:05:22 ./helloworld -l4,5,6,7
root      2671  2531  2672  0    5 274512 3668   4 18:44 pts/0    00:00:00 ./helloworld -l4,5,6,7
root      2671  2531  2673  0    5 274512 3668   5 18:44 pts/0    00:00:00 ./helloworld -l4,5,6,7
root      2671  2531  2674  0    5 274512 3668   6 18:44 pts/0    00:00:00 ./helloworld -l4,5,6,7
root      2671  2531  2675  0    5 274512 3668   7 18:44 pts/0    00:00:00 ./helloworld -l4,5,6,7
root      2778  2679  2778  0    1 28162   964   0 18:50 pts/1    00:00:00 grep --color=auto -E UID|helloworld
[root@dpdk ~]# 

数据结构:

struct rte_mbuf {}

gdb之: 去掉 -O3

设断点:

(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000435829 in lcore_main at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/skeleton/basicfwd.c:143breakpoint already hit 1 time
(gdb) l 143
138             for (;;) {
139                     /*
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                      */
143                     for (port = 0; port < nb_ports; port++) {
144
145                             /* Get burst of RX packets, from first port of pair. */
146                             struct rte_mbuf *bufs[BURST_SIZE];
147                             const uint16_t nb_rx = rte_eth_rx_burst(port, 0,
(gdb) 

debug一个包:

包格式如下:

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

(gdb) p bufs[0]
$20 = (struct rte_mbuf *) 0x7fffd9791b00
(gdb) p *bufs[0]
$21 = {cacheline0 = 0x7fffd9791b00, buf_addr = 0x7fffd9791b80, buf_physaddr = 972626816, buf_len = 2176, rearm_data = 0x7fffd9791b12 "\200", data_off = 128, {refcnt_atomic = {cnt = 1}, refcnt = 1}, nb_segs = 1 '\001', port = 0 '\000', ol_flags = 0, rx_descriptor_fields1 = 0x7fffd9791b20, {packet_type = 0, {l2_type = 0, l3_type = 0, l4_type = 0, tun_type = 0, inner_l2_type = 0, inner_l3_type = 0, inner_l4_type = 0}}, pkt_len = 42, data_len = 42, vlan_tci = 0, hash = {rss = 0, fdir = {{{hash = 0, id = 0}, lo = 0}, hi = 0}, sched = {lo = 0, hi = 0}, usr = 0}, seqn = 0, vlan_tci_outer = 0, cacheline1 = 0x7fffd9791b40, {userdata = 0x0, udata64 = 0}, pool = 0x7fffd64436c0, next = 0x0, {tx_offload = 0, {l2_len = 0, l3_len = 0, l4_len = 0, tso_segsz = 0, outer_l3_len = 0, outer_l2_len = 0}}, priv_size = 0, timesync = 0}
(gdb) x/42xb (bufs[0].buf_addr + 128)
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_rx_callback()

  rte_eth_add_tx_callback()

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

转载于:https://www.cnblogs.com/hugetong/p/6085704.html

[dpdk] 熟悉SDK与初步使用 (二)(skeleton源码分析)相关推荐

  1. Dubbo系列(二)源码分析之SPI机制

    Dubbo系列(二)源码分析之SPI机制 在阅读Dubbo源码时,常常看到 ExtensionLoader.getExtensionLoader(*.class).getAdaptiveExtensi ...

  2. AFL二三事——源码分析

    AFL二三事--源码分析 前言 AFL,全称"American Fuzzy Lop",是由安全研究员Michal Zalewski开发的一款基于覆盖引导(Coverage-guid ...

  3. RocksDB Compaction(二)源码分析

    本文的主要目的是(1)了解RocksDB源码中Flush和Compaction的基本流程(2)了解Compaction/FLush过程中是在何处.如何产生I/O的. 目录 线程调度过程&com ...

  4. Spring事务(二、源码分析之ThreadLocal)

    Thread在管理request作用域的Bean.事务管理.任务调度.AOP等模块中都有它的身影,所以想了解Spring事务管理的底层技术,ThreadLocal是必须攻克的"山头堡垒&qu ...

  5. SNMP功能开发简介 二 net-snmp源码分析报文处理流程图

    最近在开发snmp功能,核心实现是基于net-snmp,将net-snmp的代理基本功能移植到自己的程序中去,因为需要修改一些定制化的内容,所以需要对net-snmp的流程有所了解,网上这方面的资料比 ...

  6. OpenSees开发(二)源码分析——平面桁架静力有限元分析实例

    这是一个平面桁架静力分析算例,代码位于  OpenSees2.3.0\EXAMPLES\Example1\main.cpp 这里先给出原始源代码: // standard C++ includes#i ...

  7. Android Glide图片加载框架(二)源码解析之load()

    文章目录 一.前言 二.源码分析 1.load() Android Glide图片加载框架系列文章 Android Glide图片加载框架(一)基本用法 Android Glide图片加载框架(二)源 ...

  8. RocketMQ源码分析之RocketMQ事务消息实现原理上篇(二阶段提交)

    在阅读本文前,若您对RocketMQ技术感兴趣,请加入 RocketMQ技术交流群 根据上文的描述,发送事务消息的入口为: TransactionMQProducer#sendMessageInTra ...

  9. Spring Cloud源码分析(二)Ribbon(续)

    因文章长度限制,故分为两篇.上一篇:<Spring Cloud源码分析(二)Ribbon> 负载均衡策略 通过上一篇对Ribbon的源码解读,我们已经对Ribbon实现的负载均衡器以及其中 ...

  10. Android Glide图片加载框架(二)源码解析之into()

    文章目录 一.前言 二.源码解析 1.into(ImageView) 2.GlideContext.buildImageViewTarget() 3.RequestBuilder.into(Targe ...

最新文章

  1. 工程狮爸爸如何准备儿童节礼物?
  2. USACO2.1【bfs,排序,贪心,dfs,位运算】
  3. 解决苹果手机点击返回键页面不刷新问题
  4. 常见Promise面试题
  5. 在java中调用python程序
  6. 松翰单片机--SN8F5702学习笔记(七)TIMER0、TIMER1
  7. PAT备考经验相关信息
  8. 在WordPress中重新排序博客文章的4种简单方法(循序渐进)
  9. R语言ggplot2 | 如何自定义facet分面的坐标轴范围
  10. 速记TCP/IP五层模型
  11. Android加密文件系统
  12. 12、Kanzi插件——创建Kanzi Engine插件的方法
  13. 思维方式-《六顶思考帽》书中的精髓:通过在同一时间只使用一顶思考帽的方法,可以解决思维混乱等问题,从而提升思考效率。
  14. SprintBoot:Post请求的参数多一个逗号的解决方法
  15. Excel函数之~计算日期、天数、星期
  16. 五最好的应聘者可以问问题
  17. asn1编码格式的解析过程
  18. gif一键抠图 在线_强力推荐!免费在线的一键抠图神器:AIpix
  19. 数据采集卡 DAQmx
  20. 这款神奇的云端电脑可让你少装十几个软件

热门文章

  1. STL容器 之 list
  2. ios浏览器微信支付回调页面_iOS微信系列,WKWebview加载H5进行微信支付返回浏览器解决方案!...
  3. win7 32 java_Win7 32位系统下Java开发环境的安装及配置
  4. LightGBM 二元分类、多类分类、 Python的回归和分类器应用
  5. AutoViz:用一行代码自动可视化任何大小的任何数据集
  6. mysql中的utf-8_永远不要在MySQL中使用UTF-8
  7. 知识图谱、Gremlin Traversal Language、RDF、Amazon Nepture 图数据库介绍
  8. python决策树分类wine_Python写算法:二元决策树
  9. 2021-08-30缺失的第一个正数
  10. python 日志框架_按日期打印Python的Tornado框架中的日志的方法