RDMA内核态函数ib_post_send()源码分析

最近调用linux内核下RDMA的Verb API ib_post_send()出现了问题,因此从源码分析一下这个函数的调用过程。
我使用的内核版本为5.15.0-94
这是函数ib_post_send的头文件定义,这个函数的意义是向发送队列提交发送请求,他会调用qp对应设备的post_send操作
在这里插入图片描述
post_send是一个函数指针
在这里插入图片描述
post_send函数的具体实现在infiniband驱动程序里,这是驱动程序的路径
在这里插入图片描述
mlx5驱动作为内核模块载入内核:
在这里插入图片描述
模块载入过程中会进行相关变量、函数的绑定和初始化。其中post_send函数指针对应的函数为mlx5_ib_post_send_nodrain
在这里插入图片描述

而这个函数会调用mlx5_ib_post_send函数。
在这里插入图片描述
下面这个函数就是最后调用的函数。
在这里插入图片描述
这个函数的完整代码如下:

int mlx5_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
		      const struct ib_send_wr **bad_wr, bool drain)
{
	struct mlx5_wqe_ctrl_seg *ctrl = NULL;  /* compiler warning */
	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
	struct mlx5_core_dev *mdev = dev->mdev;
	struct mlx5_ib_qp *qp = to_mqp(ibqp);
	struct mlx5_wqe_xrc_seg *xrc;
	struct mlx5_bf *bf;
	void *cur_edge;
	int size;
	unsigned long flags;
	unsigned int idx;
	int err = 0;
	int num_sge;
	void *seg;
	int nreq;
	int i;
	u8 next_fence = 0;
	u8 fence;

	if (unlikely(mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR &&
		     !drain)) {
		*bad_wr = wr;
		return -EIO;
	}

	if (qp->type == IB_QPT_GSI)
		return mlx5_ib_gsi_post_send(ibqp, wr, bad_wr);

	bf = &qp->bf;

	spin_lock_irqsave(&qp->sq.lock, flags);

	for (nreq = 0; wr; nreq++, wr = wr->next) {
		if (unlikely(wr->opcode >= ARRAY_SIZE(mlx5_ib_opcode))) {
			mlx5_ib_warn(dev, "\n");
			err = -EINVAL;
			*bad_wr = wr;
			goto out;
		}

		num_sge = wr->num_sge;
		if (unlikely(num_sge > qp->sq.max_gs)) {
			mlx5_ib_warn(dev, "\n");
			err = -EINVAL;
			*bad_wr = wr;
			goto out;
		}

		err = begin_wqe(qp, &seg, &ctrl, wr, &idx, &size, &cur_edge,
				nreq);
		if (err) {
			mlx5_ib_warn(dev, "\n");
			err = -ENOMEM;
			*bad_wr = wr;
			goto out;
		}

		if (wr->opcode == IB_WR_REG_MR ||
		    wr->opcode == IB_WR_REG_MR_INTEGRITY) {
			fence = dev->umr_fence;
			next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
		} else  {
			if (wr->send_flags & IB_SEND_FENCE) {
				if (qp->next_fence)
					fence = MLX5_FENCE_MODE_SMALL_AND_FENCE;
				else
					fence = MLX5_FENCE_MODE_FENCE;
			} else {
				fence = qp->next_fence;
			}
		}

		switch (qp->type) {
		case IB_QPT_XRC_INI:
			xrc = seg;
			seg += sizeof(*xrc);
			size += sizeof(*xrc) / 16;
			fallthrough;
		case IB_QPT_RC:
			err = handle_qpt_rc(dev, qp, wr, &ctrl, &seg, &size,
					    &cur_edge, &idx, nreq, fence,
					    next_fence, &num_sge);
			if (unlikely(err)) {
				*bad_wr = wr;
				goto out;
			} else if (wr->opcode == IB_WR_REG_MR_INTEGRITY) {
				goto skip_psv;
			}
			break;

		case IB_QPT_UC:
			handle_qpt_uc(wr, &seg, &size);
			break;
		case IB_QPT_SMI:
			if (unlikely(!dev->port_caps[qp->port - 1].has_smi)) {
				mlx5_ib_warn(dev, "Send SMP MADs is not allowed\n");
				err = -EPERM;
				*bad_wr = wr;
				goto out;
			}
			fallthrough;
		case MLX5_IB_QPT_HW_GSI:
			handle_qpt_hw_gsi(qp, wr, &seg, &size, &cur_edge);
			break;
		case IB_QPT_UD:
			handle_qpt_ud(qp, wr, &seg, &size, &cur_edge);
			break;
		case MLX5_IB_QPT_REG_UMR:
			err = handle_qpt_reg_umr(dev, qp, wr, &ctrl, &seg,
						       &size, &cur_edge, idx);
			if (unlikely(err))
				goto out;
			break;

		default:
			break;
		}

		if (wr->send_flags & IB_SEND_INLINE && num_sge) {
			err = set_data_inl_seg(qp, wr, &seg, &size, &cur_edge);
			if (unlikely(err)) {
				mlx5_ib_warn(dev, "\n");
				*bad_wr = wr;
				goto out;
			}
		} else {
			for (i = 0; i < num_sge; i++) {
				handle_post_send_edge(&qp->sq, &seg, size,
						      &cur_edge);
				if (unlikely(!wr->sg_list[i].length))
					continue;

				set_data_ptr_seg(
					(struct mlx5_wqe_data_seg *)seg,
					wr->sg_list + i);
				size += sizeof(struct mlx5_wqe_data_seg) / 16;
				seg += sizeof(struct mlx5_wqe_data_seg);
			}
		}

		qp->next_fence = next_fence;
		finish_wqe(qp, ctrl, seg, size, cur_edge, idx, wr->wr_id, nreq,
			   fence, mlx5_ib_opcode[wr->opcode]);
skip_psv:
		if (0)
			dump_wqe(qp, idx, size);
	}

out:
	if (likely(nreq)) {
		qp->sq.head += nreq;

		/* Make sure that descriptors are written before
		 * updating doorbell record and ringing the doorbell
		 */
		wmb();

		qp->db.db[MLX5_SND_DBR] = cpu_to_be32(qp->sq.cur_post);

		/* Make sure doorbell record is visible to the HCA before
		 * we hit doorbell.
		 */
		wmb();

		mlx5_write64((__be32 *)ctrl, bf->bfreg->map + bf->offset);
		/* Make sure doorbells don't leak out of SQ spinlock
		 * and reach the HCA out of order.
		 */
		bf->offset ^= bf->buf_size;
	}

	spin_unlock_irqrestore(&qp->sq.lock, flags);

	return err;
}

此函数介绍如下:
1.函数参数:这个函数接收四个参数,分别是一个指向ib_qp结构的指针(代表一个InfiniBand队列对),一个指向ib_send_wr结构的指针(代表一个发送工作请求),一个指向ib_send_wr指针的指针(用于返回出错的工作请求),以及一个布尔值(表示是否为"drain"操作)。

2.函数首先进行错误检查,例如检查设备状态,检查工作请求的操作码,以及检查工作请求的SGE(Scatter/Gather Entry)数量。

3.函数的主要部分是一个循环,对每个工作请求进行处理。处理包括开始一个WQE(Work Queue Entry),设置控制段,处理不同类型的QP(例如RC、UC、UD等),设置数据段,以及完成WQE。
4.在处理完所有的工作请求后,函数会更新doorbell record,并通过写入doorbell来通知硬件开始处理WQE。

综上所述,当在内核中调用ib_post_send函数时,会触发infiniBand模块的回调函数mlx5_ib_post_send_nodrain,最后会调用到函数

int mlx5_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
		      const struct ib_send_wr **bad_wr, bool drain)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pyglet综合应用|推箱子游戏地图编辑器之图片跟随鼠标

目录 推箱子游戏 升级一&#xff1a;鼠标操作 升级二&#xff1a;增加网格 升级三&#xff1a;模拟按钮 综合应用&#xff1a;地图编辑器 关卡地图洗数 推箱子游戏 本篇为之前写的博客《Pyglet综合应用&#xff5c;推箱子游戏之关卡图片载入内存》的续篇&#xff0c;内容…

项目:shell实现多级菜单脚本编写

目录 1. 提示 2. 演示效果 2.1. 一级菜单 2.2. 二级菜单 2.3. 执行操作 3. 参考代码 1. 提示 本脚本主要实现多级菜单效果&#xff0c;并没有安装LAMP、LNMP环境&#xff0c;如果要用在实际生成环境中部署LNMP、LAMP环境&#xff0c;只需要简单修改一下就可以了。 2. 演…

ASCII编码的影响与作用:数字化时代的不可或缺之物

title: ASCII编码的影响与作用&#xff1a;数字化时代的不可或缺之物 date: 2024/2/25 16:03:37 updated: 2024/2/25 16:03:37 tags: ASCII起源标准化字符文本处理基础编程语言基石数据库存储标准跨平台兼容多语言编码基础 一、ASCII编码的起源 ASCII&#xff08;American St…

matlab 三质量-弹簧系统受激振力

1、内容简介 略 44-可以交流、咨询、答疑 建立系统运动方程&#xff0c;研究固有频率和对应主振型 2、内容说明 略 三质量&#xff0d;弹簧系统受激振力&#xff0c;并不考虑各自的阻尼。建立系统运动方程。 解&#xff1a;由于阻尼对固有频率没有影响&#xff0c;故本文不…

浅谈数据分析工具在智慧城市中的作用

随着城市化、技术进步和人口不断增长&#xff0c;智慧城市已成为当今世界主要技术发展之一。 智慧城市设备依靠描述模型对城市环境产生的大量数据进行数据分析。 在这种城市景观中&#xff0c;智慧城市是技术和可持续的城市地区&#xff0c;利用信息和通信技术(ICT)来改善城市…

异步http和同步http原理和差异

开发服务器端程序时&#xff0c;一种常见的需求是&#xff0c;通过向另一个http服务器发送请求&#xff0c;获得数据。最常规的作法是使用同步http请求的方式&#xff0c;过程如下 这种方式简单好用&#xff0c;但是在高并发场景下有缺陷。在单线程环境下&#xff0c;程序发送h…

linux调用so库之一

任务&#xff1a;linux系统&#xff0c;已经生成so库&#xff0c;需要调用。 参考文献&#xff1a; Linux 调用动态库&#xff08;.SO文件&#xff09;总结_linux deviceio.so-CSDN博客 可以看他的第一部分&#xff0c;即显式调用。但是会报错&#xff0c;我的版本是64位的U…

【SpringBoot】Spring常用注解总结

目录 ⭐spring springmvc和springboot的区别 Autowired 和Resource的区别和联系 1. SpringBootApplication 2. Spring Bean 相关 2.1. Autowired 2.2. Component,Repository,Service, Controller 2.3. RestController 2.4. Scope 2.5. Configuration 3. 处理常见的 HT…

vue3(vite)+electron打包踩坑记录(1)

vue3(vite)electron打包踩坑记录 - 打包vue 第一步 编译vue 使用vite构建vue&#xff0c;package.json如下 {"name": "central-manager","private": true,"version": "0.0.0","type": "commonjs",&q…

Autosar 开篇

背景 AUTOSAR&#xff08;Automotive Open System Architecture&#xff09;是一个跨汽车行业的标准化软件架构&#xff0c;旨在促进汽车电子系统的开发和部署。下面是AUTOSAR发展的一些关键点&#xff1a; 起源和背景&#xff1a; AUTOSAR最初于2003年由汽车制造商宝马、戴姆…

x(x-1)的含义

一.二进制中x&(x-1)的含义 把x的二进制最后一个1变为0 找一下规律&#xff1a; 二.应用 我们可以利用这个特性&#xff0c;来数这个数字中有多少数字1 算法分析&#xff1a;放入一个计数器&#xff0c;每循环一次&#xff0c;就把这个数字的最后一个1变为0&#xff0c;计数…

【JavaEE】 spring boot的配置文件详解

spring boot的配置文件详解 文章目录 spring boot的配置文件详解常用配置spring boot的配置文件1. properties 文件2. YAML 文件3. 多环境配置4. 配置文件优先级5. 配置属性注入特殊说明 properties配置文件基本语法 例子peoperties文件的缺点 YML配置文件YML使用yml 配置不同数…

阿里云-系统盘-磁盘扩容

阿里云系统磁盘扩容 之前是测试环境磁盘用的默认的有 40G&#xff0c;后面升级到正式的 磁盘怕不够用打算升级到 100G&#xff0c; 系统镜像&#xff1a; Alibaba Cloud Linux 3.2104 LTS 64 位 磁盘 ESSD 40G 升级步骤&#xff1a; 扩容与创建快照 在阿里云后台首先去扩容…

【Docker】三、日志控制

三、日志控制 使用Docker部署服务器&#xff0c;要对Docker日志定时处理。否则&#xff0c;服务器运行一段时间后&#xff0c;磁盘占比报警。 出现磁盘占比报警&#xff0c;大概率是大文件的问题&#xff0c;可查看服务器中的大文件&#xff0c;排除问题。 &#xff08;一&am…

apache 模式、优化、功能 与 nginx优化、应用

一、I/O模型——Input/Output模型 1.同步/异步 A程序需要调用B程序的某一个功能&#xff0c;A发送一个请求需要B完成一个任务 同步&#xff1a;B不会主动去通知A是否完成需要A自己去问 异步&#xff1a;B会主动通知A是否完成 2.阻塞/非阻塞 A发送一个请求需要B完成一个任务 …

Python文件和异常(二)

目录 三、异常 &#xff08;一&#xff09;处理 ZeroDivisionError 异常 &#xff08;二&#xff09;使用 try-except 代码块 &#xff08;三&#xff09;使用异常避免崩溃 &#xff08;四&#xff09;else 代码块 &#xff08;五&#xff09;处理 FileNotFoundError 异常…

单片机05__串口USART通信__按键控制向上位机传输字符串

串口USART通信 通用UART介绍 1.通信的概念 计算机与外界进行信息交换的过程称之为通信。 在通信的过程中&#xff0c;通信双方都需要遵守的规则称之为通信协议。 硬件协议&#xff1a;将数据以什么样的方式传输过去 软件协议&#xff1a;将数据以什么样的顺序传输过去 2.常用…

042 继承

代码实现 首先定义Person类&#xff08;人类&#xff09; /*** 人的基础特征** author Admin*/ public class Person {/*** 姓名*/String name;/*** 生日*/Date birthday;/*** 手机号码*/String tel;/*** 身份证号码*/String idCode;public Person() {}public Person(String …

BlackberryQ10 是可以安装 Android 4.3 应用的,Web UserAgent 版本信息

BlackberryQ10 是可以安装 Android 4.3 应用的 最近淘了个 Q10 手机&#xff0c;非常稀罕它&#xff0c;拿着手感一流。这么好的东西&#xff0c;就想给它装点东西&#xff0c;但目前所有的应用都已经抛弃这个安卓版本了。 一、开发环境介绍 BlackBerry Q10 的 安卓版本是 4.…

Spring Boot对接RocketMQ示例

部署服务 参考RocketMq入门介绍 示例 引入maven依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.2</version></dependency>完整依赖如下&am…