ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

DPDK程序初始化遇到"tailq is already registered"错误

2021-10-01 16:31:24  阅读:1219  来源: 互联网

标签:RTE rte already eal registered register tailq name


程序链接了DPDK库,启动就出错,打出如下信息:

EAL: UIO_RESOURCE_LIST tailq is already registered PANIC in tailqinitfn_rte_uio_tailq(): Cannot initialize tailq: UIO_RESOURCE_LIST

分析发现,C语言定义constructor属性的函数会先于main()执行,DPDK中定义了RTE_INIT()宏,用来声明一个如构造函数:
#define RTE_PRIO(prio) \
    RTE_PRIORITY_ ## prio

/**
 * Run function before main() with high priority.
 *
 * @param func
 *   Constructor function.
 * @param prio
 *   Priority number must be above 100.
 *   Lowest number is the first to run.
 */
#ifndef RTE_INIT_PRIO /* Allow to override from EAL */
#define RTE_INIT_PRIO(func, prio) \
static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
#endif

/**
 * Run function before main() with low priority.
 *
 * The constructor will be run after prioritized constructors.
 *
 * @param func
 *   Constructor function.
 */
#define RTE_INIT(func) \
    RTE_INIT_PRIO(func, LAST)

在tailq.h中定义了EAL_REGISTER_TAILQ()

/**
 * Register a tail queue.
 *
 * Register a tail queue from shared memory.
 * This function is mainly used by EAL_REGISTER_TAILQ macro which is used to
 * register tailq from the different dpdk libraries. Since this macro is a
 * constructor, the function has no access to dpdk shared memory, so the
 * registered tailq can not be used before call to rte_eal_init() which calls
 * rte_eal_tailqs_init().
 *
 * @param t
 *   The tailq element which contains the name of the tailq you want to
 *   create (/retrieve when in secondary process).
 * @return
 *   0 on success or -1 in case of an error.
 */
int rte_eal_tailq_register(struct rte_tailq_elem *t);

#define EAL_REGISTER_TAILQ(t) \
RTE_INIT(tailqinitfn_ ##t) \
{ \
    if (rte_eal_tailq_register(&t) < 0) \
        rte_panic("Cannot initialize tailq: %s\n", t.name); \
}

然后用定义了很多初始化构造函数,比如rte_ring.c中:

#define RTE_TAILQ_RING_NAME "RTE_RING"

static struct rte_tailq_elem rte_ring_tailq = {
    .name = RTE_TAILQ_RING_NAME,
};
EAL_REGISTER_TAILQ(rte_ring_tailq)

所以原因是涉及到的constructor函数代码有多个实例,被重复调用。我遇到的实例是因为有重复静态链接:app链接了libxxx.a和librte_*.a, 并且libxxx.a也链接了librte_*.a,app里面就有两份librte_*.a的代码实例。

解决方法:把静态链接librte_*.a都改成动态链接librte_*.so

 

加入log,可发现在main()函数之前调用了很多EAL_REGISTER_TAILQ()函数:

EAL: rte_eal_tailq_register: name=RTE_RING
EAL: rte_eal_tailq_register: name=RTE_MEMPOOL
EAL: rte_eal_tailq_register: name=RTE_MBUF_DYNFIELD
EAL: rte_eal_tailq_register: name=RTE_MBUF_DYNFLAG
EAL: rte_eal_tailq_register: name=RTE_HASH
EAL: rte_eal_tailq_register: name=RTE_FBK_HASH
EAL: rte_eal_tailq_register: name=RTE_THASH
EAL: rte_eal_tailq_register: name=RTE_ACL
EAL: rte_eal_tailq_register: name=RTE_DIST_BURST
EAL: rte_eal_tailq_register: name=RTE_DISTRIBUTOR
EAL: rte_eal_tailq_register: name=RTE_EFD
EAL: rte_eal_tailq_register: name=RTE_KNI
EAL: rte_eal_tailq_register: name=RTE_LPM
EAL: rte_eal_tailq_register: name=RTE_LPM6
EAL: rte_eal_tailq_register: name=RTE_MEMBER
EAL: rte_eal_tailq_register: name=RTE_RIB
EAL: rte_eal_tailq_register: name=RTE_RIB6
EAL: rte_eal_tailq_register: name=RTE_REORDER
EAL: rte_eal_tailq_register: name=RTE_STACK
EAL: rte_eal_tailq_register: name=RTE_IPSEC_SAD
EAL: rte_eal_tailq_register: name=RTE_FIB
EAL: rte_eal_tailq_register: name=RTE_FIB6

标签:RTE,rte,already,eal,registered,register,tailq,name
来源: https://www.cnblogs.com/youxx/p/15359598.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有