C语言
文章平均质量分 90
C语言是一种通用的、过程式的计算机程序设计语言。是一种结构化语言。C语言是Unix和类Unix系统的主要编程语言,它对操作系统和系统级应用程序的开发至关重要。C语言特点:结构化语言、直接访问硬件、内存管理、高效性能、丰富的标准库。学习C语言有助于更好地理解计算机系统的底层机制。
109702008
数字人-幺洞勾拐洞两洞洞八
展开
-
【C语言】Infiniband驱动pci_pcie_cap
PCIe功能偏移量是在PCI设备初始化时计算并保存的。注释中的函数`pci_pcie_cap`对应于一个内联函数,它接受一个指向PCI设备结构的指针,返回PCIe能力结构在PCI配置空间中的偏移。第二部分是 #define pci_pcie_cap LINUX_BACKPORT(pci_pcie_cap) 定义,这一行代码实际上将 pci_pcie_cap 符号重命名为 backport_pci_pcie_cap,意在使用已经传递过来的 pci_pcie_cap 函数,但通过新名称避免潜在的名称冲突。原创 2024-03-28 07:41:17 · 703 阅读 · 2 评论 -
【C语言】Infiniband驱动mlx4_reset
请注意,这些注释更确切地描述了代码中的每个重要步骤,并对原开发者的注释进行翻译以更好地帮助中文读者理解代码。这段代码涉及到硬件层面的操作,这其中包括了对PCI设备的配置空间的保存、设备重置以及恢复的过程。这部分代码主要执行了芯片的重置过程,并且在重置前后操作了PCI头部信息的保存与恢复,以确保设备能够在重置之后正常工作。它保存了设备的 PCI 头信息,然后重置了设备,之后还原保存的 PCI 头信息。在函数中,定义了一些宏和它们的值:这些宏用于方便地引用重置流程中所需要的一些硬件寄存器的偏移量和相关的值。原创 2024-03-27 11:11:21 · 957 阅读 · 5 评论 -
【C语言】Infiniband驱动init_dev_assign函数
这是一个循环,它遍历`dev_assign_str`表,表的大小由`MLX4_DEVS_TBL_SIZE`指定。如果分配失败,跳转到错误处理。这段代码主要负责使用设备号字符串(`dev_assign_str`)来初始化一个位图(`dev_num_str_bitmap`),这个位图用来保存设备号和它们的状态。这是错误处理的标签部分:如果在位图分配过程中出现错误,释放先前分配的位图内存,将位图指针设置为`NULL`,并打印警告信息说明`dev_assign_str`参数的值不正确,并且该参数值将被丢弃。原创 2024-03-27 11:05:24 · 710 阅读 · 0 评论 -
【C语言】Infiniband驱动__mlx4_init_one函数
8. 错误处理:一系列的错误处理标签(`err_catas`,`err_crdump`,`err_release_regions`,`err_disable_pdev`),分别对应不同阶段的初始化失败处理,包括释放资源和禁用设备等。4. 检查通过`num_vfs`和`probe_vf`模块参数指定的VF数量的有效性,它们必须是非负的,并且`probe_vf`不能超过`num_vfs`指定的值。2. 函数尝试使PCI设备可用(`mlx4_pci_enable_device`),并检查是否成功。原创 2024-03-26 13:27:52 · 824 阅读 · 2 评论 -
【C语言】Infiniband驱动mlx4_init_one
这段代码主体是一个`mlx4_init_one`函数,它是Mellanox公司网络设备驱动的初始化函数,用于对PCI网络设备进行初始化。如果启用了`devlink`配置选项(用于一些设备的配置和监控功能),它会额外处理`devlink`相关的注册和初始化。这在系统休眠或PCI设备电源管理事件中是必要的,因为在这样的事件中,设备的PCI配置可能会丢失或被重置,系统在恢复时需要这信息重新对设备进行配置。这段代码展示了复杂PCI设备驱动初始化流程的一部分,包括资源的分配和初始化,以及设备在系统内的注册。原创 2024-03-26 13:20:48 · 451 阅读 · 0 评论 -
仿照linux内核的链表构造并遍历
程序:#include "stdio.h"#include "stdlib.h"struct list_head { struct list_head *next, *prev;};#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name)#define offsetof(原创 2021-01-22 19:35:52 · 152 阅读 · 1 评论 -
gcc里的布尔值类型
在GCC里定义一个布尔值类型变量。1. 从C99标准开始,类型名字为“2. 枚举(“仿布尔型”)原创 2021-01-22 14:40:24 · 344 阅读 · 0 评论 -
linux打印不同数据类型的地址偏移
例如,即使`char`只需要1个字节,`int`成员在结构体中的实际地址可能是按4个或8个字节对齐的(这取决于系统和编译器)。尽管如此,这段程序在某些环境下运行可能得到看似合理的输出,那是因为编译器和运行环境对于对NULL指针的不当操作采取了某种隐晦的处理。之后,我们创建了一个结构体并打印了它的每个成员的地址,以及这些地址相对于结构体实例起始地址的偏移量。在Linux C编程中,如果你想打印出不同类型的数据成员在结构体或其他数据类型中的地址偏移量,可以使用offsetof宏。代表空指针,它的值为0。原创 2021-01-06 21:33:57 · 159 阅读 · 0 评论 -
使用swig将C代码转为JAVA接口的例子(Win10平台)
http://www.swig.org/download.html下载Windows 版本swigwin-4.0.2.zip,解压缩。安装java,配置好java的环境。配置环境变量JAVA_BIN和JAVA_INCLUDE。比如:JAVA_BIN:C:\Program Files\Java\jdk-12.0.2\binJAVA_INCLUDE:C:\Program Files\Java\jdk-12.0.2\include原创 2020-09-22 17:39:32 · 249 阅读 · 0 评论 -
C语言中数组首地址和数组第一个元素的地址有什么区别
C语言中数组首地址和数组第一个元素的地址关系如下:1、它们的地址值是相等的。2、第1个元素的地址如果是p,则p+1就是第2个元素的地址。3、数组的首地址如果是p,则p+1就跳过这个数组而指向这个数组最后一个元素最后一个字节的下一字节。原创 2020-12-15 16:53:28 · 3653 阅读 · 1 评论 -
C和C++的const对比
但是在C++编译器中,修改可能没有被实际写入内存中的`const`变量或者编译器可能进行了优化,并假定`const`变量不能被改变,结果是即使内存内容改变了,`b`的原始值`1`可能会被编译器硬编码或缓存到了某处,因此打印了`b=1`。尽管语法上允许这样的强制类型转换,但实际的行为是未定义的,这意味着编译器可以自由选择如何处理这段代码,可能导致不同的编译器或不同的运行时环境给出不同的结果。正确编程习惯应该避免修改`const`修饰的内存区域,如果需要修改变量的值,那么它就不应该被声明为`const`。原创 2020-07-21 17:13:58 · 97 阅读 · 0 评论 -
C与C++的struct使用对比
int data;int text;} S1;//这种方法可以在c或者c++中使用struct S2int data;int text;//C++中上面的代码类似于类,可以用 S2 s再定义一个变量;C语言定义变量需要用sruct S2 s。int text;} S3;//这种方法并没有定义一个结构,而是定义了一个S3的结构变量。S4* ptr;// 这种写法只能在C++中使用,S4类似一个类} S5;原创 2020-07-16 20:01:38 · 190 阅读 · 2 评论 -
【C语言】tcp_sendmsg_locked
整体上,`tcp_sendmsg_locked` 函数处理了一系列复杂的 TCP 发送逻辑,包括 TCP 发送缓冲区的管理、段的创建及填充、发送拥塞控制、零拷贝优化等。该函数首先锁定目标socket,然后调用实际发送消息实现的内部函数`tcp_sendmsg_locked`,发送过程完成后释放锁,并返回发送操作的结果(成功发送的字节数或错误码)。这个函数`tcp_sendmsg`用于处理TCP socket的发送消息操作。- 数据发送后,函数执行必要的清理操作,返回拷贝的字节数,或者发送失败时的错误码。原创 2024-03-25 15:28:15 · 855 阅读 · 2 评论 -
【C语言】linux内核pci_set_drvdata函数
由于PCI设备结构体`struct pci_dev`中包含了一个设备模型结构体`struct device`(通过`pdev->dev`访问),这行代码实际上是将数据与PCI设备的设备模型部分关联起来,方便以后的检索和使用。这个函数的参数包括一个指向`pci_dev`结构体的指针`pdev`,该结构体描述了一个PCI设备,以及一个`void *类型的指针data`,这个指针用来指向驱动程序希望与该PCI设备相关联的任何数据。- pdev:指向 pci_dev 结构的指针,该结构代表了特定的PCI设备。原创 2024-03-24 13:49:53 · 1060 阅读 · 3 评论 -
【C语言】linux内核pci_iomap
上述代码是Linux内核中的一个函数注释,它是用于将PCI设备的某个BAR(基址地址寄存器)区域映射到内核虚拟地址空间,以便于内核或驱动程序可以直接通过这个虚拟地址对硬件设备进行访问。这两个函数都是用来建立PCI设备的BAR(Base Address Register,基址寄存器)到进程的虚拟地址空间的映射。函数,但是将 offset 设置为0,目的是简化对整个BAR的映射,而不是基于某个特定的起始偏移量。pci_iomap是一个简化的版本,它默认从BAR的起始处映射整个区域,或者是指定长度的内存。原创 2024-03-24 13:30:14 · 535 阅读 · 0 评论 -
【C语言】linux内核pci_alloc_irq_vectors
总的来说,如果调用 pci_alloc_irq_vectors,将使用的 pci_alloc_irq_vectors_affinity 是在 .c 文件中实际定义的,除非在该 .c 文件包含的头文件中提供了一个内联定义以覆盖。最后是一个辅助函数`pci_alloc_irq_vectors`,这个函数封装了对`pci_alloc_irq_vectors_affinity`的调用,但是不需要传递亲和性描述,是一个更为简单的版本。通常,这个版本应该是实际使用的版本,因为它包含分配向量所需的实际逻辑。原创 2024-03-23 06:06:26 · 842 阅读 · 3 评论 -
【C语言】linux内核pci_set_master
函数则是一个更高级的接口,通常由驱动程序调用以启用设备的总线主控功能,并随后调用`pcibios_set_master`函数完成体系结构相关的设置。通过EXPORT_SYMBOL宏,这个函数被导出,使得其他内核模块可以调用它。这个函数专注于设置或清除PCI命令寄存器中控制总线主控的位。如果启用,它会设置这个位;如果禁用,它会清除这个位。更新操作只会在这个位的状态实际改变时发生。函数是用来做一些体系结构特定的总线主控设置的。它检查并可能会调整PCI设备的延迟定时器值以避免PCI总线拥塞。原创 2024-03-23 05:50:39 · 347 阅读 · 0 评论 -
【C语言】linux内核pci_enable_device函数和_PCI_NOP宏
在这段代码中,`pci_enable_device_flags` 是一个静态函数,它接受两个参数:一个指向 PCI 设备的指针和一个标志集合。函数的目的是启用指定的 PCI 设备,但首先会检查设备的电源管理(PM)能力和当前的电源状态,并递增设备的启用计数。定义了指向PCI设备的桥接器的指针`bridge`,一个整型错误码`err`以及两个整型变量`i`和`bars`,其中`bars`用于跟踪需要启用的设备资源条目(BARs)。这是一个外部可见的函数,用默认的标志(内存和I/O资源)来启用一个PCI设备。原创 2024-03-22 06:17:04 · 671 阅读 · 0 评论 -
【C语言】Infiniband驱动mlx4_pci_table
这个数组里包含了各种 Mellanox 设备的具体型号,例如 "MT25408" (也称为 "Hermon")以及不同速率的版本(SDR, DDR, QDR),还有 "ConnectX" 系列的不同版本例如 "ConnectX-3" 和 "ConnectX-3 Pro"。这些宏(MLX_SP、MLX_VF、MLX_GN)是为 Mellanox 专门定义的,用来初始化 pci_device_id 结构体中的元素。PCI_DEVICE_ID_... 是定义在其他文件中的宏,代表特定的 PCI 设备 ID。原创 2024-03-21 09:16:47 · 687 阅读 · 1 评论 -
【C语言】access和stat函数
在C语言中,`access` 函数是一个用于检查文件的存在性以及对文件的访问权限的函数。在代码中直接使用对应的宏(如 F_OK),而非硬编码的整数(如 0),可以提高代码的可读性和可移植性。stat 函数成功执行时,将返回0,并将文件的信息填入通过参数 buf 传递的结构体中。在C语言中,`stat` 函数是一个用来获取文件状态信息的函数,定义在 <sys/stat.h> 头文件中。- 如果任一测试失败,或者发生错误,函数返回-1,并且`errno`会被设置为一个特定的错误代码,表明检查失败的原因。原创 2024-03-20 08:08:23 · 1128 阅读 · 2 评论 -
【C语言】遍历目录树
ftw()和`nftw()`在内部可能会使用`readdir()`或类似的系统调用(如`open()`, read(), close() 以及可能的`stat()` 或 lstat())来获取目录内容及文件信息。文件的修改时间 (st_mtime), 访问时间 (st_atime), 和状态改变时间 (st_ctime) 不是直接保存在文件内容中的,而是在文件系统的元数据(metadata)中记录的。ftw()和`nftw()`对`readdir()`进行了高级封装,简化了递归遍历文件系统的复杂性。原创 2024-03-20 08:07:34 · 1261 阅读 · 1 评论 -
【C语言】守护进程(daemon)的输出到一个文本文件
接下来,调用`dup(0)`复制文件描述符0(也就是之前打开的`/dev/null`),因为在文件描述符1和2被关闭之后,`dup`调用会使用最低的、未被使用的文件描述符号,也就是先是1然后是2,因此这一步相当于重新定向了进程的标准输出到`/dev/null`,然后又将标准错误也重定向到了`/dev/null`。如果想重定向守护进程的输出到 /var/log/daemon.log ,需要使用`open`系统调用首先打开这个文件,然后才能用`dup`或`dup2`复制相应的文件描述符。原创 2024-03-19 04:53:22 · 1189 阅读 · 1 评论 -
【C语言】linux内核pci_save_state
该函数用于在挂起设备之前保存PCI设备的配置空间。`pci_save_pcie_state`、`pci_save_pcix_state`和`pci_save_vc_state`这些函数分别用于保存PCI Express、PCI-X和虚拟通道(如果它们适用)的额外状态。当调用 pci_read_config_dword 函数时,它从PCI设备的配置空间读取出必要的信息,并将这些信息存储到 struct pci_dev 结构体的 saved_config_space 数组中,该结构体通常保存在主机的内存中。原创 2024-03-16 09:18:20 · 1153 阅读 · 1 评论 -
【C语言】C语言中执行命令
在C语言编程中,执行命令通常是通过调用库函数完成的。原创 2024-03-14 09:04:01 · 921 阅读 · 2 评论 -
linux c语言中执行命令时,命令行包含的文件名中有空格的问题
比如,调用下面的函数来执行命令。如果命令语句cmd中,有文件名字符串filename,应该在filename两端加双引号。原创 2021-10-10 21:27:05 · 516 阅读 · 0 评论 -
【C语言】编译过程中查看某个宏的值
要查看宏的值,应该使用字符串化运算符 # 来将宏转换为字符串,但是由于 #pragma message 本身就是预处理器指令,所以正确的使用方式是直接在后面跟上宏的名称。比如,如果编译器不支持直接在 #pragma message 中使用宏展开,可能需要转而使用其他实现定义,或者简单地使用 printf 在程序运行时输出宏的值。: 如果在使用GCC,可以使用`#pragma message`来输出宏的值。在C语言中,使用 #pragma message 打印宏的值时,应当直接使用宏的名称。原创 2024-03-13 08:40:06 · 1113 阅读 · 1 评论 -
【C语言】Linux内核pci_read_config_和pci_write_config_
如果设备已经断开,则函数会返回一个错误码`PCIBIOS_DEVICE_NOT_FOUND`。pci_read_config_byte、`pci_read_config_word`、`pci_read_config_dword`函数可以分别读取1个字节、2个字节和4个字节的数据。如果设备连接正常,函数会通过调用`pci_bus_read_config_byte`、`pci_bus_read_config_word`或`pci_bus_read_config_dword`来实际完成数据的读取操作。原创 2024-03-11 09:03:48 · 1085 阅读 · 1 评论 -
【C语言】InfiniBand驱动mlx4_register_interface函数
这通常涉及读取和写入PCIe配置空间、映射内存空间、处理中断等任务,可能使用诸如`pci_read_config_*, pci_write_config_*, pci_enable_device`, pci_set_master, pci_alloc_irq_vectors, pci_iomap, pci_set_drvdata等PCIe底层函数。3. 分配成功后,开始初始化`dev_ctx`结构体的成员:指向接口的指针`intf`和通过接口提供的`add`函数回调来获得的设备上下文`context`。原创 2024-03-11 08:58:55 · 1031 阅读 · 0 评论 -
【C语言】tcp_transmit_skb
1. 函数接收一些参数:`sk`是指向socket结构的指针,`skb`是待发送的数据包,`clone_it`指示是否需要克隆`skb`,`gfp_mask`定义了内存分配标志,`rcv_nxt`是接收方期望收到的下一个序列号。在函数调用 __tcp_transmit_skb 后,任何实际的数据包传输、重传和解包处理都是在 __tcp_transmit_skb 函数中完成的,而 tcp_transmit_skb 本身的作用主要是一个中间调用层。它的作用是发送一个TCP段。原创 2024-03-10 06:55:32 · 1029 阅读 · 1 评论 -
【C语言】linux内核ip_local_out函数
总体来说,`dst_output` 函数的职责是调用正确的输出处理函数,这个函数由路由子系统在数据包通过路由选择的过程中确定,数据包将基于路由信息被发送到正确的网络接口。实际的`dst_entry`结构体和相关函数的定义可以在内核源代码的路由(routing)相关的文件中找到,例如`include/net/dst.h`和相关的`net/ipv4`或`net/ipv6`目录下的文件。skb_dst 几乎在所有内核版本中都是通过宏定义实现的,因此你不会在代码中找到一个名为`skb_dst`的函数。原创 2024-03-09 18:12:38 · 1196 阅读 · 1 评论 -
【C语言】linux内核tcp_write_xmit和tcp_write_queue_purge
tcp_cwnd_test(tp, skb) 和 tcp_snd_wnd_test(tp, skb, mss_now) 分别检查拥塞窗口(cwnd)和发送窗口(snd_wnd),以确保我们没有发送超出对方TCP流控制和拥塞控制的数据。4. 确定发送大小:对于要发送的SKB,它会计算出可以一次发送多少数据(TSO分段,即TCP段上合并发送),以及是否应该延迟发送,从而进行网络流量整形。7. 后处理:函数的最后部分会基于发送情况更新一些计时器,比如记录流控制限制的时间,决定是否触发进一步的丢包探测等。原创 2024-03-09 17:52:01 · 615 阅读 · 0 评论 -
一个打印数组地址的例子
没有使用volatile时,汇编指令可能会减少内存访问的次数(例如,使用寄存器来存储临时值),而使用了volatile关键字后,每次访问都会直接从内存地址中加载或者存储,来保证读取最新的数据。3. 打印数组 a 的地址。5. 讨论中的一个可能的错误来源是硬件的设置问题(例如FPGA逻辑设计上的错误或者总线配置问题),这可能导致寄存器的值在没有软件干预的情况下发生变化。- 第二个 printf 输出的是数组 a 的地址加上整个数组的大小后的地址,即数组之后的第一个位置的地址(同样,这是一个示例地址)。原创 2014-11-26 18:23:16 · 260 阅读 · 0 评论 -
【C语言】Infiniband驱动mlx4_load_one函数
错误处理部分(`err_port`、`err_steer`、`err_disable_msix`等标签)包括停止设备,关闭固件界面,清理命令接口,禁用SR-IOV(如果已启用),以及释放内存资源等。3. 代码中包含了多个错误处理标签(如`err_port`、`err_steer`等),它们用于在函数执行中遇到错误时,跳转到相应的代码位置进行资源清理和释放操作。此段代码主要完成当PCI设备是主设备(物理功能)时的初始化准备工作,包括对设备所有权的检查和声明,设备的重置,以及虚拟功能相关的设置。原创 2024-03-07 06:28:39 · 1072 阅读 · 3 评论 -
【C语言】linux内核dev_queue_xmit
注意的是,`__dev_queue_xmit`函数可以在中断上下文中调用,并且即使发送操作报告成功,也无法保证数据包一定会被传输出去,因为可能会因为网络拥堵或流量整形策略被丢弃。一旦调用该函数发送数据包,数据包的内存就被消费了,即使发送失败也不会尝试重传。这两个函数涉及到Linux内核网络发送路径的处理细节,包括选择设备队列、处理网络设备的发送锁、检查设备队列是否被停止、调用真正的发送函数、错误处理和资源清理等。它只需要一个参数,即要发送的数据包`skb`,因为它默认不需要处理从属设备`sb_dev`。原创 2024-03-06 10:41:41 · 502 阅读 · 1 评论 -
【C语言】glibc
在Debian系统中,通过`apt install glibc-source`命令安装的`glibc`源码通常会被放置在`/usr/src/glibc`目录下。请注意,如果是为了开发或者特定目的需要阅读或修改`glibc`的源码,通常建议直接从`glibc`的官方版本控制库(例如 Git)中克隆源码,这样可以获取最新的或是特定版本的源码,并且更容易获得社区的支持。或者访问`glibc`在源代码托管网站(如 sourceware.org)的页面,以获取其他可用的获取源码的方式或是具体的版本标签。原创 2024-03-06 00:10:33 · 634 阅读 · 1 评论 -
【C语言】linux内核netif_receive_skb
如果启用了泛型XDP,并且XDP程序对数据包的处理结果不是通过(XDP_PASS),则会直接返回并丢弃数据包(NET_RX_DROP),不再进一步处理。此函数简单地记录数据包接收事件(trace_netif_receive_skb_entry),并调用`netif_receive_skb_internal`函数来进行实际的数据包处理。netif_receive_skb_internal 是`netif_receive_skb`的内部实现,它执行实际的数据包接收处理操作。原创 2024-03-05 09:05:44 · 967 阅读 · 1 评论 -
【C语言】linux内核napi_gro_receive和netif_napi_add
这个函数的作用是将一个接收到的`skb`(数据包缓冲区)与一个`napi`结构(代表网络设备的轮询机制)相关联,并对数据包进行处理以适配GRO。4. 然后将网络包传递给`dev_gro_receive`实现GRO处理,这个函数的工作是尝试把多个类似的数据包合并为一个大的数据包,从而减少每个数据包的处理开销,提高整体性能。这段代码是Linux内核网络栈中处理接收包的函数,其主要作用是进行通用接收分段(Generic Receive Offload,简称GRO)的处理。原创 2024-03-04 05:01:25 · 639 阅读 · 3 评论 -
【C语言】linux内核packet_setsockopt
packet_setsockopt` 函数是一个针对`SOL_PACKET`套接字层级的设置选项的函数,可以添加或删除多播组成员,设置缓冲区环区域,修改某些性能参数等。packet_direct_xmit 函数是一个非常简单的函数,它接收一个 sk_buff 结构体指针 skb(代表网络数据包),调用 dev_direct_xmit 函数直接将这个数据包发送出去。2. PACKET_RX_RING 和 PACKET_TX_RING:设置接收和发送环形缓冲区,这些操作涉及到性能优化,以高效处理网络数据包。原创 2024-03-04 04:58:14 · 830 阅读 · 0 评论 -
【C语言】InfiniBand驱动mlx4_init和mlx4_cleanup
通过mlx4_interface的注册,Ethernet和InfiniBand驱动相互之间可以得知对应的设备添加(add)、移除(remove)等事件,然后执行针对InfiniBand协议所必需的操作。所以,当一个Mellanox设备作为PCI设备被系统发现时,Ethernet子系统中的mlx4_driver会通过mlx4_init_one初始化以太网功能,同时它也会与InfiniBand子系统进行通信以通过mlx4_ib_add初始化InfiniBand相关功能。注册PCI驱动mlx4_driver。原创 2024-03-03 13:32:59 · 966 阅读 · 1 评论 -
【C语言】InfiniBand 驱动mlx4_ib_init和mlx4_ib_cleanup
在 mlx4_core 的代码中,会在适当的位置调用 mlx4_ib_interface 结构体中指定的函数,以便在上述事件发生时,正确地通知 InfiniBand 协议栈进行相关操作。注册后,它成为 mlx4_core 驱动和高层驱动(本例中的 mlx4_ib)之间沟通的桥梁。- mlx4_ib_add - 当注册 mlx4_ib_interface 到 mlx4_core 后,如果 mlx4_core 驱动发现一个新的设备,mlx4_core 将调用 mlx4_ib 的 add 回调函数。原创 2024-03-03 13:25:04 · 902 阅读 · 0 评论