DPDK 初识DPDK(十五)

EAL

首先必须明白的一点就是, DPDK 是以若干个 lib 的形式提供给应用链接使用,其中最终要的一个 lib 就是 EAL 了, EAL 的全称是(Environment Abstraction Layer, 环境抽象层),它负责为应用间接访问底层的资源,比如内存空间、线程、设备、定时器等。如果把我们的应用比作一个豪宅的主人的话, EAL 就是这个豪宅的管家。

lcore & socket

这两个概念在 DPDK 的代码中随处可见, 注意 这里的 socket 不是网络编程里面的那一套东西,而是 CPU 相关的东西。具体的概念可以参看 Differences between physical CPU vs logical CPU vs Core vs Thread vs Socket 或者其翻译版本 physical CPU vs logical CPU vs Core vs Thread vs Socket(翻译)

对我们来说,只要知道可以 DPDK 可以运行在多个 lcore 上就足够了.

DPDK 如何知道有多少个 lcore 呢 ? 在启动时解析文件系统中的特定文件就可以了, 参考函数 eal_cpu_detected

组成模块

  • rte_timer,包装提供内核的Time-Stamp Couter(TSC)时间服务,让异步执行函数成为可能
  • rte_malloc,从memzones中分配大页,相较于4K heap pages,页表项更少,TLB命中率更高。
  • rte_ring,固定大小的环形缓存区,lockless multi-producer, multi-consumer,bulk/burst-enqueue/dequeue的FIFO队列管理API. 其中per-lcore变量通过Thread Local Storage(TLS)提供per-thread local storage.
  • rte_mempool,分区pool,pool使用name标记并使用ring分配objects.
  • rte_mbuf, 用于提供对mbuf(ctrlmbuf + pktmbuf)的管理,mbuf存储在mempool中
  • rte_eal + libc, EAL(Environment Abstration Layer)提供对上述的接口,隐藏App和Lib之间的环境细节。如:Alarm操作、中断处理、CPU特性识别(rte_cpu_get_feature)、Trace和Debug功能、PCI总线访问、原子锁操作、内存分配、Core亲和性、多进程&多线程、librte_hash(包转发算法), librte_lpm (Longest Prefix Match,包转发算法),librte_net)。EAL通过/sys向用户空间呈现PCI信息(/sys/bug/pci)与address space,EAL用igb_uio模块用户空间提供/dev/uidX设备文件,应用就可以使用mmap /dev/uidX到PCI address space。用户空间采用了pthread库。DPDK包括1G和10G的PMDs(Poll Mode Drivers), 及没有异步和中断信息机制的virtio控制器。

内存管理

一个连续的内存块通过rte_memseg来描述,再通过memzone的概念来聚集(可使用rte_eal_get_configuration()来访问)。
使用aligh参数来对齐数据(2的指数倍但不大于64 bytes)。memzone可以保留2MB或1G的大页。
CONFIG_RTE_MALLOC_DEBUG参数可以帮助调试缓存区溢出错误。
librte_malloc用于分配任意大小的内存,在NUMA中,是分配该core所在的NUMA socket还是其它socket上的内存由参数显然决定。常见两个数据结构:

  • malloc_heap, 管理per-socket上的free内存(每个NUMA node上有一个heap结构),numa_socket, mz_count, lock, free_head.
  • malloc_elem,memzone中各种管理对象的通用头部描述,heap, prev, next_free, state, padding, size.

KNI接口

DPDK提供了两种方法与linux kernel协议栈交互: TAP和KNI。KNI(Intel DPDK Kernel NIC Interface)允许用户应用访问Linux控制平面,可以让TUN/TAP设备省去系统调用和数据拷贝(copy_to_user()/copy_from_user())的时间,也可以允许应用使用kernel tcp/ip栈及使用标准的的管理工具如ethtool, ifconfig,tcpdump等(/dev/kni)。
在这里插入图片描述

DPDK的运行形式

大部分 DPDK 的代码是以 lib 的形式运行在用户应用的进程上下文.为了达到更高的性能。应用通常都会 多进程 或者 多线程 的形式运行在不同的 lcore 上

多线程的场景:
在这里插入图片描述
多进程的场景:

多进程的场景下,多个应用实例如何保证关键信息(比如内存资源)的一致性呢? 答案是不同进程将公共的数据 mmap 同一个文件,这样任何一个进程对数据的修改都可以影响到其他进程。
在这里插入图片描述
Primary & Secondary

多进程场景下,进程有两种角色 Primary 或者 Secondary ,正如其名字, Primary 进程可以 create 资源,而 Secondary 进程只能 attach 已存在的资源。一山不容二虎,一个多进程的应用,有且只有一个 Primary 进程,其余都是 Secondary 进程。应用可以通过命令行参数 --proc-type 来指定应用类型。

DPDK的入口

如同 main 函数在应用程序中的地位, rte_eal_init 函数便是 DPDK 梦开始的地方(其实前面的图已经画出来了!),我们来看看它做了什么事。

/* Launch threads, called at application init(). */
int
rte_eal_init(int argc, char **argv)
{
    thread_id = pthread_self();

    rte_eal_cpu_init();

    eal_parse_args(argc, argv);

    rte_config_init();

    rte_eal_intr_init();

    rte_mp_channel_init();
    
    rte_eal_memzone_init();
    
    rte_eal_memory_init();

    rte_eal_malloc_heap_init()
    
    eal_thread_init_master(rte_config.master_lcore);

    RTE_LCORE_FOREACH_SLAVE(i) {
        /* create a thread for each lcore */
        ret = pthread_create(&lcore_config[i].thread_id, NULL,
                     eal_thread_loop, NULL);
    
        .....
    }

    /*
     * Launch a dummy function on all slave lcores, so that master lcore
     * knows they are all ready when this function returns.
     */
    rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
    
    rte_eal_mp_wait_lcore();

    ......
}

原文链接:https://www.codercto.com/a/59815.html

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值