写点什么

DPDK 源码分析之网络基础知识

作者:于顾而言
  • 2022 年 9 月 17 日
    江苏
  • 本文字数:1680 字

    阅读完需:约 6 分钟

DPDK源码分析之网络基础知识

字节对齐

__attribute__ ((aligned (1)))

  • 在设计不同 CPU 下的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生成的代码不一样.

  • 如果跨越了 4 字节边界存储,那么 cpu 要读取两次,这样效率就低了


内存池设计原理



好处:

  • 比 malloc/free 进行内存申请/释放的方式快

  • 不会产生或很少产生堆碎片

  • 可避免内存泄漏




伙伴系统:



包在系统协议栈的流图,操作系统做了那些事情



  • 开始收包之前,Linux 要做许多的准备工作,创建 ksoftirqd 线程,协议栈注册,linux 要实现许多协议,比如 arp,icmp,ip,udp,tcp,每一个协议都会将自己的处理函数注册一下;网卡驱动初始化,每个驱动都有一个初始化函数,内核会让驱动也初始化一下。在这个初始化过程中,把自己的 DMA 准备好,把 NAPI 的 poll 函数地址告诉内核;启动网卡,分配 RX,TX 队列,注册中断对应的处理函数

  • 网卡通过 DMA 将 packet 写入内核的rx_ring环形队列缓冲区,并触发硬中断(如果没有 DMA,CPU 就会负责赋值网卡数据到内存中,这个过程非常耗时)

  • CPU 在收到中断之后,调用网卡 ISR 也就是所谓的中断 handler,分配 sk_buf 并入 input_pkt_queue(如果队列已满则丢弃),发出一个软中断 NET_RX_SOFTIRQ,软中断被调度

  • ksoftirqd 线程开始调用驱动的 poll 函数收包,然后将 sk_buf 从 input_pkt_queue 传入 process_queue,根据协议类型调用网络层协议的 handler,ip_rcv 执行包头检查,ip_router_input()进行路由,决定本机/转发/丢弃,tcp_v4_rcv 执行包头检查,tcp_v4_lookup 查询对应的 socket 和 connection,如果正常,tcp_prequeue 将 skb 放进 socket 接收队列,socket 随即唤醒所在的进程

  • 唤醒的进程调用 socket recv 系统调用,如果是 TCP 则调用 tcp_recvmsg 从 sk_buffer 拷贝数据


Dpdk 调优有哪些

  • 控制层和数据层分离。将数据包处理、内存管理、处理器调度等任务转移到用户空间去完成,而内核仅仅负责部分控制指令的处理。这样就不存在上述所说的系统中断、上下文切换、系统调用、系统调度等等问题。

  • 使用多核编程技术代替多线程技术,并设置 CPU 的亲和性,将线程和 CPU 核进行一比一绑定,减少彼此之间调度切换。

  • 针对 NUMA (Non Uniform Memory Access Architecture)系统,尽量使 CPU 核使用所在 NUMA 节点的内存,避免跨内存访问。

  • 使用大页内存代替普通的内存,减少 cache-miss。

  • 采用无锁技术解决资源竞争问题。

Tcp 建链的异常状态维护

  • 第一次握手消息丢失,触发超时重传机制,包括重传次数和重传周期

  • 第二次握手消息丢失:(SYN+ACK),客户端和服务端都会重传

  • 第三次握手消息丢失:(ACK),服务会重传 SYN+ACK 报文段,直到收到 ACK 响应或者达到最大重传次数




  • 第一次挥手消息丢失:(FIN),客户端会开启重传流程,达到最大次数后客户端将停止重传,直接进入 CLOSE 状态。

  • 第二次挥手消息丢失:(ACK),客户端会重传 FIN 报文,直到收到 ACK 报文,或达到 FIN 的最大重传次数。

  • 第三次挥手消息丢失:(FIN),TCP 状态将从 CLOSE_WAIT 状态转入 LAST_ACK 状态,如果在超时时间内未收到客户端的第四次挥手 ACK 报文,则重传 FIN 报文

  • 第四次挥手消息丢失:(ACK),ACK 报文不会重传,服务端在超时未收到 ACK 后会重传 FIN,直至成功收到 ACK 会达到最大重传次数

TIME_WAIT 存在的两个理由

  • 可靠地实现 TCP 全双工连接的终止;

  • 允许老的重复分节(数据报)在网络中消逝。

B+树

在 B +树中, 记录(数据)只能存储在叶节点上, 而内部节点只能存储键值。

B +树的叶节点以单链接列表的形式链接在一起, 以使搜索查询更高效创建



为啥线程的地址空间能一样

线程使用的底层函数和进程一样,都是 clone。从内核里看进程和线程是一样的,都有各自不同的 PCB,但是 PCB 中指向内存资源的三级页表是相同的。进程可以蜕变成线程。线程可看做寄存器和栈的集合。

三级映射:进程 PCB --> 页目录(可看成数组,首地址位于 PCB 中) --> 页表 --> 物理页面 --> 内存单元

两个线程具有各自独立的 PCB,但共享同一个页目录,也就共享同一个页表和物理页面。

Reference

(7条消息) 图解 Linux 网络包接收过程_Peter的专栏-CSDN博客

(7条消息) linux内存管理笔记(二十二)----伙伴系统原理_奇小葩-CSDN博客_伙伴系统原理

发布于: 刚刚阅读数: 9
用户头像

于顾而言

关注

| 且将新火试新茶 × 诗酒趁年华诗酒 2022.09.10 加入

| SASE | SangFor | Senior Developer | 知乎专栏:https://www.zhihu.com/people/whisper-of-the-Koo

评论

发布
暂无评论
DPDK源码分析之网络基础知识_网络协议_于顾而言_InfoQ写作社区