1.  修改配置文件 .conf, 设置如下变量的值.

[root@D129 x86_64-native-linuxapp-gcc]# cat dpdk/x86_64-native-linuxapp-gcc/.config |grep SHARE
CONFIG_RTE_BUILD_SHARED_LIB=y

2.  这个时候, 再编译的 dpdk app就会自动链接dpdk的动态库. 如下:

[root@D129 app]# ldd testpmd
linux-vdso.so. => (0x00007ffed89fd000)
librte_kni.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_kni.so. (0x00007fe9c983f000)
librte_pipeline.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pipeline.so. (0x00007fe9c962b000)
librte_table.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_table.so. (0x00007fe9c93ed000)
librte_port.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_port.so. (0x00007fe9c9191000)
librte_pdump.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pdump.so. (0x00007fe9c8d77000)
librte_distributor.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_distributor.so. (0x00007fe9c8b74000)
librte_reorder.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_reorder.so. (0x00007fe9c8965000)
librte_ip_frag.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_ip_frag.so. (0x00007fe9c8724000)
librte_meter.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_meter.so. (0x00007fe9c8521000)
librte_sched.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_sched.so. (0x00007fe9c830d000)
librte_lpm.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_lpm.so. (0x00007fe9c80ff000)
librte_acl.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_acl.so. (0x00007fe9c7ee5000)
librte_jobstats.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_jobstats.so. (0x00007fe9c7ce2000)
librte_power.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_power.so. (0x00007fe9c7acd000)
librte_timer.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_timer.so. (0x00007fe9c78c3000)
librte_hash.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_hash.so. (0x00007fe9c76af000)
librte_vhost.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_vhost.so. (0x00007fe9c7477000)
librte_kvargs.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_kvargs.so. (0x00007fe9c7274000)
librte_mbuf.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_mbuf.so. (0x00007fe9c7071000)
libethdev.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/libethdev.so. (0x00007fe9c6dd6000)
librte_cryptodev.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_cryptodev.so. (0x00007fe9c6bc1000)
librte_mempool.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_mempool.so. (0x00007fe9c69b9000)
librte_ring.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_ring.so. (0x00007fe9c67b5000)
librte_eal.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_eal.so. (0x00007fe9c6546000)
librte_cmdline.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_cmdline.so. (0x00007fe9c633b000)
librte_cfgfile.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_cfgfile.so. (0x00007fe9c6137000)
librte_pmd_bond.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pmd_bond.so. (0x00007fe9c5efa000)
libgcc_s.so. => /lib64/libgcc_s.so. (0x00007fe9c5cd9000)
libdl.so. => /lib64/libdl.so. (0x00007fe9c5ad4000)
libpthread.so. => /lib64/libpthread.so. (0x00007fe9c58b8000)
libc.so. => /lib64/libc.so. (0x00007fe9c54f5000)
/lib64/ld-linux-x86-.so. (0x00007fe9c9a51000)
libm.so. => /lib64/libm.so. (0x00007fe9c51f2000)
librt.so. => /lib64/librt.so. (0x00007fe9c4fea000)
[root@D129 app]#

3.  但是与static的时候对比, 你会发现有如下的问题:

  用static链接的时候, rte_init的时候,会扫描所有的PCI设备,找到所有可用的port, 如下:

[root@D129 app]# ./testpmd
EAL: Detected lcore(s)
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device 0000:00:03.0 on NUMA socket -1
EAL: probe driver: 1af4:1000 rte_virtio_pmd
EAL: PCI device 0000:00:04.0 on NUMA socket -1
EAL: probe driver: 1af4:1000 rte_virtio_pmd
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=, size=, socket=
RING: Cannot reserve memory
EAL: Error - exiting with code:
Cause: Creation of mbuf pool for socket failed: Cannot allocate memory
[root@D129 app]#

  在使用shared so库的时候, 会发现,dpdk app扫描不到任何 PCI 设备了. 如下:

[root@D129 app]# ./testpmd
EAL: Detected lcore(s)
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: No probed ethernet devices
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=, size=, socket=
RING: Cannot reserve memory
EAL: Error - exiting with code:
Cause: Creation of mbuf pool for socket failed: Cannot allocate memory

  这个时候,我们ldd app,会发现, 它并没有ld到pmd的so,

[root@D129 app]# ldd testpmd |grep pmd
librte_pmd_bond.so. => /root/Src/copyright/j/dpdk/x86_64-native-linuxapp-gcc/lib/librte_pmd_bond.so. (0x00007fa25689a000)
[root@D129 app]#

  猜测, dpdk在shared的情况下, pmd的库,是需要动态加载的. 并找到如下参数:

[root@D129 app]# ./testpmd -h |grep -A1 LIB.so
-d LIB.so|DIR Add a driver or driver directory
(can be used multiple times)

  使用 -d 参数制定 virtio的so, (我的虚拟机是virtio的网络设备), 果然生效了

[root@D129 app]# ./testpmd  -d ../lib/librte_pmd_virtio.so
EAL: Detected lcore(s)
EAL: Probing VFIO support...
EAL: WARNING: cpu flags constant_tsc=yes nonstop_tsc=no -> using unreliable clock cycles !
EAL: PCI device ::03.0 on NUMA socket -
EAL: probe driver: 1af4: rte_virtio_pmd
EAL: PCI device ::04.0 on NUMA socket -
EAL: probe driver: 1af4: rte_virtio_pmd
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=, size=, socket=
RING: Cannot reserve memory
EAL: Error - exiting with code:
Cause: Creation of mbuf pool for socket failed: Cannot allocate memory
[root@D129 app]#

4.  问题分析

  参考 dpdk 的源码 ../dpdk/lib/librte_eal/common/eal_common_options.c::eal_plugins_init()

  在读取 -d 参数的同时, dpdk在 rte_init函数中还会读取 RTE_EAL_PMD_PATH 目录下的文件,  所有读到的文件会使用 dlopen() 打开. 详细逻辑参见代码.

  变量RTE_EAL_PMD_PATH的值由CONFIG_RTE_EAL_PMD_PATH在编译的时候决定.

5.  参考redhat的rpm spec, 最终的解决方案是这样的.

5.1  生成一个编译与运行时都存在的目录: /lib64/tong-dpdk-pmds/,

5.2  将所以pmd软链接到这个目录下

[root@D129 app]# ll /lib64/tong-dpdk-pmds/
total
lrwxrwxrwx root root Jul : librte_pmd_af_packet.so. -> ../librte_pmd_af_packet.so.
lrwxrwxrwx root root Jul : librte_pmd_bnxt.so. -> ../librte_pmd_bnxt.so.
lrwxrwxrwx root root Jul : librte_pmd_bond.so. -> ../librte_pmd_bond.so.
lrwxrwxrwx root root Jul : librte_pmd_cxgbe.so. -> ../librte_pmd_cxgbe.so.
lrwxrwxrwx root root Jul : librte_pmd_e1000.so. -> ../librte_pmd_e1000.so.
lrwxrwxrwx root root Jul : librte_pmd_ena.so. -> ../librte_pmd_ena.so.
lrwxrwxrwx root root Jul : librte_pmd_enic.so. -> ../librte_pmd_enic.so.
lrwxrwxrwx root root Jul : librte_pmd_fm10k.so. -> ../librte_pmd_fm10k.so.
lrwxrwxrwx root root Jul : librte_pmd_i40e.so. -> ../librte_pmd_i40e.so.
lrwxrwxrwx root root Jul : librte_pmd_ixgbe.so. -> ../librte_pmd_ixgbe.so.
lrwxrwxrwx root root Jul : librte_pmd_null_crypto.so. -> ../librte_pmd_null_crypto.so.
lrwxrwxrwx root root Jul : librte_pmd_null.so. -> ../librte_pmd_null.so.
lrwxrwxrwx root root Jul : librte_pmd_ring.so. -> ../librte_pmd_ring.so.
lrwxrwxrwx root root Jul : librte_pmd_vhost.so. -> ../librte_pmd_vhost.so.
lrwxrwxrwx root root Jul : librte_pmd_virtio.so. -> ../librte_pmd_virtio.so.
lrwxrwxrwx root root Jul : librte_pmd_vmxnet3_uio.so. -> ../librte_pmd_vmxnet3_uio.so.

5.2 在编译前, 设置变量CONFIG_RTE_EAL_PMD_PATH

[root@D129 app]# cat ../.config |grep PATH
CONFIG_RTE_EAL_PMD_PATH="/lib64/tong-dpdk-pmds/"

以上, dpdk app便可以使用 shared lib 正常运行了.

6. 另一个方案:  使用 -d, 需要神马加神马, 比如:

[root@D129 app]# ./testpmd  -d ../lib/librte_pmd_virtio.so  -d ../lib/librte_pmd_ixgbe.so

完.

[dpdk] dpdk编译成动态库使用 -- PCI port自动发现与pmd动态加载的更多相关文章

  1. 动态库连接器–动态库链接信息(Mach-O文件格式和程序从加载到执行过程)

    section cmd 说明 举例 __text 主程序代码   __stubs 用于动态库链接的桩   __stub_helper 用于动态库链接的桩   __cstring 常亮字符串符号表描述信 ...

  2. dlib编译成静态库及被其它程序调用

    一.git下载:https://github.com/davisking/dlib 官网:http://dlib.net/ 二.vs中编译成静态库 1.在vs2015中创建静态库工程(vs2015以上 ...

  3. java编译通过,为什么运行却提示找不到或无法加载主类?

    java编译通过,为什么运行却提示找不到或无法加载主类? https://www.zhihu.com/question/36537093 这边提供一个关于程序中含有package关键字,使用“终端”运 ...

  4. (原)vs2013编译成静态库

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5477664.html 1. 在“属性”-“配置属性”-“常规”-“配置类型”里面设置“静态库(.lib ...

  5. Aandroid 图片加载库Glide 实战(一),初始,加载进阶到实践

    原文: http://blog.csdn.net/sk719887916/article/details/39989293 skay 初识Glide 为何使用 Glide? 有经验的 Android ...

  6. 今天遇到一件开心事,在eclipse编写的代码在命令窗口中编译后无法运行,提示 “错误: 找不到或无法加载主类”

    java中带package和不带package的编译运行方式是不同的. 首先来了解一下package的概念:简单定义为,package是一个为了方便管理组织java文件的目录结构,并防止不同java文 ...

  7. NDK下 将Platinum SDK 编译成so库 (android - upnp)

    Platinum UPnP SDK 是一个跨平台的C++库,利用该库,可以很容易就构建出DLNA/UPnP控制点(DLNA/UPnP Control Point)和DLNA/UPnP设备(DLNA/U ...

  8. Cmake编译成静态库

    To build OpenCV as static library you need to set BUILD_SHARED_LIBS flag to false/off: cmake -DBUILD ...

  9. 后台返回平铺数据,如何转换成树形json并渲染树形结构,ant tree 异步加载

    如何后台返回对象数组(平铺式) 1.根据字段标识(板块)获取根节点 ### initTreeData(dataOrg){ var resultArr=dataOrg[0] var secArr=[]; ...

随机推荐

  1. pattern-matching as an expression without a prior match -scala

    https://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html https://docs.scala-lang. ...

  2. Coding in Delphi(前4章翻译版本) (PDF)

      第四章翻译完成有一段时间了 写在前面的话       本次翻译纯属爱好,目的是提高对英文文档的理解和阅读能力,本文档大部分采用直 译的方式,而且保留了原来的英文.目的只是辅助大家理解,不喜勿喷.翻 ...

  3. 用Jmeter+Badboy+Fiddler做接口测试

    用Jmeter+Badboy+Fiddler做接口测试 2016-12-05 目录: 1 简介2 Badboy录制3 Jmeter打开Badboy脚本4 用Fiddler抓请求,补充完善脚本5 测试中 ...

  4. Python3自定义http/https请求拦截mitmproxy脚本

    [本文出自天外归云的博客园] 脚本内容 代码如下: from mitmproxy import http, ctx from multiprocessing import Lock class Fil ...

  5. MXNET:分类模型

    线性回归模型适用于输出为连续值的情景,例如输出为房价.在其他情景中,模型输出还可以是一个离散值,例如图片类别.对于这样的分类问题,我们可以使用分类模型,例如softmax回归. 为了便于讨论,让我们假 ...

  6. JavaScript Scroll家族以及封装

    JavaScript Scroll家族以及封装 scrollTop & scrollLeft 别卷去的值,就是当滑动滚轮浏览网页的时候,网页隐藏在屏幕上方或左侧的距离 获得scrollTop ...

  7. MYSQL + MHA +keepalive + VIP安装配置(二)--MHA的配置

    一.总概 1.MHA介绍 MHA(Master High Availability)是自动的master故障转移和Slave提升的软件包.它是基于标准的MySQL复制(异步/半同步).      MH ...

  8. How to Catch Ctrl-C in Shell Script

    ref: https://stackpointer.io/script/how-to-catch-ctrl-c-in-shell-script/248/   #!/bin/sh # this func ...

  9. Java8学习笔记(五)--Stream API详解[转]

    为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...

  10. JAVA WEB -- request

    request request.getContextPath()  返回站点的根目录 request.getRealpath("/")得到的是实际的物理路径,也就是你的项目所在服务 ...