一个网络报文从网卡接收到被应用处理,中间主要需要经历两个阶段:
阶段一:网卡通过其DMA硬件将收到的报文写入到收包队列中(入队) 阶段二: 应用从收包队列中读取报文(出队) 由于目前正在使用vpp/dpdk 优化waf引擎的工作,所以就看看ixgbe网卡在dpdk框架下是怎么工作的。 下面分别介绍一下 收包队列结构 初始化(使能) 收包流程
收发包的配置和初始化,主要是配置收发队列等。
收发包的配置最主要的工作就是配置网卡的收发队列,设置DMA拷贝数据包的地址等。使用数据包时,只要去对应队列取出指定地址的数据即可;主题配置函数见 rte_eth_dev_configure ;当收发队列配置完成后,就调用设备的配置函数,进行最后的配置。(*dev->dev_ops->dev_configure)(dev),-----进入ixgbe_dev_configure()来分析其过程,主要是调用了ixgbe_check_mq_mode()来检查队列的模式。然后设置允许接收批量和向量的模式
2.数据包的获取和发送,主要是从队列中获取到数据包或者把数据包放到队列中。 收包队列的构造主要是通过网卡队列设置函数 rte_eth_rx_queue_setup设置相关参数;最后,调用到队列的setup函数做最后的初始化。ret = (*dev->dev_ops->rx_queue_setup)(dev, rx_queue_id, nb_rx_desc, socket_id, rx_conf, mp); 对于ixgbe设备,rx_queue_setup就是函数ixgbe_dev_rx_queue_setup()
说一说主要的结构体:
View Code
【免费订阅,永久学习】学习地址:
Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂
收包队列的启动主要是通过调用rte_eth_dev_start
DPDK是零拷贝的,那么分配的mem_pool中的对象怎么和队列以及驱动联系起来呢????
设备的启动是从rte_eth_dev_start()
中开始,会调用
diag = (*dev->dev_ops->dev_start)(dev);
找到设备启动的真正启动函数:ixgbe_dev_start
其中队列初始化流程函数为:
ixgbe_alloc_rx_queue_mbufs(struct ixgbe_rx_queue *rxq) { struct ixgbe_rx_entry *rxe = rxq->sw_ring; uint64_t dma_addr; unsigned int i; /* Initialize software ring entries 队列所属内存池的ring中循环取出了nb_rx_desc个mbuf指针, 填充rxq->sw_ring。每个指针都指向内存池里的一个数据包空间 然后就先填充了新分配的mbuf结构,最最重要的是填充计算了dma_addr 初始化queue ring,即rxd的信息,标明了驱动把数据包放在dma_addr处。 最后把分配的mbuf“放入”queue 的sw_ring中, 这样,驱动收过来的包,就直接放在了sw_ring中。 */ for (i = 0; i < rxq->nb_rx_desc; i++) { volatile union ixgbe_adv_rx_desc *rxd; struct rte_mbuf *mbuf = rte_mbuf_raw_alloc(rxq->mb_pool); if (mbuf == NULL) { PMD_