DPDK提供了两种模式来处理网络数据包:中断驱动和轮询模式。在中断驱动模式下,DPDK会使用硬件中断来通知应用程序有新的数据包到达。而在轮询模式下,DPDK会周期性地检查网络接口是否有新的数据包到达。
默认情况下,DPDK使用中断驱动模式来处理网络数据包。但是,在某些情况下,如高速网络环境下或者需要最小化延迟的应用程序中,使用轮询模式可能更为合适。
要将DPDK设置为轮询模式,可以按照以下步骤操作:
- 禁用所有硬件中断
将所有与DPDK相关的硬件设备的中断禁用,例如:
echo 0 > /proc/irq/{IRQ}/smp_affinity
echo "disable" > /sys/firmware/acpi/interrupts/{IRQ}/gpe0_{N}
其中{IRQ}是指硬件设备的IRQ号码。
- 使用rte_eth_dev_configure函数配置网卡
在DPDK应用程序初始化时,可以使用rte_eth_dev_configure函数配置网卡。在该函数调用时指定RTE_ETH_DEV_NO_RX_INTERRUPTS标志即可禁用接收队列上的硬件中断,并使网卡进入轮询模式:
struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
.split_hdr_size = 0,
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = rss_symmetric_key,
.rss_key_len = RSS_HASH_KEY_LENGTH,
.rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
};
rte_eth_dev_configure(port_id, nb_rx_queue, nb_tx_queue, &port_conf);
/* Disable RX interrupts and enable RX polling. */
rte_eth_dev_set_rx_queue_intr_enable(port_id, 0, 0);
在这个例子中,禁用了接收队列上的硬件中断,并启用了轮询模式。
- 调整轮询间隔
为了最小化延迟,可以调整DPDK应用程序的轮询间隔。可以使用rte_delay_us函数来设置轮询间隔:
const uint32_t poll_interval_us = 10;
const uint64_t poll_interval_cycles =
rte_get_timer_hz() * poll_interval_us / 1000000;
while (1) {
/* Poll for incoming packets. */
rte_eth_rx_burst(port_id, queue_id, rx_pkts, MAX_BURST_SIZE);
/* Process the received packets. */
/* Wait for the next polling interval. */
rte_delay_us(poll_interval_cycles);
}
在这个例子中,使用rte_get_timer_hz函数获取CPU的时钟频率,并计算出指定的轮询间隔对应的CPU时钟周期数。然后使用rte_delay_us函数在每次轮询后等待指定的时间。
通过以上步骤,就可以将DPDK设置为轮询模式,以最小化延迟并提高网络处理性能。