DPDK 内存的初始化主要在rte_eal_init()函数中进行:

  • eal_hugepage_info_init()
/* 获取系统中hugepage种类以及数量信息到internal_config.hugepage_info,用于后续内存初始化 */if (internal_config.no_hugetlbfs == 0 &&internal_config.process_type != RTE_PROC_SECONDARY &&internal_config.xen_dom0_support == 0 &&eal_hugepage_info_init() < 0)rte_panic("Cannot get hugepage information\n");/* 获取系统中所有hugepage内存大小,计算方法:hugepage_sz*num_pages */if (internal_config.memory == 0 && internal_config.force_sockets == 0) {if (internal_config.no_hugetlbfs)internal_config.memory = MEMSIZE_IF_NO_HUGE_PAGE;}

这个函数比较简单,主要是从 /sys/kernel/mm/hugepages 目录下面读取目录名和文件名,从而获取系统的hugetlbfs文件系统数,
以及每个 hugetlbfs 的大页面数目和每个页面大小,并保存在一个文件里,这个函数,只有主进程会调用。存放在internal_config结构里

  • rte_eal_config_create()
    主要是初始化rte_config.mem_config。如果是以root用户运行dpdk程序的话,rte_config.mem_config指向/var/run/.rte_config文件mmap的一段sizeof(struct rte_mem_config)大小的内存。
    rte_config.mem_config = /var/run/.rte_config文件mmap的首地址;

/* create memory configuration in shared/mmap memory. Take out* a write lock on the memsegs, so we can auto-detect primary/secondary.* This means we never close the file while running (auto-close on exit).* We also don't lock the whole file, so that in future we can use read-locks* on other parts, e.g. memzones, to detect if there are running secondary* processes. */
static void
rte_eal_config_create(void)
{void *rte_mem_cfg_addr;int retval;const char *pathname = eal_runtime_config_path();  /* /var/run/.rte_config */if (internal_config.no_shconf)return;/* map the config before hugepage address so that we don't waste a page */if (internal_config.base_virtaddr != 0)rte_mem_cfg_addr = (void *)RTE_ALIGN_FLOOR(internal_config.base_virtaddr -sizeof(struct rte_mem_config), sysconf(_SC_PAGE_SIZE));elserte_mem_cfg_addr = NULL;if (mem_cfg_fd < 0){mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);if (mem_cfg_fd < 0)rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);}retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));if (retval < 0){close(mem_cfg_fd);rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);}retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);if (retval < 0){close(mem_cfg_fd);rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary ""process running?\n", pathname);}/* 将文件/var/run/.rte_config以共享方式mmap到主进程 即struct rte_mem_config*/rte_mem_cfg_addr = mmap(rte_mem_cfg_addr, sizeof(*rte_config.mem_config),PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);if (rte_mem_cfg_addr == MAP_FAILED){rte_panic("Cannot mmap memory for rte_config\n");}memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;/* store address of the config in the config itself so that secondary* processes could later map the config into this exact location */rte_config.mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;}
  • rte_eal_hugepage_init():primary进程中进行大页的映射

    主要是在文件系统hugetlbfs挂载的 目录(有些是/mnt/huge,但是172.16.6.139这台机器是挂载在/dev/hugepages下面)下创建hugetlbfs配置的内存页数(139设置为1024)的rtemap_xx文件,并为每个rtemap_xx文件做mmap映射,保证mmap后的虚拟地址与实际的物理地址是一样的。

  • rte_eal_memzone_init()函数
    memzone是内存分配器,上一步中,我们已经把大页内存分段放好了,但是在使用的时候,怎么来分配呢?自然需要内存分配器,就是memzone。而rte_eal_memzone_init主要就是把内存放到空闲链表中,等需要的时候,能够分配出去
    malloc_elem结构体表示一个内存对象

struct malloc_elem {struct malloc_heap *heap;struct malloc_elem *volatile prev;      /* points to prev elem in memseg */LIST_ENTRY(malloc_elem) free_list;      /* list of free elements in heap */const struct rte_memseg *ms;volatile enum elem_state state;uint32_t pad;size_t size;
#ifdef RTE_LIBRTE_MALLOC_DEBUGuint64_t header_cookie;         /* Cookie marking start of data *//* trailer cookie at start + size */
#endif
} __rte_cache_aligned;
int
rte_eal_malloc_heap_init(void)
{struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;unsigned ms_cnt;struct rte_memseg *ms;if (mcfg == NULL)return -1;/* 依次把每一段都添加到heap中,段属于哪个socket,就添加到哪个socket的heap中,分配就从这里拿 */for (ms = &mcfg->memseg[0], ms_cnt = 0;(ms_cnt < RTE_MAX_MEMSEG) && (ms->len > 0);ms_cnt++, ms++) {malloc_heap_add_memseg(&mcfg->malloc_heaps[ms->socket_id], ms);}return 0;
}
/** Expand the heap with a memseg.* This reserves the zone and sets a dummy malloc_elem header at the end* to prevent overflow. The rest of the zone is added to free list as a single* large free block*/
static void
malloc_heap_add_memseg(struct malloc_heap *heap, struct rte_memseg *ms)
{/* allocate the memory block headers, one at end, one at start */struct malloc_elem *start_elem = (struct malloc_elem *)ms->addr;struct malloc_elem *end_elem = RTE_PTR_ADD(ms->addr,ms->len - MALLOC_ELEM_OVERHEAD);end_elem = RTE_PTR_ALIGN_FLOOR(end_elem, RTE_CACHE_LINE_SIZE);const size_t elem_size = (uintptr_t)end_elem - (uintptr_t)start_elem;/* 把每一段做初始化,并挂在空闲链表中 */malloc_elem_init(start_elem, heap, ms, elem_size);malloc_elem_mkend(end_elem, start_elem);malloc_elem_free_list_insert(start_elem);heap->total_size += elem_size;
}

DPDK内存管理二:初始化相关推荐

  1. dpdk内存管理——内存初始化

    *说明:本系列博文源代码均来自dpdk17.02* 1.1内存初始化 1.1.1 hugepage技术 hugepage(2M/1G..)相对于普通的page(4K)来说有几个特点: (1) huge ...

  2. dpdk内存管理分析

    dpdk内存管理分析 文章目录 dpdk内存管理分析 1.1 简述 1.2 `rte_config_init`分析 1.3 `eal_hugepage_info_init`的分析 1.4 `rte_e ...

  3. DPDK 内存管理---malloc_heap和malloc_elem

    博文是基于dpdk20.5代码阅读所写,如理解有错误或不当之处,烦请指正,不甚感激.也可以私信我一起探讨. 两种数据结构体介绍 Malloc 库内部使用了两种数据结构类型(可以参考dpdk官方文档3. ...

  4. 启动期间的内存管理之初始化过程概述----Linux内存管理(九)

    转载地址:https://blog.csdn.net/gatieme/article/details/52403148 日期 内核版本 架构 作者 GitHub CSDN 2016-09-01 Lin ...

  5. dpdk内存管理之rte_eal_hugepage_init()函数分析

    dpdk版本:dpdk-stable-16.11.11 今天我们来看一下rte_eal_hugepage_init() 函数都干了哪些事. 1.计算大页总数 在调用rte_eal_hugepage_i ...

  6. DPDK内存管理总结

    1.前言 本文基于DPDK-17.05.2分析总结, DPDK通过使用hugetlbfs,减少CPU TLB表的Miss次数,提高性能. 2.Hugetlbfs初始化 DPDK的内存初始化工作,主要是 ...

  7. BOOST内存管理(二) --- boost::pool

    Boost库的pool提供了一个内存池分配器,用于管理在一个独立的.大的分配空间里的动态内存分配.Boost库的pool主要适用于快速分配同样大小的内存块,尤其是反复分配和释放同样大小的内存块的情况. ...

  8. 操作系统概念学习笔记 16 内存管理(二) 段页

    操作系统概念学习笔记 16 内存管理 (二) 分页(paging) 分页(paging)内存管理方案允许进程的物理地址空间可以使非连续的.分页避免了将不同大小的内存块匹配到交换空间上(前面叙述的内存管 ...

  9. android 设置setmultichoiceitems设置初始化勾选_Linux内核启动:虚拟盘空间设置和内存管理结构初始化...

    1. 设置虚拟盘并初始化 接下来main函数将对外设中的虚拟盘区进行设置. 检查makefile文件中"虚拟盘使用标志"是否设置, 以此确定系统是否使用了虚拟盘(假设有虚拟盘,大小 ...

最新文章

  1. linux应用之----多线程
  2. 简记模态对话框和非模态对话框
  3. linux公司常用基础命令必知必会一
  4. 一次SSIS Package的调试经历
  5. 电商设计师抢着用的液态水滴素材到底有多酷!
  6. 摩拜服务器维护,摩拜的后台是云服务器
  7. C/C++[codeup 1925]特殊排序
  8. docker 学习之使用dockerfile 创建镜像遇到的坑
  9. 关于MFC窗口句柄,窗口ID,窗口指针
  10. 程序员求职之道(《程序员面试笔试宝典》)之求职的时候该不该只看钱?
  11. Roberts算子,matlab代码实现
  12. 计算机二级实践网上教程答案,全国计算机等级二级教程课后习题+答案
  13. java 帕斯卡_Java编程实现帕斯卡三角形代码示例
  14. 〖全域运营实战白宝书 - 高转化文案速成篇④〗- 如何撰写摘要型文案?
  15. MSN关闭前爆发盗号“高潮” 中国用户面临选择
  16. linux 下的无线网络配置,详解在LINUX环境下怎样设置无线网络配置
  17. UGUI事件传递流程解析
  18. [原创]QQ农场外挂辅助程序-小萝莉偷菜机器人,提供下载。
  19. 【转】dB的计算方法
  20. 【java感悟】接口,抽象类的关系

热门文章

  1. Flink实战——每隔5秒,统计最近10秒的窗口数据
  2. 手机翻书效果html,移动端实现翻书效果
  3. 土木工程结构力学————钢架的位移法
  4. [paper]Defense against Adversarial Attacks Using High-Level Representation Guided Denoiser
  5. 基于51单片机的电子万年历的设计-源代码
  6. vm装linux不能上网 系统,VM 安装Linux后,以前的系统无法上网
  7. 三阶魔方CFOP还原方法图解
  8. mysql多条件count_Mysql中使用count加条件统计
  9. 电阻色环转换为阻值对照表
  10. 《Photoshop+Lightroom数码摄影后期处理经典教程》—第1章1.5节准备将Lightroom和Photoshop结合起来...