鲲鹏社区首页
中文
注册
运行DPDK23.11 eventdev_pipeline样例程序崩溃问题

运行DPDK23.11 eventdev_pipeline样例程序崩溃问题

网络DPDK

发表于 2025/04/28

0

作者|王陈星宇

问题描述

  • DPDK服务器为鲲鹏 + Openeuler22.03 OS 。使用以下命令启动eventdev_pipeline样例程序会程序崩溃,核心已转储 :./dpdk-eventdev_pipeline -l 0-48 --vdev event_sw0 -- -r1 -t1 -e1 -w ff0 -s5 -n0 -c32 -W1000 -D
  •  X86服务器 + Openeuler22.03 OS 可复现该问题


问题分析

函数调用栈分析

问题场景的调用栈如下图所示。可以看到挂死的原因是访问了异常指针地址。

分析报错代码

eventdev_pipeline样例程序的报错代码如下图所示。该地址是来自queue结构体保存的tx_buf地址,queue结构体是通过对queue数组作偏移得到的。挂死函数需要对这个tx_buf进行读写。


触发报错代码验证分析

经维测打印排查,未发现queue数组的基地址存在异常,用作偏移量的queue明显大于queue结构体中描述queue队列长度的nb_queues数值。

进一步分析代码发现,这里的queue来自mbuf.hash.txadapter.txq,这个值在问题场景代码流程中没有进行过赋值操作和值校验。而其他eventdev_pipeline样例程序(app/eventdev_pipeline)中,在first stages中对其进行了赋值操作。


解决方案与验证

方案一 :在发送前对queue做值范围保护

程序崩溃根因是错误偏移量导致的踩内存,可以考虑在计算queue地址前添加 queue < nb_queues 的保护作为临时解决方案一。该方案能适配发送队列不为1的业务场景,但是触发该问题的数据包会丢失。
  • 修改方法 :将\dpdk-23.11\dpdk-23.11\lib\eventdev\rte_event_eth_tx_adapter.c文件txa_service_tx函数定义中的第624行
tqi = txa_service_queue(txa, port, queue);
替换成
if (likely(queue < txa->txa_ethdev[port].nb_queues)) {
    tqi = txa_service_queue(txa, port, queue);
} else {
    tqi = NULL;
}

方案二 :在pipeline的第一个stage对txq进行赋值

由于其他样例程序在处理流程中对queue进行了赋值,且当前的程序仅有一个发包队列,因此可以在eventdev_pipeline程序里添加这个赋值,作为临时解决方案二。该方案不会导致数据包丢失,但是会让所有的数据包会进入同一个发送队列,若业务中存在多个发送队列时,需要自行适配。
  • 修改方法 :将\dpdk-23.11\examples\eventdev_pipeline\pipeline_worker_generic.c文件worker_generic_burst函数定义中的第100行
if (events[i].queue_id == cdata.qid[0])及其if代码块
替换成
if (events[i].queue_id == cdata.qid[0]) {
    events[i].flow_id = events[i].mbuf->hash.rss
        % cdata.num_fids;
    rte_event_eth_tx_adapter_txq_set(events[i].mbuf, 0);
}


问题总结

  • 方案验证中的两种方案在鲲鹏、x86环境中均进行了验证,方案修改后均未复现挂死现象。方案一会丢弃问题数据包,方案二在多发送队列场景下需要自行适配调度策略。对于挂死问题可根据业务实际需求,任选一种方案进行修改后即可修复。
  • 方案二已提交DPDK社区,Patch地址 : https://mails.dpdk.org/archives/dev/2024-August/298848.html

本页内容