层次结构
3个主要主体:
- 协议接口,向上提供的服务,是根据业务来的
- 设备接口,设备运转的主体
- 驱动,设备接口的具体实现
Linux驱动中3层的主要接口
layer | tx | rx |
---|---|---|
网络协议接口层 | dev_queue_xmit | netif_rx |
网络设备接口层(net_device) | hard_start_xmit | 中断(__do_softirq() -> net_rx_action()) |
驱动层(举例) | xxx_xmit_frame() |
dev层本质只是提供标准操作方式,实际是上层业务调用dev_queue_xmit会直接call到驱动的xxx_xmit的代码,进而调用驱动。
数据包的2次拷贝
- 网卡从网卡硬件ASIC的收包buf 通过DMA拷贝到内存的RX 队列 (ring buffer)
- 从DMA拷贝到内核数据包skb:skb = mlx5e_skb_from_cqe_linear()
处理流程其他细节:
- DMA到ring buffer,产生软中断,软中断例程调用__do_softirq(),进而调用net_rx_action()统一收入,然后使用NAPI接口napi_poll()进行处理。如果是mlnx的驱动,就是读取ring buffer中的rx的cq,进一步读取rx 的cqe调度实体,收到cqe之后就创建内核数据包skb。所以是 ring buf的rx cq -》 cqe -》 skb
参考:
https://arthurchiao.art/blog/linux-net-stack-implementation-rx-zh