DPDK内存管理-----rte_mbuf(转)
本文主要介绍rte_mbuf与rte_mempool数据结构之间的组织关系、以及网卡接收到的数据是如何存储在rte_mbuf中的。
一、rte_mbuf、rte_mempool及网卡收到的数据包在内存中的组织结构
调用rte_mempool_create()函数创建rte_mempool的时候,指定申请多少个rte_mbuff及每个rte_mbuf中elt_size的大小。elt_size是为网卡接收的数据包预先分配的内存的大小,该内存块就是rte_mbuf->pkt.data的实际存储区域。具体如上图所示。
在申请的rte_mempool内存块中,最前面存储struct rte_mempool数据结构,后面紧接着是rte_pktmbuf_pool_private数据,再后面就是N个rte_mbuf内存块。
每个rte_mbuf内存中,最前面同样存储的是struct rte_mbuf数据结果,后面是RTE_PKTMBUF_HEADROOM,最后面就是实际网卡接收到的数据,如下:
struct rte_mbuf *m = _m;
uint32_t buf_len = mp->elt_size - sizeof(struct rte_mbuf);
RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct rte_mbuf));
memset(m, , mp->elt_size);
/* start of buffer is just after mbuf structure */
m->buf_addr = (char *)m + sizeof(struct rte_mbuf);
m->buf_physaddr = rte_mempool_virt2phy(mp, m) +
sizeof(struct rte_mbuf);
m->buf_len = (uint16_t)buf_len;
/* keep some headroom between start of buffer and data */
m->pkt.data = (char*) m->buf_addr + RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len);
/* init some constant fields */
m->type = RTE_MBUF_PKT;
m->pool = mp;
m->pkt.nb_segs = ;
m->pkt.in_port = 0xff;
二、网卡接收的数据是如何存储到rte_mbuf中的?
以e1000网卡为例,在网卡初始化的时候,调用eth_igb_rx_init()初始化网卡的收包队列。每个收包队列数据结果如下:
/**
* Structure associated with each RX queue.
*/
struct igb_rx_queue {
struct rte_mempool *mb_pool; /**< mbuf pool to populate RX ring. */
volatile union e1000_adv_rx_desc *rx_ring; /**< RX ring virtual address. */
uint64_t rx_ring_phys_addr; /**< RX ring DMA address. */
volatile uint32_t *rdt_reg_addr; /**< RDT register address. */
volatile uint32_t *rdh_reg_addr; /**< RDH register address. */
struct igb_rx_entry *sw_ring; /**< address of RX software ring. */
struct rte_mbuf *pkt_first_seg; /**< First segment of current packet. */
struct rte_mbuf *pkt_last_seg; /**< Last segment of current packet. */
uint16_t nb_rx_desc; /**< number of RX descriptors. */
uint16_t rx_tail; /**< current value of RDT register. */
uint16_t nb_rx_hold; /**< number of held free RX desc. */
uint16_t rx_free_thresh; /**< max free RX desc to hold. */
uint16_t queue_id; /**< RX queue index. */
uint16_t reg_idx; /**< RX queue register index. */
uint8_t port_id; /**< Device port identifier. */
uint8_t pthresh; /**< Prefetch threshold register. */
uint8_t hthresh; /**< Host threshold register. */
uint8_t wthresh; /**< Write-back threshold register. */
uint8_t crc_len; /**< 0 if CRC stripped, 4 otherwise. */
uint8_t drop_en; /**< If not 0, set SRRCTL.Drop_En. */
};
我们只关注其中两个成员变量,rx_ring和sw_ring。rx_ring记录的是union e1000_adv_rx_desc数组,每个union e1000_adv_rx_desc中指定了网卡接收数据的DMA地址,网卡收到数据后,直接往该地址写数据。sw_ring数组记录的是每个具体的rte_mbuf地址,每个rte_mbuf的rte_mbuff->buf_phyaddr + RTE_PKTMBUF_HEADROOM映射后的DMA地址就存储在rx_ring队列的union e1000_adv_rx_desc数据结构中。rte_mbuff->buf_phyaddr + RTE_PKTMBUF_HEADROOM指向的就是rte_mbuf->pkt.data的地址。此时,rte_mbuf、rte_mbuf->pkt.data,已及网卡的收包队列就关联起来了。具体如下:
static int
igb_alloc_rx_queue_mbufs(struct igb_rx_queue *rxq)
{
struct igb_rx_entry *rxe = rxq->sw_ring;
uint64_t dma_addr;
unsigned i;
/* Initialize software ring entries. */
for (i = ; i < rxq->nb_rx_desc; i++) {
volatile union e1000_adv_rx_desc *rxd;
struct rte_mbuf *mbuf = rte_rxmbuf_alloc(rxq->mb_pool);
if (mbuf == NULL) {
PMD_INIT_LOG(ERR, "RX mbuf alloc failed "
"queue_id=%hu\n", rxq->queue_id);
return (-ENOMEM);
}
dma_addr =
rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR_DEFAULT(mbuf));
rxd = &rxq->rx_ring[i];
rxd->read.hdr_addr = dma_addr;
rxd->read.pkt_addr = dma_addr;
rxe[i].mbuf = mbuf;
}
return ;
}
网卡收到数据后,向rx_ring指定的DMA地址上写数据,其实,就是往每个rte_mbuf->pkt.data写数据。应用程序在调用rte_eth_rx_burst()收包时,以e1000网卡为例,最后调用的是eth_igb_recv_pkts(),就是从每个收包队列中,从sw_ring数组中将rte_mbuf取出来,然后重启申请新的rte_mbuf替换到rx_ring中,重新关联rte_mbuf、union e1000_adv_rx_desc、sw_ring以及rte_mbuf->pkt.data的DMA地址。如下简图所示。
DPDK内存管理-----rte_mbuf(转)的更多相关文章
- DPDK内存管理-----(二)rte_mempool内存管理
DPDK以两种方式对外提供内存管理方法,一个是rte_mempool,主要用于网卡数据包的收发:一个是rte_malloc,主要为应用程序提供内存使用接口.本文讨论rte_mempool.rte_me ...
- DPDK内存管理(1)
1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal 是统一 ...
- DPDK内存管理(1)(转)
1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal 是统一 ...
- DPDK内存管理-----(一)初始化
1 前言 DPDK通过使用hugetlbfs,减少CPU TLB表的Miss次数,提高性能. 2 初始化 DPDK的内存初始化工作,主要是将hugetlbfs的配置的大内存页,根据其映射的物理地址是否 ...
- DPDK内存管理-----(三)rte_malloc内存管理
rte_malloc()为程序运行过程中分配内存,模拟从堆中动态分配内存空间. void * rte_malloc(const char *type, size_t size, unsigned al ...
- rte_mempool内存管理
DPDK以两种方式对外提供内存管理方法,一个是rte_mempool,主要用于网卡数据包的收发:一个是rte_malloc,主要为应用程序提供内存使用接口.本文讨论rte_mempool.rte_me ...
- .NET基础拾遗(1)类型语法基础和内存管理基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...
- PHP扩展-生命周期和内存管理
1. PHP源码结构 PHP的内核子系统有两个,ZE(Zend Engine)和PHP Core.ZE负责将PHP脚本解析成机器码(也成为token符)后,在进程空间执行这些机器码:ZE还负责内存管理 ...
- linux2.6 内存管理——逻辑地址转换为线性地址(逻辑地址、线性地址、物理地址、虚拟地址)
Linux系统中的物理存储空间和虚拟存储空间的地址范围分别都是从0x00000000到0xFFFFFFFF,共4GB,但物理存储空间与虚拟存储空间布局完全不同.Linux运行在虚拟存储空间,并负责把系 ...
随机推荐
- Linux C 编程内存泄露检测工具(一):mtrace
前言 所有使用动态内存分配(dynamic memory allocation)的程序都有机会遇上内存泄露(memory leakage)问题,在Linux里有三种常用工具来检测内存泄露的情況,包括: ...
- AMD 规范使用总结
转自:http://www.jianshu.com/p/9b44a1fa8a96 AMD模式 define和require这两个定义模块.调用模块的方法,合称为AMD模式.它的模块定义的方法非常清晰, ...
- 《Javascript高级程序设计》阅读记录(五):第六章 上
这个系列以往文字地址: <Javascript高级程序设计>阅读记录(一):第二.三章 <Javascript高级程序设计>阅读记录(二):第四章 <Javascript ...
- BZOJ4930: 棋盘
BZOJ4930: 棋盘 https://lydsy.com/JudgeOnline/problem.php?id=4930 分析: 基本上就是游戏那道题加上费用流了,所以没啥好说的. 记得两边都是拆 ...
- [SP16549]QTREE6
luogu vjudge 题意 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.支持两种操作: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥有相同 ...
- [ Laravel 5.5 文档 ] 处理用户请求 —— HTTP 请求的过滤器:中间件
[ Laravel 5.5 文档 ] 处理用户请求 —— HTTP 请求的过滤器:中间件 http://laravelacademy.org/post/7812.html 简介 中间件为过滤进入应用的 ...
- Update多个字段从一个表中
UPDATE XXXXXX S SET (S.XXX, S.CCC, S.DDD, S.AAA, S.BBB) = (SELECT F.XXX, F.CCC, F.AAA, BBB FROM XXXX ...
- 机器学习:数据归一化(Scaler)
数据归一化(Feature Scaling) 一.为什么要进行数据归一化 原则:样本的所有特征,在特征空间中,对样本的距离产生的影响是同级的: 问题:特征数字化后,由于取值大小不同,造成特征空间中样本 ...
- 9个步骤:教你设计出优秀的MMORPG副本关卡
转自:http://www.gameres.com/664485.html 副本的定义 以一张场景地图为原型,针对单个玩家.队伍或者团队生成的一个实例,包含完整的开启关闭.怪物刷新.进度记录等逻辑. ...
- Git学习笔记(二)分支管理与合并及Bug分支
一.分支管理 1.什么是分支 分支就相当于我们看科幻片里的平行宇宙,如果两个平行宇宙互不干扰,那铁定是啥事儿没有.不过,在某个时间点,两个平行宇宙合并了呢?假如两个宇宙中都有你的影子, 合并之后相当于 ...