1 linux网络栈监控及调优:数据接收-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

linux网络栈监控及调优:数据接收

Linux阅码场 来源:窗有老梅 2023-03-25 16:44 次阅读

4. 初始化

b5041890-cae8-11ed-bfe3-dac502259ad0.jpg

图 1 网络设备在 packet 到达并需要处理时,通常会触发一个 IRQ。IRQ 处理函数是在很高的优先级下执行的,一般会阻塞其他 IRQs 的触发(译者注:often blocks additional IRQs from being generated。个人觉得原文这里并不准确,中断上下文中关中往往只是让 CPU 不响应中断,而不是让其他设备直接不发出中断)。故而,设备驱动中的 IRQ 处理函数必须越快越好,并将比较耗时的工作挪到中断上下文之外去执行,这就是为啥会有软中断系统。

linux 内核软中断系统支持在设备驱动的中断上下文之外处理工作。网络设备场景下,软中断系统用作处理 incoming packets。内核在 boot 阶段做软中断系统的初始化。 图 1 对应前文“软中断”一节,展示的是软中断系统及其 per-CPU 内核线程的初始化。 软中断系统的初始化流程如下:

spawn_ksoftirqd(kernel/softirq.c)调用 smpboot_register_percpu_thread(kernel/smpboot.c)创建软中断内核线程(每个 CPU 一个)。如代码所示,run_ksoftirqd 作为 smp_hotplug_thread 的 thread_fn,会在一个 loop 中被执行。

ksoftirqd 线程会在 run_ksoftirqd 中运行其 processing loop。

随后,创建 softnet_data 数据结构(前文“struct softnet_data 数据结构初始化”一节),每个 CPU 一个。此数据结构包含在网络数据处理时所需要的重要信息。另外还有一个 poll_list,下文会说。设备驱动调用 napi_schedule 或其他 NAPI APIs,将 NAPI poll 数据结构添加至 poll_list 上。

net_dev_init 调用 open_softirq 向软中断系统注册 NET_RX_SOFTIRQ 软中断,被注册的软中断处理函数是 net_rx_action(前文“软中断处理函数初始化”一节)。软中断内核线程会调用此函数来处理 packets。

图 1 中的第 5 - 8 步与数据的到达有关,下一节会说。

5. 数据到达

b536fc38-cae8-11ed-bfe3-dac502259ad0.jpg

图 2 数据从网络上来了(前文“数据到达”一节)! 网络数据到达 NIC 时,NIC 会通过 DMA 将 packet 数据写入 RAM。igb 网络驱动会在 RAM 中构建一个 ring buffer,其指向接收到的 packets。值得注意的是,有些 NIC 支持 "multiqueue",这些 NIC 可以使用多个处理器来处理 incoming 网络数据(前文“准备从网络接收数据”一节)。

简化起见,图 2 只画了一个 ring buffer,但取决于 NIC 以及硬件配置,你的系统可能使用的是多个队列。 下面流程的细节参阅前文“数据到达”一节。 我们来过一遍数据接收流程:

数据从网络到达 NIC。

NIC 通过 DMA 将网络数据写入 RAM。

NIC 触发一个 IRQ。

执行设备驱动注册的 IRQ 处理函数(前文“中断处理”一节)。

NIC 清除 IRQ,这样新 packet 到来时可以继续触发 IRQs。

调用 napi_schedule 拉起 NAPI 软中断 poll loop(前文“NAPI 与 napi_schedule”一节)。

napi_schedule 的调用触发了 图 1 中的 5 - 8 步。如后面所见,NAPI 软中断 poll loop 拉起的原理,就是翻转一个 bit 域,并向 poll_list 上添加一个数据结构。napi_schedule 没干什么其他事,这就是驱动将处理工作转交给软中断系统的原理。

继续分析 图 1,对照图中相应的数字:

驱动调用 napi_schedule 将驱动的 NAPI poll 数据结构添加至当前 CPU 的 poll_list 上。

软中断 pending bit 会被置上,如此该 CPU 上的 ksoftirqd 线程知晓有 packets 需要处理。

执行 run_ksoftirqd 函数(在 ksoftirqd 内核线程的 loop 中执行)。

调用 __do_softirq 检查是否有 pending 的 bit 域,以此确认是否有 pending 的软中断,进而调用 pending 软中断的处理函数:net_rx_action,该函数干了所有的 incoming 网络数据处理的脏活。

需要注意的是,软中断内核线程执行的是 net_rx_action,而不是设备驱动的 IRQ 处理函数。

6. 网络数据处理的开始

b556db02-cae8-11ed-bfe3-dac502259ad0.jpg

图 3 至此开始数据的处理。net_rx_action 函数(在 ksoftirqd 内核线程中调用)会执行当前 CPU poll_list 上注册的 NAPI poll 数据结构。poll 数据结构的注册一般有两种情况:

设备驱动调用 napi_schedule。

Receive Packet Steering 场景(前文“Receive Packet Steering(RPS)”一节)下使用 Inter-processor Interrupt。

我们将从 poll_list 获取驱动 NAPI 数据结构的流程串起来(下一节会讲 RPS 是怎么通过 IPIs 注册 NAPI 数据结构的)。 图 3 流程在前文有详细拆解过,总结一下就是:

net_rx_action poll 检查 NAPI poll list 中的 NAPI 数据结构。

校验 budget 及消耗的时间,以确保软中断不会霸占 CPU。

调用注册的 poll 函数(前文“NAPI poll 函数及权重”一节)。本文场景下,igb 驱动注册的是 igb_poll 函数。

驱动的 poll 函数收取 RAM ring buffer 中的 packets(前文“NAPI poll”一节)。

packets 进一步给到 napi_gro_receive,其可能会进一步被 Generic Receive Offloading 处理(前文“Generic Receive Offloading(GRO)”一节)。

packets 要么被 GRO 处理,这样整个调用链也就结束了;要么 packets 通过 net_receive_skb 进一步给到上层协议栈。

下面会讲 net_receive_skb 是怎么实现 Receive Packet Steering,也就是在多个 CPUs 之间分发 packet 的。

7. 网络数据的进一步处理

b55fbea2-cae8-11ed-bfe3-dac502259ad0.jpg

图 4 从 netif_receive_skb 开始继续网络数据的处理,数据的具体路径取决于是否使能了 Receive Packet Steering(RPS)。一个“开箱即用”的 linux 内核(译者注:意思就是通用的发行版)默认是不使能 RPS 的,如果你想用 RPS,就必须显式地配置及使能之。

RPS 禁能的情况下(前文“禁能 RPS 场景(默认配置)”一节),对应 图 4 中的如下数字:

1. netif_receive_skb 将数据给到 __netif_receive_core。

6. __netif_receive_core 将数据给到系统中可能存在的 taps(前文“packet tap 投递”一节)(比如 PCAP,https://www.tcpdump.org/manpages/pcap.3pcap.html)。

7. __netif_receive_core 将数据给到协议层注册的 handlers(前文“协议层投递”一节)。大多数情况下,此 handler 是 IPv4 协议栈所注册的 ip_rcv 函数。

RPS 使能的情况下(前文“使能 RPS 场景”一节):

netif_receive_skb 将数据给到 enqueue_to_backlog。

packets 会被送到 per-CPU 的输入队列上以待后续处理。

将远端 CPU 的 NAPI 数据结构添加至该远端 CPU 的 poll_list 上,并向该 CPU 发一个 IPI,进而唤醒远端 CPU 上的软中断内核线程(如果其并未在运行的话)。

当远端 CPU 上的 ksoftirqd 内核线程运行起来后,其处理模式与上一节中的相同,不同之处是,注册进来的 poll 函数是 process_backlog,该函数会从当前(译者注:本 CPU) CPU 的输入队列收取 packets。

packets 进一步给到 __net_receive_skb_core。

__net_receive_skb_core 将数据给到系统中可能存在的 taps(前文“packet tap 投递”一节)(比如 PCAP)。

__net_receive_skb_core 将数据给到协议层注册的 handlers(前文“协议层投递”一节)。大多数情况下,此 handler 是 IPv4 协议栈所注册的 ip_rcv 函数。

8. 协议栈及用户 sockets

数据接下来要走的路径是:协议栈、netfilter、Berkeley Packet Filters,最终到达用户 socket。 虽然代码路径挺长的,但是逻辑是直白清晰的。 网络数据路径更详细地拆解见前文“协议层注册”一节。下面是 high level 的简要总结:

IPv4 协议层通过 ip_rcv 收取 packets。

会做 netfilter 以及路由优化。

目标是本机的数据,会进一步给到更 high level 的协议层,比如 UDP。

UDP 协议层通过 udp_rcv 收取 packets,并通过 udp_queue_rcv_skb 及 sock_queue_rcv 将数据入队到用户 socket 的接收 buffer 中。在入队到接收 buffer 之前,会做 Berkeley Packet Filters。

值得注意的是,netfilter 在这个过程中会被调用多次,具体位置参考前文的详细拆解(前文“协议层注册”一节)。

9. 总结

linux 网络栈极其复杂,涉及到的系统很多。如果要监控这个复杂的系统就必须得搞清楚这些系统之间是怎么交互的,以及对某一系统配置的调整,会如何影响到其他系统。本文作为前文的补充,试图把这些问题梳理的更清晰易懂一些。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10854

    浏览量

    211567
  • Linux系统
    +关注

    关注

    4

    文章

    593

    浏览量

    27392
  • IRQ
    IRQ
    +关注

    关注

    0

    文章

    16

    浏览量

    10760
  • 中断系统
    +关注

    关注

    1

    文章

    96

    浏览量

    61015

原文标题:图解之 linux 网络栈监控及调优:数据接收

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    深度解析Linux网络路径及sk_buff struct 数据结构

    的 Segmentation Offloading 技术(接收端) 1. Linux 网络路径 1.1 发送端 1.1.1 应用层 (1) Socket 应用层的各种网络应用程序基本上
    的头像 发表于 10-22 15:04 5604次阅读
    深度解析<b class='flag-5'>Linux</b><b class='flag-5'>网络</b>路径及sk_buff struct <b class='flag-5'>数据</b>结构

    Linux网络原理与实现

    本文尝试从技术研发与工程实践(而非纯理论学习)角度,在原理与实现、监控告警、 配置三方面介绍内核5.10 网络。由于内容非常多,因此分
    发表于 08-10 08:58 3739次阅读

    基于全HDD aarch64服务器的Ceph性能实践总结

    提升吞吐率。- Linux内核中有很多网络相关的参数,我们可以根据不同的应用场景,不同的块大小来调整这些网络参数,以达到最优的性能。- 中断也是网络
    发表于 07-05 14:26

    infosphere CDC 性能及MC性能指标监控

    infosphere CDC 性能及MC性能指标监控
    发表于 09-07 09:26 4次下载
    infosphere CDC 性能<b class='flag-5'>调</b><b class='flag-5'>优</b>及MC性能指标<b class='flag-5'>监控</b>

    机器学习如何数据

    在延迟方面,相比 Postgres 默认配置,OtterTune、工具、DBA 和 RDS 的配置获得了近似的提升。我们大概可以把这归于 OLTP-Bench 客户端和 DBMS 之间的网络开销
    发表于 11-07 13:50 1137次阅读
    机器学习如何<b class='flag-5'>调</b><b class='flag-5'>优</b><b class='flag-5'>数据</b>库

    如何对电机进行的好处是什么?

    如何自动对电机进行
    的头像 发表于 08-22 00:03 3127次阅读

    Linux网络接收过程的监控

    、ksoftirqd软中断处理几个过程。其中在ksoftirqd软中断处理中,把数据包从RingBuffer中摘下来,送到协议的处理,再之后送到用户进程socket的接收队列中。 图1 Li
    的头像 发表于 11-10 14:50 1673次阅读

    Linux查看资源使用情况和性能常用的命令

    ,包括进程、线程、程序堆栈、内存、Swap、CPU调度、内存调度、网络连接和IO读写等。 本文介绍了Linux查看资源使用情况和性能常用的命令,包括top、htop、ps、free
    的头像 发表于 11-12 17:54 4195次阅读

    Linux用电功耗的笔记分享

    整理一些Linux用电功耗的笔记,分享给小伙伴,关于用电个人觉得
    的头像 发表于 06-23 15:19 4089次阅读

    Linux性能常见工具和堆栈解析

      Linux系统性能涉及多个方面,包括内核参数调整、文件系统优化、网络设置等。   1. 内核参数调整:通过调整内核参数来提高系统性能。例如,调整进程调度策略、内存管理参数等。
    的头像 发表于 06-29 09:45 919次阅读
    <b class='flag-5'>Linux</b>性能<b class='flag-5'>调</b><b class='flag-5'>优</b>常见工具和堆栈解析

    Linux网络技术的相关知识

    网络是一个很复杂的协议,今天网络这么发达,网络协议起到关键性作用。 这里就给大家详细描述一下:Linux
    的头像 发表于 08-24 10:33 662次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>网络</b>技术<b class='flag-5'>栈</b>的相关知识

    jvm参数

    JVM(Java虚拟机)是Java程序的运行环境,它负责解释Java字节码并执行相应的指令。为了提高应用程序的性能和稳定性,我们可以JVM的参数。 JVM主要涉及到堆内存、垃圾
    的头像 发表于 12-05 11:29 623次阅读

    jvm主要是哪里

    JVM主要涉及内存管理、垃圾回收、线程管理与锁优化等方面。下面将详细介绍每个方面的技术和策略以及如何进行优化。 内存管理 JVM的内存管理主要包括堆内存、
    的头像 发表于 12-05 11:37 1554次阅读

    jvm工具有哪些

    JVM是提高Java应用程序性能的重要手段,而JVM工具则是辅助开发人员进行工作的利
    的头像 发表于 12-05 11:44 1067次阅读

    Linux网络协议的实现

    网络协议是操作系统核心的一个重要组成部分,负责管理网络通信中的数据包处理。在 Linux 操作系统中,
    的头像 发表于 09-10 09:51 298次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>网络</b>协议<b class='flag-5'>栈</b>的实现