DPDK学习记录11 - 内存初始化4之rte_eal_hugepage_init
1 rte_eal_hugepage_init
rte_eal_hugepage_init有两种模式:legacy和dynamic,默认是后者。我运行dpdk app时没有指定模式,所以gdb跟代码到了后者函数中。
int
rte_eal_hugepage_init(void)
{return internal_config.legacy_mem ?eal_legacy_hugepage_init() :eal_hugepage_init();
}
2 eal_hugepage_init
internal_config.socket_mem[hp_sz_idx] = 0;
internal_config.force_socket_limits = 0;
好像什么都没做,分支都不会进去。
static int
eal_hugepage_init(void)
{struct hugepage_info used_hp[MAX_HUGEPAGE_SIZES];uint64_t memory[RTE_MAX_NUMA_NODES];int hp_sz_idx, socket_id;test_phys_addrs_available();memset(used_hp, 0, sizeof(used_hp));for (hp_sz_idx = 0;hp_sz_idx < (int) internal_config.num_hugepage_sizes;hp_sz_idx++) {/* also initialize used_hp hugepage sizes in used_hp */struct hugepage_info *hpi;hpi = &internal_config.hugepage_info[hp_sz_idx];used_hp[hp_sz_idx].hugepage_sz = hpi->hugepage_sz;}/* make a copy of socket_mem, needed for balanced allocation. */for (hp_sz_idx = 0; hp_sz_idx < RTE_MAX_NUMA_NODES; hp_sz_idx++)memory[hp_sz_idx] = internal_config.socket_mem[hp_sz_idx];/* calculate final number of pages */ //calc_num_pages_per_socket返回值为0,且used_hp没有被修改。if (calc_num_pages_per_socket(memory,internal_config.hugepage_info,used_hp,internal_config.num_hugepage_sizes) < 0)return -1;for (hp_sz_idx = 0; hp_sz_idx < (int)internal_config.num_hugepage_sizes;hp_sz_idx++) {for (socket_id = 0; socket_id < RTE_MAX_NUMA_NODES;socket_id++) {struct rte_memseg **pages;struct hugepage_info *hpi = &used_hp[hp_sz_idx];unsigned int num_pages = hpi->num_pages[socket_id]; int num_pages_alloc, i;if (num_pages == 0) //这里都是0,每次都是被continue;continue;pages = malloc(sizeof(*pages) * num_pages);num_pages_alloc = eal_memalloc_alloc_seg_bulk(pages,num_pages, hpi->hugepage_sz,socket_id, true);if (num_pages_alloc < 0) {free(pages);return -1;}/* mark preallocated pages as unfreeable */for (i = 0; i < num_pages_alloc; i++) {struct rte_memseg *ms = pages[i];ms->flags |= RTE_MEMSEG_FLAG_DO_NOT_FREE;}free(pages);}}/* if socket limits were specified, set them */if (internal_config.force_socket_limits) { //internal_config.force_socket_limits = 0unsigned int i; for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {uint64_t limit = internal_config.socket_limit[i];if (limit == 0)continue;if (rte_mem_alloc_validator_register("socket-limit",limits_callback, i, limit))RTE_LOG(ERR, EAL, "Failed to register socket limits validator callback\n");}}return 0;
}
3 calc_num_pages_per_socket
internal_config.force_sockets = 0;
total_mem = internal_config.memory = 0;
total_size = internal_config.memory = 0;
internal_config.socket_mem[socket] = 0
上面几个都会0,会导致所有的分支都不能进去,所以hp_used不会被改变,返回值total_num_pages为初始值0。
static int calc_num_pages_per_socket(uint64_t * memory, struct hugepage_info *hp_info,struct hugepage_info *hp_used,unsigned num_hp_info)
{int total_num_pages = 0;uint64_t total_mem = internal_config.memory;if (num_hp_info == 0)return -1;/* if specific memory amounts per socket weren't requested */if (internal_config.force_sockets == 0) {total_size = internal_config.memory;for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_size != 0; socket++) {/* Set memory amount per socket */default_size = (internal_config.memory * cpu_per_socket[socket])/ rte_lcore_count();/* Limit to maximum available memory on socket */default_size = RTE_MIN(default_size, get_socket_mem_size(socket));/* Update sizes */memory[socket] = default_size;total_size -= default_size;}for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_size != 0; socket++) {/* take whatever is available */default_size = RTE_MIN(get_socket_mem_size(socket) - memory[socket],total_size);/* Update sizes */memory[socket] += default_size;total_size -= default_size;}}for (socket = 0; socket < RTE_MAX_NUMA_NODES && total_mem != 0; socket++) {/* skips if the memory on specific socket wasn't requested */for (i = 0; i < num_hp_info && memory[socket] != 0; i++){strlcpy(hp_used[i].hugedir, hp_info[i].hugedir,sizeof(hp_used[i].hugedir));hp_used[i].num_pages[socket] = RTE_MIN(memory[socket] / hp_info[i].hugepage_sz,hp_info[i].num_pages[socket]);cur_mem = hp_used[i].num_pages[socket] *hp_used[i].hugepage_sz;memory[socket] -= cur_mem;total_mem -= cur_mem;total_num_pages += hp_used[i].num_pages[socket];/* check if we have met all memory requests */if (memory[socket] == 0)break;/* check if we have any more pages left at this size, if so* move on to next size */if (hp_used[i].num_pages[socket] == hp_info[i].num_pages[socket])continue;/* At this point we know that there are more pages available that are* bigger than the memory we want, so lets see if we can get enough* from other page sizes.*/remaining_mem = 0;for (j = i+1; j < num_hp_info; j++)remaining_mem += hp_info[j].hugepage_sz *hp_info[j].num_pages[socket];/* is there enough other memory, if not allocate another page and quit */if (remaining_mem < memory[socket]){cur_mem = RTE_MIN(memory[socket],hp_info[i].hugepage_sz);memory[socket] -= cur_mem;total_mem -= cur_mem;hp_used[i].num_pages[socket]++;total_num_pages++;break; /* we are done with this socket*/}}/* if we didn't satisfy all memory requirements per socket */if (memory[socket] > 0 &&internal_config.socket_mem[socket] != 0) {/* to prevent icc errors */requested = (unsigned) (internal_config.socket_mem[socket] /0x100000);available = requested -((unsigned) (memory[socket] / 0x100000));RTE_LOG(ERR, EAL, "Not enough memory available on socket %u! ""Requested: %uMB, available: %uMB\n", socket,requested, available);return -1;}}/* if we didn't satisfy total memory requirements */if (total_mem > 0) {requested = (unsigned) (internal_config.memory / 0x100000);available = requested - (unsigned) (total_mem / 0x100000);RTE_LOG(ERR, EAL, "Not enough memory available! Requested: %uMB,"" available: %uMB\n", requested, available);return -1;}return total_num_pages;
}
4 总结
在我当前什么都没有配置的情况下,貌似rte_eal_hugepage_init什么都没有操作。
DPDK学习记录11 - 内存初始化4之rte_eal_hugepage_init相关推荐
- DDR SDRAM 学习笔记 —— DDR4 内存初始化过程 之 Multi Purpose Register (MPR Read)
DDR4 Multi Purpose Register (MPR) 我是谁?-- MPR 简介 MRP 其实是物理上真是存在的寄存器,简单理解就是存储 0/1 的器件.所以啊,它设计时,是独立于 ce ...
- 吴恩达深度学习 —— 3.11 随机初始化
当你训练神经网络的时候,随机初始化权重非常重要,对于逻辑回归,可以将权重初始化为零,但如果将神经网络的各参数数组全部初始化为0,再使用梯度下降算法那会完全无效,让我们看看是什么原因. 如上图,神经网络 ...
- GDI+ 学习记录(11): 路径渐变画刷 - PathGradientBrush
为什么80%的码农都做不了架构师?>>> //路径渐变画刷 varg: TGPGraphics;path: TGPGraphicsPath;pb: TGPPathGradien ...
- Linux学习记录-11
章节简述: 本章先向读者科普什么是Web服务程序,以及Web服务程序的用处,然后通过对比当前主流的Web服务程序来使读者更好地理解其各自的优势及特点,最后通过对httpd服务程序中"全局配置 ...
- 编程学习记录11:Oracle数据库的一些基本操作1,创建用户,授权
登录指令: 初始管理员登录,在命令窗口输入sqlplus / as sysdba 进行登录, 普通用户登录 在命令窗口输入sqlplus 后会出现输入账号密码,输入密码时不会显示. 修改用户指令: 创 ...
- Java零基础学习记录11(抽象方法、接口、内部类)
** 1. 抽象类和抽象方法 ** (1) 简述抽象方法的特征 1.抽象方法中可有成员变量.成员方法.静态方法.final所修饰的方法.abstract所修饰的方法. 2.抽象方法只能声明在抽象类中( ...
- Java设计模式学习记录-单例模式
前言 已经介绍和学习了两个创建型模式了,今天来学习一下另一个非常常见的创建型模式,单例模式. 单例模式也被称为单件模式(或单体模式),主要作用是控制某个类型的实例数量是一个,而且只有一个. 单例模式 ...
- dpdk内存管理——内存初始化
*说明:本系列博文源代码均来自dpdk17.02* 1.1内存初始化 1.1.1 hugepage技术 hugepage(2M/1G..)相对于普通的page(4K)来说有几个特点: (1) huge ...
- dpdk代码分析——内存初始化
一. 前言 dpdk 是 intel 开发的x86芯片上用于高性能网络处理的基础库,业内比较常用的模式是linux-app模式,即利用该基础库,在用户层空间做数据包处理,有了这个基础库,可以方便地在写 ...
最新文章
- Spring Boot日志学习记录【2】
- 信息安全技术 网络安全等级保护测评要求_【诚资讯】等保2.0版本出炉!信息安全技术 网络安全等级保护基本要求正式发布...
- bind-utils.x86_64(dig) 安装失败解决办法
- js检测鼠标是否在操作_原生JS趣味demo:炫酷头像鼠标追随效果的实现
- 李洪强iOS开发之- 实现简单的弹窗
- ASP.NET Core基于K8S的微服务电商案例实践--学习笔记
- XEIM 飞鸽传书数据库说明
- 国内外独立IP行情及网站用独立IP优势面面观
- 可见光迁移——学习笔记
- [译]反射(Reflection)和动态(dynamic)
- c语言单片机烧写器,单片机烧写器是什么 烧写器怎么用
- java验证码提交错误时_验证码输入错误后自动刷新验证码
- java生成密码生成
- 【自媒体营销神器】一键自动下载短视频并分发至长视频平台脚本开源展示
- 猴子分桃子,递归算法简练通俗易懂
- vue中阻止表单自动提交
- 古文观止卷七_春夜宴桃李園序_李白
- Mybatis日志源码探究
- 子类调用父类构造器《转载》
- 教你快速打出左角括号、右角括号「」(直角括号)