问题一:网卡数据报文与驱动是如何交互的,DMA之后,如何放入到对应的Queue中,其中涉及哪些操作?
看了一下这个问题的提出是在去年(2023年)11月的时候提出,当时还不清楚网卡收发包的整个流程。说来惭愧,作为一个在网络里面学习了快十来年的人,这点基础还不清楚,也足以证明自己的怀疑,自己似乎不是一个搞技术的人。不管怎样,技术驱动科技的进步。让自己成为一个技术人。
前面啰嗦了半天,请忽略唠叨。
接下来以收包流程为例说明。
网卡和驱动之间的交互queue称之为 描述符队列,收包为收包描述符队列,发包则为发包描述符队列。
收包的描述符信息定义如下:
/* Receive Descriptor - Advanced */
union ixgbe_adv_rx_desc {
struct {
__le64 pkt_addr; /* Packet buffer address */
__le64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
union {
__le32 data;
struct {
__le16 pkt_info; /* RSS, Pkt type */
__le16 hdr_info; /* Splithdr, hdrlen */
} hs_rss;
} lo_dword;
union {
__le32 rss; /* RSS Hash */
struct {
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
__le32 status_error; /* ext status/error */
__le16 length; /* Packet length */
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
网卡收到报文之后,先检查描述符环形队列中,是否有可用的描述符,如果没有,则rx失败,rx_miss++;否则,则将报文DMA到 描述符所指向的地址,这个地址在软件看来就是rte_mbuf (dpdk中的定义),或者sk_buff(Linux中的定义)。