0x01 缘由
继续学习dpdk相关特性。
0x02 介绍(基本上是翻译学习)
DPDK由许多库组成。在这些库里面有些函数能被多线程安全调用,有些不能是线程安全的。本节允许开发人员在构建自己的应用程序时考虑这些问题。
DPDK典型的运行环境为单逻辑核单线程模式。在一些场景,它不仅是多线程,而且是多进程模式。通常,最好避免在可能的情况下在线程和/或进程之间共享数据结构。如果需要在多进程访问多样的数据结构,则执行块必须以一种多线程安全的方式访问数据。常见的多线程互斥方式有锁、原子操作等。然而上面的操作都可能对性能造成一点影响。
1.Fast-Path APIs
在数据平面中运行的应用程序对性能敏感,但这些库中的某些功能不支持多线程方式。hash,LPM,内存池库 和 RX/TX和PMD驱动。
hash和LPM库设计为非线程安全是为了维持性能。然而,如果开发者需要支持多线程,则开发者可以在这些库的顶层添加安全访问。并不是所有场景都需要锁,hash和LPM库,可以在多线程中并行查询值。但是,当访问单个hash和LPM表时,在不加锁的情况下无法保证线程安全。另外一种替代方法是为每个线程创建一个表的副本,每个线程访问副本。(表如何同步)
PMD的RX/TX是DPDK应用程序最关键的方面,建议无锁操作,因为对整个网络数据包的收发影响较大。但是请注意,当每个线程在不同的NIC队列上执行I / O时,这些函数可以安全地从多个线程使用。如果多个线程在同一个NIC端口上使用相同的硬件队列,则需要锁定或某种其他形式的互斥。
RING 库是基于无锁ring-buffer算法的原始线程安全设计。此外,它提供高性能的多生产者单生产者/消费入队/出队操作。内存池是基于DPDK无锁ring库实现,因此它也是线程安全的。
2.性能敏感API
在第25.1节描述的性能敏感区域之外,DPDK为大多数其他库提供了线程安全的API。 例如,malloc和memzone功能可以安全地用于多线程和多进程环境中。
PMT的设置和配置不是性能敏感的,也不是性能安全的。在多线程环境下,如果同时对PMD的相关配置进行读写,可能对相关文件进行破坏。因为这个不是性能敏感的,开发者可以自己在顶层设计中实现线程安全的配置和设置。预计,在大多数应用中,对网络端口的初始化配置都是用单线程去完成。
3.初始化库
建议DPDK库在应用程序启动时在主线程中初始化,而不是随后在转发线程中初始化。 但是,DPDK会执行检查,以确保库仅被初始化一次。 如果多次尝试初始化,则返回错误。
在多进程情况下,共享内存的配置信息只能由主进程初始化。 此后,主进程和辅助进程都可以分配/释放最终依赖于rte_malloc或memzone的任何内存对象。
4.中断线程
DPDK在轮询模式下几乎完全用于Linux用户空间。 对于某些不频繁的操作,例如接收PMD链路状态改变通知,可以在主DPDK处理线程外部的附加线程中调用回调。 这些函数回调应该避免操作也由普通DPDK线程管理的DPDK对象,如果需要这样做,则应用程序可以为这些对象提供适当的锁定或互斥限制。
0x03 总结
学习应该坚持。。。