网卡驱动接收数据----软中断处理数据----socket接收数据
1. 数据接收的详细流程
(1) 网卡接收数据并写入 DMA 缓冲区
-
DMA 缓冲区:
网卡驱动初始化时,会为每个接收队列分配一块 DMA 缓冲区(通常是一个环形队列,称为 RX Ring)。 -
数据接收:
当网卡接收到数据包时,会通过 DMA(直接内存访问) 将数据包直接写入内核预先分配的 DMA 缓冲区(sk_buff
),无需 CPU 参与。 -
描述符更新:
网卡会更新 接收描述符(Descriptor),标记数据包的位置和状态。
(2) 硬件中断触发
-
硬件中断:
当网卡将数据包写入 DMA 缓冲区后,会触发 硬件中断,通知 CPU 有数据到达。 -
硬件中断处理程序:
硬件中断处理程序(如ixgbe_msix_clean_rings
)执行以下操作:-
从 DMA 缓冲区取出数据包:
硬件中断处理程序从 DMA 缓冲区中取出数据包(sk_buff
)。 -
将数据包放入内核的接收队列:
将数据包放入 每 CPU 的接收队列(如softnet_data->input_pkt_queue
)。 -
触发软中断:
硬件中断处理程序触发 软中断(NET_RX_SOFTIRQ
),调度net_rx_action
执行。
-
(3) 软中断处理数据
-
软中断触发:
硬件中断处理程序触发软中断后,内核会在合适的时机(如硬件中断返回时)调度net_rx_action
执行。 -
net_rx_action
执行:
net_rx_action
是软中断处理函数,负责从接收队列中取出数据包并进行协议栈处理:-
从接收队列取出数据包:
从softnet_data->input_pkt_queue
中取出数据包(sk_buff
)。 -
协议栈处理:
解析数据包的协议头(如 Ethernet、IP、TCP/UDP),并将数据包传递给协议栈的上层(如ip_rcv
、tcp_v4_rcv
)。 -
放入 socket 接收缓冲区:
将数据包放入对应 socket 的接收缓冲区。
-
(4) 进程接收数据
-
recv(socket)
调用:
进程调用recv(socket)
等待数据时,内核会检查 socket 的接收缓冲区:-
如果接收缓冲区有数据,将数据拷贝到用户空间缓冲区,并返回。
-
如果接收缓冲区为空,进程进入睡眠状态,等待数据到达。
-
-
数据到达时唤醒进程:
当数据包到达并放入 socket 的接收缓冲区时,内核会唤醒等待的进程。
2. 关键问题解答
(1) 软中断是从 DMA 写入的内核缓冲区获取数据给协议栈吗?
-
不是直接获取:
软中断 不直接从 DMA 缓冲区获取数据,而是从 内核的接收队列(如softnet_data->input_pkt_queue
)中获取数据。 -
数据传递路径:
-
网卡通过 DMA 将数据包写入 DMA 缓冲区。
-
硬件中断处理程序从 DMA 缓冲区取出数据包,放入内核的接收队列。
-
软中断从接收队列中取出数据包,传递给协议栈。
-
(2) 硬中断在其中有转一手拷贝吗?
-
没有额外的拷贝:
硬件中断处理程序 不会拷贝数据包,而是直接将数据包(sk_buff
)从 DMA 缓冲区移动到内核的接收队列。 -
零拷贝设计:
数据包从网卡到内核协议栈的传递过程中,没有额外的数据拷贝,只有sk_buff
的指针传递。
3. 软中断的角色
-
异步处理:
软中断用于异步处理网络数据包,避免在硬件中断上下文中执行耗时操作(如协议栈处理)。 -
任务分解:
将数据包处理任务分解为硬件中断(快速接收)和软中断(协议栈处理),提高系统响应速度。 -
批量处理:
net_rx_action
会批量处理多个数据包,减少上下文切换开销。
4. 数据传递的路径总结
-
网卡 → DMA 缓冲区:
数据通过 DMA 写入内核的 DMA 缓冲区(sk_buff
)。 -
DMA 缓冲区 → 内核接收队列:
硬件中断处理程序将数据包从 DMA 缓冲区移动到内核的接收队列(如softnet_data->input_pkt_queue
)。 -
内核接收队列 → 协议栈:
软中断net_rx_action
从接收队列中取出数据包,传递给协议栈(如ip_rcv
、tcp_v4_rcv
)。 -
协议栈 → socket 接收缓冲区:
协议栈将数据包放入对应 socket 的接收缓冲区。 -
socket 接收缓冲区 → 用户空间:
进程调用recv(socket)
时,内核将数据从 socket 接收缓冲区拷贝到用户空间。
5. 性能优化
-
NAPI(New API):
在高流量场景下,使用 NAPI 减少硬件中断次数,通过轮询方式批量处理数据包。 -
RPS(Receive Packet Steering):
将数据包处理负载均衡到多个 CPU 核心,提高多核系统的性能。 -
XDP(eXpress Data Path):
在网卡驱动层直接处理数据包,绕过内核协议栈,提升性能。
6. 总结
-
DMA 缓冲区:网卡通过 DMA 将数据包直接写入内核的 DMA 缓冲区。
-
硬件中断:硬件中断处理程序将数据包从 DMA 缓冲区移动到内核的接收队列,并触发软中断。
-
软中断:软中断从接收队列中取出数据包,传递给协议栈。
-
零拷贝设计:数据包从网卡到协议栈的传递过程中,没有额外的数据拷贝。