【C语言】linux内核ipoib模块 - ipoib_send

一、ipoib_send函数定义

int ipoib_send(struct net_device *dev, struct sk_buff *skb,struct ib_ah *address, u32 dqpn)
{struct ipoib_dev_priv *priv = ipoib_priv(dev);struct ipoib_tx_buf *tx_req;int hlen, rc;void *phead;unsigned int usable_sge = priv->max_send_sge - !!skb_headlen(skb);if (skb_is_gso(skb)) {hlen = skb_transport_offset(skb) + tcp_hdrlen(skb);phead = skb->data;if (unlikely(!skb_pull(skb, hlen))) {ipoib_warn(priv, "linear data too small\n");++dev->stats.tx_dropped;++dev->stats.tx_errors;dev_kfree_skb_any(skb);return -1;}} else {if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);++dev->stats.tx_dropped;++dev->stats.tx_errors;ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);return -1;}phead = NULL;hlen  = 0;}if (skb_shinfo(skb)->nr_frags > usable_sge) {if (skb_linearize(skb) < 0) {ipoib_warn(priv, "skb could not be linearized\n");++dev->stats.tx_dropped;++dev->stats.tx_errors;dev_kfree_skb_any(skb);return -1;}/* Does skb_linearize return ok without reducing nr_frags? */if (skb_shinfo(skb)->nr_frags > usable_sge) {ipoib_warn(priv, "too many frags after skb linearize\n");++dev->stats.tx_dropped;++dev->stats.tx_errors;dev_kfree_skb_any(skb);return -1;}}ipoib_dbg_data(priv,"sending packet, length=%d address=%p dqpn=0x%06x\n",skb->len, address, dqpn);/** We put the skb into the tx_ring _before_ we call post_send()* because it's entirely possible that the completion handler will* run before we execute anything after the post_send().  That* means we have to make sure everything is properly recorded and* our state is consistent before we call post_send().*/tx_req = &priv->tx_ring[priv->tx_head & (priv->sendq_size - 1)];tx_req->skb = skb;if (skb->len < ipoib_inline_thold &&!skb_shinfo(skb)->nr_frags) {tx_req->is_inline = 1;priv->tx_wr.wr.send_flags |= IB_SEND_INLINE;} else {if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req))) {++dev->stats.tx_errors;dev_kfree_skb_any(skb);return -1;}tx_req->is_inline = 0;priv->tx_wr.wr.send_flags &= ~IB_SEND_INLINE;}if (skb->ip_summed == CHECKSUM_PARTIAL)priv->tx_wr.wr.send_flags |= IB_SEND_IP_CSUM;elsepriv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM;/* increase the tx_head after send success, but use it for queue state */if (atomic_read(&priv->tx_outstanding) == priv->sendq_size - 1) {ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");netif_stop_queue(dev);}skb_orphan(skb);skb_dst_drop(skb);if (netif_queue_stopped(dev))if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP |IB_CQ_REPORT_MISSED_EVENTS) < 0)ipoib_warn(priv, "request notify on send CQ failed\n");rc = post_send(priv, priv->tx_head & (priv->sendq_size - 1),address, dqpn, tx_req, phead, hlen);if (unlikely(rc)) {ipoib_warn(priv, "post_send failed, error %d\n", rc);++dev->stats.tx_errors;if (!tx_req->is_inline)ipoib_dma_unmap_tx(priv, tx_req);dev_kfree_skb_any(skb);if (netif_queue_stopped(dev))netif_wake_queue(dev);rc = 0;} else {netif_trans_update(dev);rc = priv->tx_head;++priv->tx_head;atomic_inc(&priv->tx_outstanding);}return rc;
}

二、函数解读

是的,这个函数`ipoib_send`是IPoIB驱动中的一个函数,它的责任是从上层网络协议栈接收数据并使用InfiniBand(IB)将其发送到网络中。具体的步骤包括:
1. ipoib_send接收四个参数:`net_device *dev`指向网络设备的指针;`struct sk_buff *skb`是要发送的套接字缓冲区(socket buffer);`struct ib_ah *address`是目标地址句柄(address handle),用于IB通信;`u32 dqpn`是目的QP(Queue Pair)编号。
2. 函数首先通过`ipoib_priv(dev)`获取与网络设备关联的IPoIB设备私有数据结构。
3. 然后这个函数检查传入的`skb`是否是一个GSO包(Generic Segmentation Offload),也就是大型数据包需要分段发送的情况。如果是,它计算传输头的长度,并通过`skb_pull`调整`skb`的数据指针,排除这些头部。
4. 如果`skb`的长度超过了IPoIB的最大传输单位(MTU)加上封装的长度,函数会打印一条警告信息,递增统计计数器,处理`skb`为过长,并返回。
5. 接下来的代码检查是否有足够的scatter/gather元素(分布/聚集元素)去描述`skb`的数据。如果不是,会尝试使`skb`变成一个线性的数据结构;如果线性化失败,函数会记录一个错误,释放`skb`并返回。
6. 在将`skb`发送到IB硬件之前,函数将它放入传输队列`tx_ring`。这个队列是一个环形缓冲区,用来存储即将被发送或正等待完成通知的包。
7. 函数设置`tx_req`结构体中与`skb`相关的字段,并根据条件判定数据是否可以内联发送(内联发送即数据随发送请求一起发送,而非通过DMA读取)。
8. 函数还设置是否启用IP校验和卸载功能。
9. 在发送操作之前,代码检查传输队列是否已满。如果满了,则会停止网络队列。
10. 函数 then calls post_send,该函数负责准备IB发送请求并提交到硬件进行处理。
11. 如果`post_send`返回错误,函数会记录错误,回滚上面的操作,并唤醒网络队列(如果它停止了)。
12. 如果`post_send`成功,函数修正`tx_head`,也就是传输队列头的位置,并增加处理中的传输数量`tx_outstanding`。
13. 最后,函数返回`post_send`的结果或者一个错误码。如果成功,返回的是之前增加的`tx_head`的值。
总体来说,`ipoib_send`负责处理将要发送的数据包,包括准备IB发送请求,处理数据包的线性化和分散/聚集元素,以及向IB硬件提交发送任务等。如果传输过程中遇到错误,它会统一处理错误情况,包括记录错误,释放资源,及时唤醒网络队列等。

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

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

相关文章

基于python socket实现TCP/UDP通信

两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程&#xff0c;我们知道IP层的ip地址可以唯一标示主机&#xff0c;而TCP层协议和端口号可以唯一标示主机的一个进程&#xff0c;这样我们可以利用ip地址&#xff0b;协议&#xff0b;端口号唯一标示网络中…

使用 crypto-js 进行 AES 加解密操作

在前端开发中&#xff0c;数据的加密和解密是为了保障用户隐私和数据的安全性而常见的任务。AES&#xff08;Advanced Encryption Standard&#xff09;是一种对称密钥加密算法&#xff0c;被广泛用于保护敏感信息的传输和存储。本文将介绍 AES 加解密的基本原理&#xff0c;并…

寒假思维训练计划day11

每日一题&#xff0c;这两天有事&#xff0c;断更了一天&#xff0c;今天补上&#xff0c;感觉状态也不太好&#xff0c;来道1500的题压压惊。 宣传一下我总结的几个构造题模型&#xff0c;一点个人的浅薄见解&#xff1a; 1、前后缀贪心&#xff0c;比如说观察前后缀的sum&…

RK3568平台 LT9211转接芯片调试笔记

一.简介 龙讯LT9211是一个高性能转换器&#xff0c;支持MIPI LVDS TTL两两之间转换。 使用此款芯片大部分为MIPI与LVDS进行互相转换。 下图为LT9211的典型应用图&#xff1a; 二.LT9211原理图 三.车载显示器和摄像头系统 四.调试LT9211输出 MIPI数据 &#xff08;1&#xf…

web系统设计安全性基本要求

接口设计安全 身份鉴别 独立的登录模块&#xff1a;为社会用户和平台运营管理用户提供独立的登录地址、登录界面和身份认证模块&#xff0c;通过防火墙等设备严格限制能够登录WEB应用的用户地址、身份&#xff1b; 双因素认证&#xff1a; 平台运营管理人员&#xff1a;采用用…

Civil 3D安装教程,免费使用,带安装包和工具,一分钟轻松搞的安装

前言 Civil 3D是一款面向基础设施行业的建筑信息模型&#xff08;BIM&#xff09;解决方案。它为基础设施行业的各类技术人员提供了强大的设计、分析以及文档编制功能&#xff0c;广泛适用于勘察测绘、岩土工程、交通运输、水利水电、市政给排水、城市规划和总图设计等众多领域…

MySQL(五)——多表查询

上期文章 MySQL&#xff08;四&#xff09;——约束 文章目录 上期文章多表关系一对多&#xff08;多对一&#xff09;多对多多表外键关系可视化一对一 多表查询概述笛卡尔积多表查询分类连接查询 内连接隐式内连接显式内连接 外连接左外连接右外连接 自连接联合查询 union&am…

Android Framework | AOSP源码下载及编译指南(基于Android13)

Android Framework | AOSP源码下载及编译指南(基于Android13) 引言 AOSP&#xff08;Android Open Source Project&#xff09;是Android操作系统的开源项目&#xff0c;通过下载和编译AOSP源码&#xff0c;您可以获得原始的Android系统&#xff0c;并进行定制和开发。本教程…

【C++】—— C++的IO流

在C中&#xff0c;I/O流是一项关键的编程概念&#xff0c;为程序提供了与外部世界进行交互的重要手段。通过使用C的强大I/O库&#xff0c;开发者能够实现对标准输入输出、文件、字符串等多种数据源的高效处理。接下来让我们深入探讨C的I/O流&#xff0c;了解其基本原理、常见操…

浏览器插件:WebScraper基本用法和抓取页面内容(不会编程也能爬取数据)

Web Scraper 是一个浏览器扩展&#xff0c;用于从页面中提取数据(网页爬虫)。对于简单或偶然的需求非常有用&#xff0c;例如正在写代码缺少一些示例数据&#xff0c;使用此插件可以很快从类似的网站提取内容作为模拟数据。从 Chrome 的插件市场安装后&#xff0c;页面 F12 打开…

RT-Thread experimental 代码学习(1)thread_sample

RTOS的最基础功能是线程。 线程的调度是如何工作的&#xff1f;RT-thread官方的实验文档是最好的参考。 老规矩&#xff0c;先放法国人doxygen。 thread_sample 代码的调用关系图 有意思的是&#xff0c;RT有两种创建线程的方式 - 静态和动态&#xff0c;粗略的理解是&…

微信小程序之WXML 模板语法之数据绑定、事件绑定、wx:if和列表渲染

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

数字图像处理期末速成笔记

目录 一、基础知识二、相邻像素间基本关系三、图像增强方法1、直方图求解2、直方图均衡化3、直方图规定化4、图像平滑5、邻域平均法&#xff08;线性&#xff09;6、 中值滤波法&#xff08;分线性&#xff09;7、中值滤波与领域平均的异同8、4-邻域平滑法9、超限像素平滑法10、…

我们应该了解的⽤户画像

当我们谈⽤户画像时&#xff0c;到底在谈什么 对于互联⽹公司来说&#xff0c;企业的增⻓、内容、活动、产品等⼯作基本上都是围绕着“⽤户”来做的&#xff0c;可以说都是在做“⽤户运营”这个⼯作&#xff0c;⽽⽤户画像是⽤户运营⼯作中⾮常重要的⼀环 ⽤户画像的主要特征是…

【js】js 异步机制详解 Generator / Async / Promise

三种语法功能放在一起&#xff0c;是因为他们都有相似特点&#xff1a; 维护某种状态在未来恢复状态并执行 本文重点回答以下几个问题&#xff1a; 为什么 Generator 和 Async 函数的 代码执行流 都可以简化成树形结构&#xff1f;async 函数为什么返回一个 promise&#xf…

Cloudreve存储策略-通过从机存储来拓展容量

Sham的云服务器是搬瓦工最低低低配的&#xff0c;1H 0.5G不说&#xff0c;硬盘容量也只有10g&#xff0c;说实话&#xff0c;装了宝塔面板和服务器套件后&#xff0c;基本满了&#xff0c;这时又想在云服务器上打个网盘用于下载、存储&#xff0c;这时就需要拓展硬盘&#xff0…

【podman】podman学习

Podman 官网 快速开始 面向 Docker 用户的 Podman 和 Buildah Podman是一个开源的容器、pod和容器映像管理引擎。Podman使查找、运行、构建和共享容器变得容易。 Podman Desktop是Podman的图形应用程序&#xff0c;使其易于在Windows、MacOS和Linux上安装和使用Podman&…

烟火检测AI边缘计算智能分析网关V4如何通过ssh进行服务器远程运维

智能分析网关V4是一款高性能、低功耗的AI边缘计算硬件设备&#xff0c;它采用了BM1684芯片&#xff0c;集成高性能8核ARM A53&#xff0c;主频高达2.3GHz&#xff0c;并且INT8峰值算力高达17.6Tops&#xff0c;FB32高精度算力达到2.2T&#xff0c;每个摄像头可同时配置3种算法&…

Fiddler基础使用指南

1. Fiddler介绍 Fiddler 是一款抓包工具&#xff0c;可以将网络传输发送与接受的数据包进行截获、重发、编辑、转存等操作&#xff0c;也可以用来检测网络安全 2. 设置过滤 通过设置过滤条件&#xff0c;可以使抓包工具过滤掉非目标包 3. 删除数据 被抓取的包可以进行手动删除 …

使用aspera下载SRA数据速度高达 下载中国gsa数据? ascp

转载自&#xff1a;秘籍 | 惊了&#xff0c;使用aspera下载SRA数据速度高达 291Mb/s - 简书 一、安装Aspera Connect 安装Linux版的Aspera Connect # 上面链接是最新版&#xff0c;因此下载的时候去官网复制最新的链接地址下载&#xff0c;否则可能会报错 wget https://d3gcli…