dpdk 18 ixgbe驱动初始化分析

rte_log_set_global_level

rte_log_set_global_level(uint32_t level)

pci bus注册

TE_REGISTER_BUS(pci, rte_pci_bus.bus); drivers/bus/pci/pci_common.c ,注册静态的设置rte_pci_bus,在rte_pci_bus中设置了pci bus的各个回调函数

struct rte_pci_bus rte_pci_bus = {.bus = {.scan = rte_pci_scan,.probe = rte_pci_probe, .find_device = pci_find_device,.plug = pci_plug,.unplug = pci_unplug,.parse = pci_parse,.get_iommu_class = rte_pci_get_iommu_class,.dev_iterate = rte_pci_dev_iterate,.hot_unplug_handler = pci_hot_unplug_handler,.sigbus_handler = pci_sigbus_handler,},.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),
};          RTE_REGISTER_BUS(pci, rte_pci_bus.bus);

TE_REGISTER_BUS的定义如下:

//
/*** Helper for Bus registration.* The constructor has higher priority than PMD constructors.*/
#define RTE_REGISTER_BUS(nm, bus) \
RTE_INIT_PRIO(businitfn_ ##nm, BUS) \
{\(bus).name = RTE_STR(nm);\rte_bus_register(&bus); \
}

设置了bus name并调用rte_bus_register注册总线

RTE_INIT_PRIO、TE_INIT的定义为:

//rte_common.h:::
/*** 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.*/
#define RTE_INIT_PRIO(func, prio) \
static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)/*** 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)

设置了constructor属性,这些函数会在main函数之前执行,prio为优先级,优先级高的constructor函数会被先执行,以下是dpdk优先级的一些定义

//dpdk-stable/lib/librte_eal/common/include/rte_common.h 
#define RTE_PRIORITY_LOG 101
#define RTE_PRIORITY_BUS 110
#define RTE_PRIORITY_CLASS 120
#define RTE_PRIORITY_LAST 65535

可以看出dpdk log的相关初始化最先被执行

对于rte_bus_register,会检测被注册的总线必要的回调函数是否存在,然后将buf添加到rte_bus_list

void
rte_bus_register(struct rte_bus *bus)
{RTE_VERIFY(bus);RTE_VERIFY(bus->name && strlen(bus->name));/* A bus should mandatorily have the scan implemented */RTE_VERIFY(bus->scan);RTE_VERIFY(bus->probe);RTE_VERIFY(bus->find_device);/* Buses supporting driver plug also require unplug. */RTE_VERIFY(!bus->plug || bus->unplug);TAILQ_INSERT_TAIL(&rte_bus_list, bus, next);RTE_LOG(DEBUG, EAL, "Registered [%s] bus.\n", bus->name);
}

驱动注册

RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd);

net_ixgbe 为驱动名字,rte_ixgbe_pmd结构体是对被注册driver的描述

 /** Helper for PCI device registration from driver (eth, crypto) instance */#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \RTE_INIT(pciinitfn_ ##nm) \
{\(pci_drv).driver.name = RTE_STR(nm);\rte_pci_register(&pci_drv); \
} \

对于rte_pci_register,

void
rte_pci_register(struct rte_pci_driver *driver)
{//添加driver到listTAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next);//rte_pci_bus为全局变量driver->bus = &rte_pci_bus;
}

将驱动添加到对应的总线的driver_list。我们在看看rte_ixgbe_pmd 结构体

static struct rte_pci_driver rte_ixgbe_pmd = {.id_table = pci_id_ixgbe_map,.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,.probe = eth_ixgbe_pci_probe,.remove = eth_ixgbe_pci_remove,
};

结构体中,pci_id_ixgbe_map描述了driver支持的设备,并设置了probe、remove回调函数,在后续会扫描PCI总线上的device,并对调用rte_pci_match(dr, dev)检测device、driver匹配,匹配则进一步调用driver的probe函数。

device扫描

#0  rte_pci_scan () at  dpdk-stable/drivers/bus/pci/linux/pci.c:464
#1  rte_bus_scan () at  dpdk-stable/lib/librte_eal/common/eal_common_bus.c:78
#2  rte_eal_init (argc=argc@entry=10, argv=argv@entry=0xffffff31a8) at  dpdk-stable/lib/librte_eal/linuxapp/eal/eal.c:1028
#3  main (argc=<optimized out>, argv=0xffffff31a8) at  dpdk-stable/app/test-pmd/testpmd.c:3124

在rte_bus_scan函数中会遍历rte_bus_list,并调用每个bus注册的scan回调函数,对于本文例子就是rte_pci_scan()函数。rte_pci_scan 会遍历系统中的device设,备,并将device信息填充到rte_pci_device,最后调用pci_scan_one–>rte_pci_add_device 将device添加到rte_pci_bus.device_list

driver初始化

#0  eth_ixgbe_pci_probe	() at  dpdk-stable/drivers/net/ixgbe/ixgbe_ethdev.c:1799
#1  rte_pci_probe_one_driver () at  dpdk-stable/drivers/bus/pci/pci_common.c:199
#2  pci_probe_all_drivers () at  dpdk-stable/drivers/bus/pci/pci_common.c:273
#3  rte_pci_probe () at  dpdk-stable/drivers/bus/pci/pci_common.c:308
#4  rte_bus_probe	() at  dpdk-stable/lib/librte_eal/common/eal_common_bus.c:100
#5  rte_eal_init () at  dpdk-stable/lib/librte_eal/linuxapp/eal/eal.c:1213

在device和driver都安放好后就要开始初始化,对于PCI总线上的设备,会在rte_pci_probe遍历rte_pci_bus.device_list,对每个device调用 pci_probe_all_drivers()函数,并在函数中遍历rte_pci_bus.driver_list,使用rte_pci_match(dr, dev) 判断device和driver是否匹配,匹配则调用driver的probe。

以下是对这个过程的简化代码

FOREACH_DEVICE_ON_PCIBUS(dev){FOREACH_DRIVER_ON_PCIBUS(dr)if (!rte_pci_match(dr, dev))return 1;probe_driver();
}

by:junchao_zhao@yeah.net

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265803.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ATM + 购物商城程序

模拟实现一个ATM 购物商城程序 额度 15000或自定义 实现购物商城&#xff0c;买东西加入 购物车&#xff0c;调用信用卡接口结账 可以提现&#xff0c;手续费5% 每月22号出账单&#xff0c;每月10号为还款日&#xff0c;过期未还&#xff0c;按欠款总额 万分之5 每日计息 …

esp8266 擦拭_【一起玩esp8266】flash的擦除方法——专治疑难杂症

出现新问题。。。COM口没法操作 拒绝访问C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\Scripts>esptool.py --port COM6 erase_flashesptool.py v2.3.1Traceback (most recent call last):File "C:\Users\Administrator\AppData\Local\Programs\…

诗人李白小评

李白其实一生都不得志&#xff0c;他从小学文习武&#xff0c;少年时开始“行路&#xff0c;读万卷书&#xff0c;拜万家师”&#xff0c;希望走一条由人推荐&#xff0c;而一举成名的道路。可惜他忌恶如仇的性格&#xff0c;开罪了小人&#xff0c;导致小人对他仕途之路的极力…

智能家居 (11) ——树莓派摄像头捕捉人脸并识别

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

centos上使用高版本gcc、g++

0x0 在centos7上gcc版本是4.85&#xff0c;在编译一些代码时需要使用g的一些新特性&#xff0c;而网上大多教程都是重新编译gcc&#xff0c;太麻烦了&#xff0c;在centos 7上默认是yum search不到高版本的gcc的 安装scl scl 是Software collections 的缩写&#xff0c;安装…

【Docker系列教程之一】docker入门

我们在理解 docker 之前&#xff0c;首先我们得先区分清楚两个概念&#xff0c;容器和虚拟机。 我们用的传统虚拟机如 VMware &#xff0c; VisualBox 之类的需要模拟整台机器包括硬件&#xff0c;每台虚拟机都需要有自己的操作系统&#xff0c;虚拟机一旦被开启&#xff0c;预…

jmeter聚个报告怎么看qps_【jmeter】jmeter测试网站QPS

上一节中&#xff0c;我们了解了jmeter的一此主要元件&#xff0c;那么这些元件如何使用到性能测试中呢。这一节创建一个简单的测试计划来使用这些元件。该计划对应的测试需求。1)测试目标网站是fnng.cnblogs.com2)测试目的是该网站在负载达到20 QPS 时的响应时间。QPS 解释QPS…

mysql升级5.5

对付Linux的问题&#xff0c;其实很多都是权限问题&#xff0c;细心想一下即可。 centos6.4默认装的是mysql5.1&#xff0c;使用 yum update 也update不了。google了一下&#xff0c;找到个yum安装的方法&#xff1a;http://www.webtatic.com/packages/mysql55/ 先备份一下&…

Java基础 —— 变量,选择,循环,数组,输入与输出等

目录嵌入式学JAVAJava安卓开发环境搭建并运行HelloWorld概念引入JavaSE,EE,ME的区别JREJDK编程实操&#xff1a;从C面向过程转变变量定义与输出数组的定义与遍历(循环、控制、选择和C完全一样)函数的调用&#xff1a;类比c语言结构体的使用输入数据&#xff1a;Scanner嵌入式学…

ubuntu20 编译dpdk错误 -Werror=address-of-packed-member

0x0 在ubuntu20上编译dpdk 18.11报错&#xff0c;gcc 版本为9.3.0&#xff0c;报错如下&#xff1a; error: converting a packed ‘const struct ether_addr’ pointer (alignment 1) to a ‘unaligned_uint16_t’ {aka ‘const short unsigned int’} pointer (alignment 2…

linux 火狐无法执行二进制文件_尝试在Linux上运行Shell脚本时“无法执行二进制文件”...

我对linux和shell编写非常陌生。我正在尝试使用以下命令从linux上的安全shell(ssh)运行shellscript&#xff1a;chmod x path/to/mynewshell.shsh path/to/mynewshell.sh我收到此错误&#xff1a;path/to/mynewshell.sh: path/to/mynewshell.sh: cannot execute binary file.尝…

Java 特性

Java有四大特性&#xff1a; 1.封装&#xff1a;隐藏对象的属性和实现细节&#xff0c;仅仅对外公开接口。 封装具有一下优点&#xff1a; 便于使用者正确、方便的使用系统&#xff0c;防止使用者错误修改系统属性&#xff1b;有助于建立各个系统之间的松耦合关系&#xff1b;…

MyBatis 传递多个参数

2019独角兽企业重金招聘Python工程师标准>>> 在MyBatis中可以用以下的方式来传递多个参数 1. 用java.util.Map来传递, Code 如下: public List<User> getAllUsersByUserName(String username, int start, int limit){Map<String,Object> params new H…

Linux stmac网卡代码分析----probe

probe 主要分析一下驱动的主要框架&#xff0c;必要地方细致分析下 文件位置&#xff1a; drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c 从文件的最后看起&#xff1a; module_pci_driver(stmmac_pci_driver); stmmac_pci_driver结构体如下&#xff0c;里面包含了id_…

Java面向对象(1) —— 封装

目录一、封装的概念二、类的封装以及使用三、访问修饰符四、属性封装的实现五、方法封装的实现六、UML类图七、类的构造方法与可重载八、this关键字九、static关键字十、方法重载&#xff1a;overload十一、包&#xff1a;package一、封装的概念 将字段&#xff08;C结构体中的…

太阳能板清洗机器人科沃斯_科沃斯推出水清洗扫地机器人 要把打扫做的更彻底...

传统的扫地机器人只能对家里的灰尘做简单清扫&#xff0c;要想打扫的更彻底&#xff0c;还是得靠周末自己拿上工具水洗一遍。现在科沃斯就推出了可以帮你用水清洗地面的扫地机器人&#xff0c;不用再担心地面清洁不干净。科沃斯扫地机器人的水清洁方式一共分为五步&#xff0c;…

linux下源码软件包的安装

我们在使用linux做服务器的时候&#xff0c;因为linux自带的软件包都有些老&#xff0c;不是最新的&#xff0c;但是有时候我们为了使用最新的软件&#xff0c;会使用最新的软件的源码来进行安装。所以我们需要用心去做了...在我们拿到一个软件的源码时&#xff0c;源码一般都是…

react-native 打包apk 并解决 图片 不出现问题

react-native官网打包apk方法&#xff1a;https://reactnative.cn/docs/signed-apk-android/ 解决办法&#xff1a; 找到项目 android目录下 gradle.properties文件 打开加入如下代码&#xff1a; android.enableAapt2false这段代码非常重要 官网缺少 。不然打包apk图片不出现。…

龙芯派2亚克力外壳

0x0 龙芯派自带的亚克力顶板没有风扇的孔位&#xff0c;在长时间运行时亚克力板很烫&#xff0c;因此我设计了个带风扇孔位的亚克力顶板 效果如下&#xff1a; 风扇规格 4X4风扇 供电由龙芯派的GPIO上的5V管脚供电 使用方法 1.某宝搜索亚克力板定制 2. 将本文件发送给店家…

Java面向对象(2) —— 继承

目录前言继承的概念和实现extends关键字super关键字继承过来的属性和方法的权限研究方法重写OverrideObject根类常见方法toString()常把toString()方法重写后应用equals()重写&#xff1a;判断两个对象p1和p2特征是否相同IDEA的重写模板&#xff1a;敲equals可选择的方案之一St…