DPDK RX / TX Callbacks 源码阅读
这个sample是基于basicfw的。basicfw就是一个网口收到的包立即从另一个网口转发出去,非常简洁明了的程序,可以通过basicfw学习基础的DPDK发包API。RX / TX Callbacks 演示在接收和传输的数据包上使用用户定义的回调函数。
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2015 Intel Corporation
*/
#include <stdint.h>
#include <inttypes.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_cycles.h>
#include <rte_lcore.h>
#include <rte_mbuf.h>
#define RX_RING_SIZE 1024
#define TX_RING_SIZE 1024
#define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250
#define BURST_SIZE 32
static const struct rte_eth_conf port_conf_default = {
.rxmode = {
.max_rx_pkt_len = ETHER_MAX_LEN,
.ignore_offload_bitfield = 1,
},
};
static struct {
uint64_t total_cycles;
uint64_t total_pkts;
} latency_numbers;
/* 回调函数的函数指针的格式设定:
一、rx
typedef uint16_t(* rte_rx_callback_fn)(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], uint16_t nb_pkts, uint16_t max_pkts, void *user_param)
参数:
1. port id
2. queue index
3. 接收的 burst pkt 所存放的 rte_mbuf 的数组
4. burst 中数据包的数量
5. 可以存储在pkts数组中的最大数据包数。
6. 最初配置回调时应用程序传入的任意用户参数
二、tx
typedef uint16_t(* rte_tx_callback_fn)(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], uint16_t nb_pkts, void *user_param)
参数:
1. port id
2. queue index
3. rte_mbuf的数组,里面的pkt即将被发送
4. burst 中数据包的数量
5. 最初配置回调时应用程序传入的任意用户参数
*/
// rx 队列的回调函数,添加接收时刻的时间戳
static uint16_t
add_timestamps(uint16_t port __rte_unused, uint16_t qidx __rte_unused,
struct rte_mbuf **pkts, uint16_t nb_pkts,
uint16_t max_pkts __rte_unused, void *_ __rte_unused)
{
unsigned i;
uint64_t now = rte_rdtsc(); // 用来获取时间戳计数器。
for (i = 0; i < nb_pkts; i++)
pkts[i]->udata64 = now; // 8字节用户数据
return nb_pkts;
}
// tx 队列的回调函数,发送时计算时延
static uint16_t
calc_latency(uint16_t port __rte_unused, uint16_t qidx __rte_unused,
struct rte_mbuf **pkts, uint16_t nb_pkts, void *_ __rte_unused)
{
uint64_t cycles = 0;
uint64_t now = rte_rdtsc();
unsigned i;
for (i = 0; i < nb_pkts; i++)
cycles += now - pkts[i]->udata64; // 在main.c中的全局struct中记录收到的包数量和总时延
latency_numbers.total_cycles += cycles;
latency_numbers.total_pkts += nb_pkts;
if (latency_numbers.total_pkts > (100 * 1000 * 1000ULL)) { // 每十亿个包计算平均时延
printf("Latency = %"PRIu64" cycles\n",
latency_numbers.total_cycles / latency_numbers.total_pkts);
latency_numbers.total_cycles = latency_numbers.total_pkts = 0;
}
return nb_pkts;
}
/*
* Initialises a given port using global settings and with the rx buffers
* coming from the mbuf_pool passed as parameter
*/
static inline int
port_init(uint16_t port, struct rte_mempool *mbuf_pool)
{
/*......*/
/*上面的部分和basicfw是一摸一样的*/
/* rte_eth_add_rx_callback() 这个API设定一个回调函数,特定 port id 和 rx queue index上每个收到的pkt(burst)都会进行突发调用。
参数四个:
1. port id
2. queue index
3. 回调函数的函数指针
4. 传递给回调函数的参数指针
返回值是一个指针,可以用于删除回调的API
rte_eth_add_tx_callback()就是为 tx queue 上的发包配置回调函数。
*/
// 回调函数指针有统一的 typedef
rte_eth_add_rx_callback(port, 0, add_timestamps, NULL);
rte_eth_add_tx_callback(port, 0, calc_latency, NULL);
return 0;
}
/*
* Main thread that does the work, reading from INPUT_PORT
* and writing to OUTPUT_PORT
*/
// lcore_main 与 basicfw 完全一样。
static __attribute__((noreturn)) void
lcore_main(void)
{
/*......*/
}
/* Main function, does initialisation and calls the per-lcore functions */
// main 函数也与 basicfw 一样。
int
main(int argc, char *argv[])
{
/*......*/
}
执行情况
开了之后运行了一会,得到了输出。应该开一个外部的发包器比较好。
root@ubuntu:/home/chang/dpdk/examples/rxtx_callbacks/build# ./rxtx_callbacks -l 1 -n 4
EAL: Detected 8 lcore(s)
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Multi-process socket /var/run/.rte_unix
EAL: Probing VFIO support...
EAL: PCI device 0000:02:01.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:02.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:03.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:04.0 on NUMA socket -1
EAL: Invalid NUMA socket, default to 0
EAL: probe driver: 8086:100f net_e1000_em
Port 0 MAC: 00 0c 29 f7 4d 25
Port 1 MAC: 00 0c 29 f7 4d 2f
Core 1 forwarding packets. [Ctrl+C to quit]
Latency = 629 cycles
Latency = 787 cycles
^C
参考
sample guide:https://doc.dpdk.org/guides/sample_app_ug/rxtx_callbacks.html
API:ethdev, mbuf
DPDK RX / TX Callbacks 源码阅读的更多相关文章
- 【原】SDWebImage源码阅读(三)
[原]SDWebImage源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1.SDWebImageDownloader中的downloadImageWithURL 我们 ...
- ng2048源码阅读
ng2048源码阅读 Tutorial: http://www.ng-newsletter.com/posts/building-2048-in-angularjs.html Github: http ...
- jQuery.Callbacks 源码解读二
一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...
- 【 js 基础 】【 源码学习 】backbone 源码阅读(一)
最近看完了 backbone.js 的源码,这里对于源码的细节就不再赘述了,大家可以 star 我的源码阅读项目(https://github.com/JiayiLi/source-code-stud ...
- Spring源码阅读笔记
前言 作为一个Java开发者,工作了几年后,越发觉力有点不从心了,技术的世界实在是太过于辽阔了,接触的东西越多,越感到前所未有的恐慌. 每天捣鼓这个捣鼓那个,结果回过头来,才发现这个也不通,那个也不精 ...
- Pytorch版本yolov3源码阅读
目录 Pytorch版本yolov3源码阅读 1. 阅读test.py 1.1 参数解读 1.2 data文件解析 1.3 cfg文件解析 1.4 根据cfg文件创建模块 1.5 YOLOLayer ...
- Flume-NG源码阅读之SourceRunner,及选择器selector和拦截器interceptor的执行
在AbstractConfigurationProvider类中loadSources方法会将所有的source进行封装成SourceRunner放到了Map<String, SourceRun ...
- Sping学习笔记(一)----Spring源码阅读环境的搭建
idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...
- Spring源码阅读 之 配置的读取,解析
在上文中我们已经知道了Spring如何从我们给定的位置加载到配置文件,并将文件包装成一个Resource对象.这篇文章我们将要探讨的就是,如何从这个Resouce对象中加载到我们的容器?加载到容器后又 ...
随机推荐
- jQuery带缩略图轮播效果图片切换带缩略图
以上为效果图 HTML代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /& ...
- 《The C Programming Language》读书笔记(一)
1. 对这本书的印象 2011年进入大学本科,C语言入门书籍如果我没记错的话应该是谭浩强的<C程序设计>,而用现在的眼光来看,这本书只能算是一本可用的教材,并不能说是一本好书.在自学操作系 ...
- SAP RANG语法
Range 和select-option 的变量是差不多的 sign = 'I' 或 sign = 'E' 是指INCLUED 和 EXCLUDE OPTION = 'EQ' 或其他操作符.. LO ...
- net辅助工具列表
最近对.net的辅助工具比较感兴趣,网上也已经有.net的十个必备工具的帖子了,这里提供了一份全面的工具列表: Code generation NVelocity CodeSmith X-Code . ...
- 20155327 李百乾 Exp4 恶意代码分析
20155327 李百乾 Exp4 恶意代码分析 基础问题回答 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所以想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法 ...
- 《Java 程序设计》课堂实践项目-简易计算器
<Java 程序设计>课堂实践项目简易计算器 课后学习总结 目录 改变 简易计算器实验要求 课堂实践成果 课后思考 改变 修改了博客整体布局,过去就贴个代码贴个图很草率,这次布局和内容都有 ...
- Noip前的大抱佛脚----考场配置
(global-linum-mode t) (global-set-key (kbd "RET") 'newline-and-indent) (setq default-tab-w ...
- 【转载】MSXML应用总结 开发篇(上)
原文:http://blog.sina.com.cn/s/blog_48f93b530100ejv9.html 本篇是接前文“MSXML应用总结 概念篇”写的,主要总结一下MSXML DOM接口的应用 ...
- 二维码QR Code简介及其解码实现(zxing-cpp)
二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种 ...
- Python day1 ---python基础1
本节内容 Python介绍 编程语言分类 Hello World程序 变量 字符编码 用户输入 数据类型初识 表达式if ...else语句 表达式while 循环 表达式for 循环 break a ...