转自:http://www.cnblogs.com/MerlinJ/p/4081986.html,作为记录参考
DPDK以两种方式对外提供内存管理方法,一个是rte_mempool,主要用于网卡数据包的收发;一个是rte_malloc,主要为应用程序提供内存使用接口。本文讨论rte_mempool。rte_mempool由函数rte_mempool_create()负责创建,从rte_config.mem_config->free_memseg[]中取出合适大小的内存,放到rte_config.mem_config->memzone[]中。
本文中,以l2fwd为例,说明rte_mempool的创建及使用。
一、rte_mempool的创建
1 l2fwd_pktmbuf_pool = 2 rte_mempool_create("mbuf_pool", NB_MBUF, 3 MBUF_SIZE, 32, 4 sizeof(struct rte_pktmbuf_pool_private), 5 rte_pktmbuf_pool_init, NULL, 6 rte_pktmbuf_init, NULL, 7 rte_socket_id(), 0);
“mbuf_pool”:创建的rte_mempool的名称。
NB_MBUF:rte_mempool包含的rte_mbuf元素的个数。
MBUF_SIZE:每个rte_mbuf元素的大小。
1 #define RTE_PKTMBUF_HEADROOM 128 2 #define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) 3 #define NB_MBUF 8192
1 struct rte_pktmbuf_pool_private { 2 uint16_t mbuf_data_room_size; /**< Size of data space in each mbuf.*/ 3 };
rte_mempool由函数rte_mempool_create()负责创建。首先创建rte_ring,再创建rte_mempool,并建立两者之间的关联。
1、rte_ring_create()创建rte_ring无锁队列
1 r = rte_ring_create(rg_name, rte_align32pow2(n+1), socket_id, rg_flags);
具体步骤如下:
a、需要保证创建的队列数可以被2整除,即,count = rte_align32pow2(n + 1);
b、计算需要为count个队列分配的内存空间,即,ring_size = count * sizeof(void *) + sizeof(struct rte_ring);
struct rte_ring的数据结构如下,
1 struct rte_ring { 2 TAILQ_ENTRY(rte_ring) next; /**< Next in list. */ 3 4 char name[RTE_RING_NAMESIZE]; /**< Name of the ring. */ 5 int flags; /**< Flags supplied at creation. */ 6 7 /** Ring producer status. */ 8 struct prod { 9 uint32_t watermark; /**< Maximum items before EDQUOT. */ 10 uint32_t sp_enqueue; /**< True, if single producer. */ 11 uint32_t size; /**< Size of ring. */ 12 uint32_t mask; /**< Mask (size-1) of ring. */ 13 volatile uint32_t head; /**< Producer head. */ 14 volatile uint32_t tail; /**< Producer tail. */ 15 } prod __rte_cache_aligned; 16 17 /** Ring consumer status. */ 18 struct cons { 19 uint32_t sc_dequeue; /**< True, if single consumer. */ 20 uint32_t size; /**< Size of the ring. */ 21 uint32_t mask; /**< Mask (size-1) of ring. */ 22 volatile uint32_t head; /**< Consumer head. */ 23 volatile uint32_t tail; /**< Consumer tail. */ 24 #ifdef RTE_RING_SPLIT_PROD_CONS 25 } cons __rte_cache_aligned; 26 #else 27 } cons; 28 #endif 29 30 #ifdef RTE_LIBRTE_RING_DEBUG 31 struct rte_ring_debug_stats stats[RTE_MAX_LCORE]; 32 #endif 33 34 void * ring[0] __rte_cache_aligned; /**< Memory space of ring starts here. 35 * not volatile so need to be careful 36 * about compiler re-ordering */ 37 };
c、调用rte_memzone_reserve(),在rte_config.mem_config->free_memseg[]中查找一个合适的free_memseg(查找规则是free_memseg中剩余内存大于等于需要分配的内存,但是多余的部分是最小的),从该free_memseg中分配指定大小的内存,然后将分配的内存记录在rte_config.mem_config->memzone[]中。
d、初始化新分配的rte_ring。
1 r->flags = flags; 2 r->prod.watermark = count; 3 r->prod.sp_enqueue = !!(flags & RING_F_SP_ENQ); 4 r->cons.sc_dequeue = !!(flags & RING_F_SC_DEQ); 5 r->prod.size = r->cons.size = count; 6 r->prod.mask = r->cons.mask = count-1; 7 r->prod.head = r->cons.head = 0; 8 r->prod.tail = r->cons.tail = 0; 9 10 TAILQ_INSERT_TAIL(ring_list, r, next); // 挂到rte_config.mem_config->tailq_head[RTE_TAILQ_RING]队列中
2、创建并初始化rte_mempool
a、计算需要为rte_mempool申请的内存空间。包含:sizeof(struct rte_mempool)、private_data_size,以及n * objsz.total_size。
1 mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size; 2 if (vaddr == NULL) 3 mempool_size += (size_t)objsz.total_size * n;
objsz.total_size = objsz.header_size + objsz.elt_size + objsz.trailer_size; 其中,
objsz.header_size = sizeof(struct rte_mempool *);
objsz.elt_size = MBUF_SIZE;
objsz.trailer_size = ????
b、调用rte_memzone_reserve(),在rte_config.mem_config->free_memseg[]中查找一个合适的free_memseg,在该free_memseg中分配mempool_size大小的内存,然后将新分配的内存记录到rte_config.mem_config->memzone[]中。
c、初始化新创建的rte_mempool,并调用rte_pktmbuf_pool_init()初始化rte_mempool的私有数据结构。
1 /* init the mempool structure */ 2 mp = mz->addr; 3 memset(mp, 0, sizeof(*mp)); 4 snprintf(mp->name, sizeof(mp->name), "%s", name); 5 mp->phys_addr = mz->phys_addr; 6 mp->ring = r; 7 mp->size = n; 8 mp->flags = flags; 9 mp->elt_size = objsz.elt_size; 10 mp->header_size = objsz.header_size; 11 mp->trailer_size = objsz.trailer_size; 12 mp->cache_size = cache_size; 13 mp->cache_flushthresh = (uint32_t) 14 (cache_size * CACHE_FLUSHTHRESH_MULTIPLIER); 15 mp->private_data_size = private_data_size; 16 17 /* calculate address of the first element for continuous mempool. */ 18 obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) + 19 private_data_size; 20 21 /* populate address translation fields. */ 22 mp->pg_num = pg_num; 23 mp->pg_shift = pg_shift; 24 mp->pg_mask = RTE_LEN2MASK(mp->pg_shift, typeof(mp->pg_mask)); 25 26 /* mempool elements allocated together with mempool */ 27 mp->elt_va_start = (uintptr_t)obj; 28 mp->elt_pa[0] = mp->phys_addr + 29 (mp->elt_va_start - (uintptr_t)mp); 30 31 mp->elt_va_end = mp->elt_va_start; 32 33 RTE_EAL_TAILQ_INSERT_TAIL(RTE_TAILQ_MEMPOOL, rte_mempool_list, mp); //挂到rte_config.mem_config->tailq_head[RTE_TAILQ_MEMPOOL]队列中
d、调用mempool_populate(),以及rte_pktmbuf_init()初始化rte_mempool的每个rte_mbuf元素。
3、总结
相关数据结构的关联关系如下图:
二、rte_mempool的调用
未完,待续。。。。
错误之处,欢迎指出。
在CentOS 7系统中配置非root用户的jmeter环境变量,通过编辑.bash_profile文件并添加export JMET命令来配置。确保配置生效后,可通过java -version命令查看java版本信息。参考链接:知乎和程序员宅基地。
文章浏览阅读7.6k次。L2-039 清点代码库 (25 分)Java (javac)时间限制1500 ms内存限制128 MBPython (python3)时间限制1500 ms内存限制64 MB其他编译器时间限制500 ms内存限制64 MB上图转自新浪微博:“阿里代码库有几亿行代码,但其中有很多功能重复的代码,比如单单快排就被重写了几百遍。请设计一个程序,能够将代码库中所有功能重复的代码找出。各位大佬有啥想法,我当时就懵了,然后就挂了。。。”这里我们把问题简化一下:首先假设两个功能模_l2-039 清点代码库 java
文章浏览阅读922次,点赞2次,收藏6次。题目详情:一个无重复的非负整数序列,必定对应唯一的一棵形状为完全二叉树的二叉搜索树。本题就要求你输出这棵树的层序遍历序列。输入格式:首先第一行给出一个正整数N(≤1000),随后第二行给出N个不重复的非负整数。数字间以空格分隔,所有数字不超过 2000。输出格式:在一行中输出这棵树的层序遍历序列。数字间以 1 个空格分隔,行首尾不得有多余空格。输入样例:101 2 3 4 5 6 7 8 9 0结尾无空行输出样例:6 3 8 1 5 7 9 0 2 4..._完全二叉搜索树 分数 10 作者 陈越 单位 浙江大学 一个无重复的非负整数序列,必定
文章浏览阅读72次。教程本刷机包比一般的大,是因为同时适配recovery卡刷和酷卓一键刷机。但是刷进系统后和普通刷机包都是一样的。注意事项(务必细读) 联想 ZUK Z1 免解锁BL(bootloader),一键ROOT是保资料的,刷机是会清空数据的(无论如何都请备份重要数据)卡刷方法卡刷需要已经安装了twrp recovery,直接传入手机后用twrp recovery刷机,和普通刷机包使用无区别..._zukz1被root了怎么办
文章浏览阅读590次。一、题目 编写支持双端队列的例程,插入与弹出操作均花费 O(1)时间二、解答 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的数据结构。 双端队列中的元素可以从两端弹出,插入和删除操作限定在队列的两边进行。 基本操作:在双端队列两端插入与删除。 ADT术语: ..._编写算法实现双端队列。数据结构分析
文章浏览阅读4.2k次。centos7安装clion下载clion的linux包。上传到linux服务器下。scp -P 20211 E:\迅雷下载\cmake-3.14.3.tar.gz 用户名@服务器地址:/home/bob/解压并到解压的文件夹bin目录下。运行命令“./clion.sh”。(需在centos7图形界面模式下才能启动clion)启动之后还不能运行c语言程序,我们还需要安装gcc、..._clion centos
文章浏览阅读382次。Multi-head attention 是一种在深度学习中的注意力机制。它在处理序列数据时,通过对不同位置的特征进行加权,来决定该位置特征的重要性。Multi-head attention 允许模型分别对不同的部分进行注意力,从而获得更多的表示能力。这在自然语言处理中,特别是在处理长文本时,可以显著提高模型性能。..._multi-head attention是什么
文章浏览阅读2.1k次。因初次编译安装php时没有开启openssl, 导致请求https网站报错, 为此需要手动编译openssl扩展然后添加到php.ini中. 问题就在自己明明已经编译安装生成openssl.so的步骤都没有错, 也已经将extension=openssl.so加入php.ini中,服务器也重启了, 但是无论是访问phpinfo()打印的出内容还是直接命令行php -m打印加载的模块都没有显示有加载..._php.ini加入了extension 不生效
文章浏览阅读8.1k次。这是linux中一个非常重要命令,请大家一定要熟悉。它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,具体用法是:ln -s 源文件 目标文件。当 我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的 目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间..._linux建立文件链接
文章浏览阅读5.2w次,点赞27次,收藏102次。摘要:本文主要说明了如何在Windows安装运行Kafka_kafak windows版
文章浏览阅读4.3k次,点赞2次,收藏11次。element里面表格的一个属性 formatter 叫格式化内容的_formatter
文章浏览阅读897次。(MIT6.828) 1.实验环境搭建参考官网:https://pdos.csail.mit.edu/6.828/2018/tools.html在ubuntu14中安装x86模拟器QEMU.1. 检查工具链objdump -i会看到elf32-i386等信息gcc -m32 -print-libgcc-file-name会看到/usr/lib/gcc/i486-linux-gnu..._mit6.828实验是否能在虚拟机上完成