【C语言】ipoib驱动 - ipoib_cm_post_receive_nonsrq_rss函数

这篇具有很好参考价值的文章主要介绍了【C语言】ipoib驱动 - ipoib_cm_post_receive_nonsrq_rss函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、ipoib_cm_post_receive_nonsrq_rss函数定义

static int ipoib_cm_post_receive_nonsrq_rss(struct net_device *dev,
					    struct ipoib_cm_rx *rx, int id)
{
	struct ipoib_dev_priv *priv = ipoib_priv(dev);
	struct ipoib_recv_ring *recv_ring = priv->recv_ring + rx->index;
	struct ib_sge *sge;
	struct ib_recv_wr *wr;
	int i, ret;

	sge = recv_ring->cm.rx_sge;
	wr = &recv_ring->cm.rx_wr;

	wr->wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV;

	for (i = 0; i < IPOIB_CM_RX_SG; ++i)
		sge[i].addr = rx->rx_ring[id].mapping[i];

	ret = ib_post_recv(rx->qp, wr, NULL);
	if (unlikely(ret)) {
		ipoib_warn(priv, "post recv failed for buf %d (%d)\n", id, ret);
		ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1,
				      rx->rx_ring[id].mapping);
		dev_kfree_skb_any(rx->rx_ring[id].skb);
		rx->rx_ring[id].skb = NULL;
	}

	return ret;
}

二、解读

解读1

这段代码是Linux内核中的一个函数,用于在使用RDMA(远程直接内存访问)协议的InfiniBand网卡上进行接收数据。具体来说,这段代码用于在RDMA接收队列(rx->qp)上提交一个接收工作请求(wr),以便接收数据。

首先,函数从net_device结构体中获取与RDMA相关的私有数据结构ipoib_dev_priv。然后,它根据接收队列的索引(rx->index)获取接收环的指针(recv_ring),接收环包含了一些用于接收数据的缓冲区描述符。

接下来,函数从接收环中获取RDMA接收工作请求的描述符(wr)和缓冲区的描述符(sge)。wr->wr_id是一个用于标识接收工作请求的唯一值,通过将id与IPOIB_OP_CM和IPOIB_OP_RECV相或运算得到。

然后,函数使用rx->rx_ring[id].mapping数组中的缓冲区地址来初始化sge数组中的每个元素。这些缓冲区是之前分配给接收队列的。

最后,函数调用ib_post_recv函数将接收工作请求提交到接收队列上。如果返回值不为0,则表示提交失败,函数会释放相关资源(解映射DMA内存和释放缓冲区)。

总之,这段代码是一个在RDMA接收队列上提交接收工作请求的函数,用于接收来自RDMA协议的数据。

解读2

这段代码是Linux内核中的一个模块驱动函数,用于处理IP over InfiniBand (IPoIB) 的非Shared Receive Queue (SRQ) 情况下的Connected Mode (CM) 接收路径。函数`ipoib_cm_post_receive_nonsrq_rss`与之前讨论的`ipoib_cm_post_receive_srq_rss` 类似,但是针对的是非SRQ,也即每个Queue Pair (QP) 有自己独立的接收队列。这辟出来的通道允许接收侧的扩展(RSS),用来在多个CPU之间分配网络处理任务。下面来详细解析这段代码:
1. 函数接收三个参数:
   - *dev:指向 net_device 结构的指针,它与InfiniBand 网络【C语言】ipoib驱动 - ipoib_cm_post_receive_nonsrq_rss函数,编程,# C语言,linux内核,c语言设备相关联。
   - *rx:指向一个 ipoib_cm_rx 结构的指针,该结构包含了与特定CM接收队列相关的信息。
   - id:一个用于追踪特定接收缓冲区的标识符。
2. 通过 ipoib_priv(dev) 获取到一个指向IPoIB 私有结构(`ipoib_dev_priv`)的指针。
3. 计算对应接收环(`ipoib_recv_ring`)的地址,它是通过在IPoIB私有结构中的`recv_ring`加上`rx`提供的索引(`index`)得到的。
4. 设置局部指针变量指向Scatter-Gather元素(`ib_sge`)和接收工作请求(`ib_recv_wr`),这两者都从`recv_ring` 结构中获得。
5. 设置接收工作请求(Receive Work Request)的`wr_id`字段,将提供的 id 加上 IPOIB_OP_CM 和 IPOIB_OP_RECV 标志,表明这个操作与Connected Mode的接收动作有关。
6. 一个通过 IPOIB_CM_RX_SG 控制的循环用来设置 ib_sge 数组的地址(`addr`)。这些地址指向的是内存映射,硬件会使用它们在接收到包的时候放入其中。
7. 通过 ib_post_recv() 将接收工作请求提交到对应的Queue Pair (QP)。这个函数通常需要QP,指向工作请求的指针,以及用于存放下一个工作请求指针的指针(在这里是空指针NULL,因为不需要)。
8. 如果调用 ib_post_recv() 失败(返回非零值),通过 ipoib_warn() 记录错误信息。然后调用 ipoib_cm_dma_unmap_rx() 进行DMA解映射处理,并通过调用 dev_kfree_skb_any() 释放关联的套接字缓冲区,并将 skb 字段设置为 NULL。
9. 最后,这个函数返回来自 ib_post_recv() 的状态代码(`ret`),它指示成功(0)或错误码。
这个代码片段依然是源自于一个比较底层的Linux内核驱动程序,涉及到内核开发、InfiniBand架构、设备驱动程序和直接内存访问(DMA)。因此,它处理的网络设备操作和内存管理是由InfiniBand规范和驱动程序的架构决定的

解读3

这段代码是一个Linux内核模块驱动的一部分,特定于InfiniBand(IB)通信中的非SRQ(Subscription/Notification Queue)接收操作。下面是对代码的中文解释:

  1. 函数定义:

    • static int ipoib_cm_post_receive_nonsrq_rss(struct net_device *dev, struct ipoib_cm_rx *rx, int id):这是一个静态函数,返回类型为int。它接收三个参数:一个网络设备结构体指针dev,一个指向ipoib_cm_rx结构体的指针rx,和一个整数id
  2. 局部变量:

    • struct ipoib_dev_priv *priv = ipoib_priv(dev);:从网络设备结构体中获取私有数据结构体指针。
    • struct ipoib_recv_ring *recv_ring = priv->recv_ring + rx->index;:根据给定的索引从私有数据结构体的接收环中获取接收环结构体指针。
    • struct ib_sge *sge;:定义一个指向InfiniBand SGE(Scatter Gather Element)的指针。
    • struct ib_recv_wr *wr;:定义一个指向InfiniBand接收写请求的指针。
    • int i, ret;:定义整数变量i和ret。
  3. 设置写请求:

    • sge = recv_ring->cm.rx_sge;:将SGE指针设置为接收环中的SGE。
    • wr = &recv_ring->cm.rx_wr;:将写请求指针设置为接收环中的写请求。
    • wr->wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV;:设置写请求的ID,由id、IPOIB_OP_CM和IPOIB_OP_RECV按位或运算得到。
  4. 设置SGE:

    • 循环遍历私有数据结构体的碎片数量,并设置每个SGE的地址。
  5. 发送接收请求:

    • ret = ib_post_recv(rx->qp, wr, NULL);:使用InfiniBand API发送接收请求。如果返回值不为0,则进入错误处理部分。
  6. 错误处理:

    • 如果返回值ret不为0,则打印警告信息,取消DMA映射,并释放相关缓冲区。最后返回ret。
  7. 返回值:

    • 函数返回ret,即接收请求的返回值。如果成功,则返回0;否则返回非0值。

总体来说,这个函数的主要目的是通过InfiniBand接口发送非SRQ接收请求,并处理可能发生的错误情况。文章来源地址https://www.toymoban.com/news/detail-808580.html

到了这里,关于【C语言】ipoib驱动 - ipoib_cm_post_receive_nonsrq_rss函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言通过IXMLHTTPRequest以get或post方式发送http请求获取服务器文本或xml数据

    做过网页设计的人应该都知道ajax。 Ajax即Asynchronous Javascript And XML(异步的JavaScript和XML)。使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 在IE浏览器中,Ajax技术就是

    2024年01月25日
    浏览(62)
  • 由浅入深C系列五:使用libcurl进行基于http get/post模式的C语言交互应用开发

    大多数在linux下的开发者,都会用到curl这个命令行工具。对于进行restful api的测试等,非常方便。其实,这个工具还提供了一个C的开发库,可以很方便的在C语言开发环境下完成基于http的请求和响应交互,高效的开发基于http/smtp等的网络应用程序 下载并安装curl的开发包 开发

    2024年02月13日
    浏览(47)
  • CM3学习-中断

    红叶何时落水 编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断。具体类型P108 这里的编号指的是中断源,而不是优先级,优先级是可以重定义的 在 NVIC 的中断控制及状态寄存器中,有一个 VECTACTIVE 位段;另外,还有一个特殊功能寄 存器 IPSR。在它们二者的里面,

    2024年02月07日
    浏览(28)
  • day2 驱动开发 c语言

    通过驱动开发给pcb板子点灯。 u-boot已经提前移植到了emmc中。 灯也是一种字符型设备。 编程流程需要先注册设备,然后创建结点,然后操作电灯相关寄存器 应用层直接调用read write来打开字符设备进行操作。 这样写会造成无法处理内核页面请求的虚拟地址内部错误,没找到解

    2024年02月15日
    浏览(36)
  • C语言调用libusb访问USB驱动

    目录 一、环境搭建 1. 下载库文件 2. 解压 3. 配置VS工程 3.1 头文件的配置 3.2 静态库文件的处理 3.3 配置运行时库 二、生成自定义设备的驱动 1. 禁用Windows驱动程序强制签名 2. 设备描述符的设计 3. 设备枚举 4. 如何为自己的设备安装WinUSB驱动 三、测试 1. 测试代码 2. 小结 开发环

    2024年02月07日
    浏览(27)
  • PLA: 语言驱动的开放词汇3D场景理解

    论文:https://arxiv.org/abs/2211.16312 GitHub - CVMI-Lab/PLA: (CVPR 2023) PLA: Language-Driven Open-Vocabulary 3D Scene Understanding代码:GitHub - CVMI-Lab/PLA: (CVPR 2023) PLA: Language-Driven Open-Vocabulary 3D Scene Understanding 开放词汇场景理解旨在定位和识别标注标签空间之外的未见类别。 最近二维开放词汇感知的突

    2024年02月12日
    浏览(48)
  • day3 驱动开发 c语言编程

    通过ioctl(内核+应用层) 控制led灯三盏,风扇,蜂鸣器,小马达 头文件head.h 内核代码 ioctldev.c 应用层代码 ioctl.c

    2024年02月16日
    浏览(56)
  • day4 驱动开发 c语言学习

    不利用系统提供的register_chrdev,自己实现字符设备的注册 底层代码 led.c 应用层代码 app.c 头文件 head.h

    2024年02月14日
    浏览(39)
  • 猿创征文|[CM311-1A Armbian]-烧录制作 Armbian 系统盘以及写入 CM311-1A 机顶盒的 EMMC 刷成服务器

    ################################################## 目录 寻找盒子系统镜像 关于镜像网站 盒子简介 卖家镜像站 s9x 芯片镜像 Ubuntu Armbian jammy Debian Armbian bullseye 默认 arm 系统账户和密码 我所使用的 Armbian Server 镜像资源 使用烧录工具烧录 Armbian 系统盘 获取 balenaEtcher U 盘系统烧录工具 安

    2024年02月04日
    浏览(217)
  • BSP-D2000平台调试CM9434串口芯片

    原理图显示两块9434的INT分别接到D2000的GPIO0_A3和GPIO0_A5. 设备树配置:   驱动GPIO操作 不用设备树配置,驱动代码中对固定GPIO操作 #define GPIO8_A6 254 ret = gpio_request(GPIO8_A6 , \\\"gpio8_a6\\\"); if (!ret) {          printk(\\\"request for gpio8_a6 failed:%dn\\\", ret);              return 0; } gpio_direct

    2024年01月16日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包