当 NIC 接收到数据时,网络中断处理程序会做什么?

问题描述

据我所知,当数据包到达网卡时,DMAC 会将数据包复制到内核空间。当 DMAC 完成其工作时,它会通知 cpu,然后 cpu 将数据复制到用户空间。这样做会导致内存被读取一次并被写入两次。我写了一个简单的程序来模拟这个过程。这是代码

# server.py
import socket
import sys

server = socket.socket(socket.AF_INET,socket.soCK_STREAM)
host = "70.202.0.116"
port = 12306
server.bind((host,port))

server.listen(5)

while True:
    conn,addr = server.accept()      
    print(conn,addr)
    while True:
        data = conn.recv(4096)
        if not data:
            print("client has lost")
            conn.close()
            break

server.close()
# client.py
import socket
import sys

client = socket.socket(socket.AF_INET,socket.soCK_STREAM)

host = "70.202.0.116"
port = 12306

client.connect((host,port))

data = ''
for i in range(4096):
    data += 'a'


while True:
   client.send(data.encode())

client.close()

我的机器有两个 numa 节点。第一次,我通过ethtool -L eno1 combined 1禁用了NIC Multi-Queue,因此只剩下一个网络中断,并通过ehco 22 > /proc/irq/137/smp_affinity_list设置了affanity。 Core 22 在 numa 1 上。然后我运行 server.py。我用pcm-memory监控系统内存带宽,得到了预期的输出,读写比接近1:2。

output 1

但是当我将亲和力更改为位于 numa 0 上的核心 0 时,我得到了完全不同的结果。读写比接近1:1。

output 2

我想知道interrput handler在这个过程中做了什么,为什么我得到了不同的结果?

解决方法

增加读取延迟可能是因为设备属于不同的 numa_node。检查服务器和客户端运行的设备属于哪个numa节点

# cat /sys/bus/pci/devices/<PCI device>/numa_node