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

一、中文注释

这个函数是用来处理 Infiniband 设备在传输完成时的回调。该回调负责释放发送队列中的缓冲区并更新网络设备统计信息。

static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
{
    // 通过net_device结构体获取私有数据结构
    struct ipoib_dev_priv *priv = ipoib_priv(dev);

    // 获取工作请求ID,这个ID在发送时被赋予,用于标识对应的缓冲区
    unsigned int wr_id = wc->wr_id;
    struct ipoib_tx_buf *tx_req;

    // 调试信息,输出完成的工作请求的ID和状态
    ipoib_dbg_data(priv, "send completion: id %d, status: %d\n",
               wr_id, wc->status);

    // 检查wr_id是否有效
    if (unlikely(wr_id >= priv->sendq_size)) {
        // 如果不是,打印警告信息
        ipoib_warn(priv, "send completion event with wrid %d (> %d)\n",
               wr_id, priv->sendq_size);
        return;
    }
    
    // 使用工作请求ID来获取发送队列中的缓冲区
    tx_req = &priv->tx_ring[wr_id];

    // 如果不是内联传输,就需要去除DMA映射
    if (!tx_req->is_inline)
        ipoib_dma_unmap_tx(priv, tx_req);

    // 更新网络设备的发送包统计信息
    ++dev->stats.tx_packets;
    dev->stats.tx_bytes += tx_req->skb->len;

    // 释放socket缓冲区
    dev_kfree_skb_any(tx_req->skb);
    tx_req->skb = NULL;

    // 更新发送尾部指针和未完成的发送计数
    ++priv->tx_tail;
    atomic_dec(&priv->tx_outstanding);

    // 如果网络队列停止了,并且未完成的发送数少于发送队列大小的一半,同时设备标记为"管理上行"则重新唤起网络队列
    if (unlikely(netif_queue_stopped(dev) &&
             (atomic_read(&priv->tx_outstanding) <= priv->sendq_size >> 1) &&
             test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)))
        netif_wake_queue(dev);

    // 如果完成状态不是成功且不是"刷新错误",那么会对QP状态进行验证和修复
    if (wc->status != IB_WC_SUCCESS &&
        wc->status != IB_WC_WR_FLUSH_ERR) {
        // 打印错误警告信息
        ipoib_warn(priv,
               "failed send event (status=%d, wrid=%d vend_err %#x)\n",
               wc->status, wr_id, wc->vendor_err);
        // 为QP验证工作分配内存
        struct ipoib_qp_state_validate *qp_work;
        qp_work = kzalloc(sizeof(*qp_work), GFP_ATOMIC);
        // 如果内存分配失败就直接返回
        if (!qp_work)
            return;

        // 初始化工作队列项并将它放到工作队列中去
        INIT_WORK(&qp_work->work, ipoib_qp_state_validate_work);
        qp_work->priv = priv;
        queue_work(priv->wq, &qp_work->work);
    }
}

该函数的作用是处理InfiniBand网络设备在发送数据完成后的清理工作。它检查完成状态,释放资源并更新发送队列状态,若发送失败则可能会尝试修复QP(Queue Pair)状态。

二、中文讲解

这个函数 ipoib_ib_handle_tx_wc 是处理IP-over-Infiniband(IPoIB)传输完成工作请求(Work Completion,WC)的函数,主要用于处理在IPoIB网络设备上完成发送操作的情况。这个函数是Linux内核中IPoIB模块的一部分,用来处理InfiniBand协议栈发送操作的完成事件。

下面将逐条中文解释该函数的逻辑:

// 函数声明,接受一个网络设备和一个工作完成结构作为参数
static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) {
    // 从网络设备结构获取IPoIB设备私有数据
    struct ipoib_dev_priv *priv = ipoib_priv(dev);
    // 获取工作请求ID
    unsigned int wr_id = wc->wr_id;
    struct ipoib_tx_buf *tx_req;

    // 输出调试信息,包括工作请求ID和状态
    ipoib_dbg_data(priv, "send completion: id %d, status: %d\n", wr_id, wc->status);

    // 检查工作请求ID是否有效,如果不在发送队列范围内,打印警告并返回
    if (unlikely(wr_id >= priv->sendq_size)) {
        ipoib_warn(priv, "send completion event with wrid %d (> %d)\n", wr_id, priv->sendq_size);
        return;
    }

    // 获取对应工作请求ID的发送缓冲区
    tx_req = &priv->tx_ring[wr_id];

    // 如果发送请求并非内联的(数据不是和描述符一起发送的),则撤销DMA映射
    if (!tx_req->is_inline)
        ipoib_dma_unmap_tx(priv, tx_req);

    // 更新网络设备统计信息:增加发送的数据包和字节计数
    ++dev->stats.tx_packets;
    dev->stats.tx_bytes += tx_req->skb->len;

    // 释放对应的skb(socket缓冲区),并将指针置空
    dev_kfree_skb_any(tx_req->skb);
    tx_req->skb = NULL;

    // 增加发送队列尾部索引,表示处理了一个发送请求
    ++priv->tx_tail;
    // 原子减少正在处理的发送请求计数
    atomic_dec(&priv->tx_outstanding);

    // 如果网络队列停止,且未完成的发送请求数量小于发送队列大小的一半
    // 并且网络接口状态为上,那么重新启动网络队列
    if (unlikely(netif_queue_stopped(dev) &&
             (atomic_read(&priv->tx_outstanding) <= priv->sendq_size >> 1) &&
             test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)))
        netif_wake_queue(dev);

    // 如果工作完成状态非成功,并且不是因为刷新错误
    if (wc->status != IB_WC_SUCCESS && wc->status != IB_WC_WR_FLUSH_ERR) {
        struct ipoib_qp_state_validate *qp_work;
        // 打印警告,发送请求失败
        ipoib_warn(priv, "failed send event (status=%d, wrid=%d vend_err %#x)\n",
                   wc->status, wr_id, wc->vendor_err);
        // 为验证队列对状态分配工作并初始化
        qp_work = kzalloc(sizeof(*qp_work), GFP_ATOMIC);
        if (!qp_work)
            return;

        INIT_WORK(&qp_work->work, ipoib_qp_state_validate_work);
        qp_work->priv = priv;
        // 将验证工作加入到工作队列中
        queue_work(priv->wq, &qp_work->work);
    }
}

从代码可以看出,这个函数的主要作用是处理InfiniBand设备发送缓冲区完成工作事件,释放资源,更新统计数据,以及在发送操作失败时进行错误处理。 

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

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

相关文章

网络安全之内容安全

内容安全 攻击可能只是一个点&#xff0c;防御需要全方面进行 IAE引擎 DFI和DPI技术--- 深度检测技术 DPI --- 深度包检测技术--- 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对 数据包的内容进行识别。&#xff08;应用…

S32 Design Studio PE工具配置TMR

配置步骤 配置内容 生成的配置结构体如下&#xff0c;在Generated_Code路径下的lpTmr.c文件和lpTmr.h文件。 /*! lpTmr1 configuration structure */ const lptmr_config_t lpTmr1_config0 {.workMode LPTMR_WORKMODE_PULSECOUNTER,.dmaRequest false,.interruptEnable tr…

数据抽取平台pydatax介绍--实现和项目使用

数据抽取平台pydatax实现过程中&#xff0c;有2个关键点&#xff1a; 1、是否能在python3中调用执行datax任务&#xff0c;自己测试了一下可以&#xff0c;代码如下&#xff1a; 这个str1就是配置的shell文件 try:result os.popen(str1).read() except Exception as …

git忽略某些文件(夹)更改方法

概述 在项目中,常有需要忽略的文件、文件夹提交到代码仓库中,在此做个笔录。 一、在项目根目录内新建文本文件,并重命名为.gitignore,该文件语法如下 # 以#开始的行,被视为注释. # 忽略掉所有文件名是 a.txt的文件. a.txt # 忽略所有生成的 java文件, *.java # a.j…

数据结构:栈和队列与栈实现队列(C语言版)

目录 前言 1.栈 1.1 栈的概念及结构 1.2 栈的底层数据结构选择 1.2 数据结构设计代码&#xff08;栈的实现&#xff09; 1.3 接口函数实现代码 &#xff08;1&#xff09;初始化栈 &#xff08;2&#xff09;销毁栈 &#xff08;3&#xff09;压栈 &#xff08;4&…

【MQ05】异常消息处理

异常消息处理 上节课我们已经学习到了消息的持久化和确认相关的内容。但是&#xff0c;光有这些还不行&#xff0c;如果我们的消费者出现问题了&#xff0c;无法确认&#xff0c;或者直接报错产生异常了&#xff0c;这些消息要怎么处理呢&#xff1f;直接丢弃&#xff1f;这就是…

ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the ‘ssl‘报错解决

安装labelme出错了 根据爆栈的提示信息&#xff0c;我在cmd运行以下命令之后一切正常了&#xff0c;解决了问题&#xff01; pip install urllib31.26.6参考网址&#xff1a;ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1, currently the ‘ssl’ module is compile…

常见的socket函数封装和多进程和多线程实现服务器并发

常见的socket函数封装和多进程和多线程实现服务器并发 1.常见的socket函数封装2.多进程和多线程实现服务器的并发2.1多进程服务器2.2多线程服务器2.3运行效果 1.常见的socket函数封装 accept函数或者read函数是阻塞函数&#xff0c;会被信号打断&#xff0c;我们不能让它停止&a…

docker容器技术(3)

Docker技术编排 概述&#xff1a; docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题&#xff1f; 如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,…

【XR806开发板试用】socket客户端与虚拟机服务器通信交互测试以及终端交互

XR806 客户端准备工作。 1、连接wifi 2、创建socket连接服务器。 3、创建终端接收数据线程。 wifi_connect.c #include <stdio.h> #include <string.h> #include "wifi_device.h" #include "wifi_hotspot.h" #include "kernel/os/os.h…

桥接模式(Bridge Pattern) C++

上一节&#xff1a;适配器模式&#xff08;Adapter Pattern&#xff09; C 文章目录 0.理论1.组件2.使用场景 1.实践 0.理论 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它的核心思想是将抽象部分与其实现部分分离&#xff0c;使它们可…

区块链智能合约开发

一.区块链的回顾 1.区块链 区块链实质上是一个去中心化、分布式的可进行交易的数据库或账本 特征: 去中心化&#xff1a;简单来说&#xff0c;在网络上一个或多个服务器瘫痪的情况下&#xff0c;应用或服务仍然能够持续地运行&#xff0c;这就是去中心化。服务和应用部署在…

死区过滤器Deadband和DeadZone区别(应用介绍)

死区过滤器的算法和详细介绍专栏也有介绍,这里我们主要对这两个模块的区别和应用场景进行详细介绍 1、死区过滤器 https://rxxw-control.blog.csdn.net/article/details/128521007https://rxxw-control.blog.csdn.net/article/details/128521007 1、Deadband和DeadZone区别…

kafka学习笔记三

目录 第二篇 外部系统集成 第三篇 生产调优手册 第1章 kafka硬件配置选择 第2章 生产者调优 2.1 生产者核心参数配置 2.2 生产者如何提高吞吐量 2.3 数据可靠性 2.4 数据去重 2.5 数据有序 2.6 数据乱序 第3章 Kafka Broker调优 3.1 Broker核心参数配置 3.2 其他 …

k8s service的概念以及创建方法

Service 的功能&#xff1a; Service主要用于提供网络服务&#xff0c;通过Service的定义&#xff0c;能够为客户端应用提供稳定的访问地址&#xff08;域名或IP地址&#xff09;和负载均衡功能&#xff0c;以及屏蔽后端Endpoint的变化&#xff0c;是K8s实现微服务的核心资源。…

【README 小技巧】 展示gitee中开源项目start

【README 小技巧】 展示gitee中开源项目start <a target"_blank" hrefhttps://gitee.com/wujiawei1207537021/wu-framework-parent><img srchttps://gitee.com/wujiawei1207537021/wu-framework-parent/badge/star.svg altGitee star/></a>

使用ffmpeg压缩视频

一、到ffmpeg官网下载文件包&#xff1a; Download FFmpeg 下载后找到 bin 下的3个exe文件&#xff0c;复制到自己本机的某个目录下, 如&#xff1a; 二、使用命令行压缩&#xff1a; ffmpeg -i input.mp4 -c:v libx265 -crf 28 -y output.mp4 这条命令使用 FFmpeg 工具对输…

QA 的未来:使用生成式 AI 进行 API 测试

QA 团队面临着比以往任何时候都更大的满足软件质量和发布速度期望的压力。继续阅读&#xff0c;了解 GenAI 如何改善开发人员和测试人员的工作体验&#xff0c;同时最大限度地提高团队生产力并提高软件质量。 软件质量差的后果正在日益严重&#xff0c;许多组织因功能缺陷和安…

LACP——链路聚合控制协议

LACP——链路聚合控制协议 什么是LACP&#xff1f; LACP&#xff08;Link Aggregation Control Protocol&#xff0c;链路聚合控制协议&#xff09;是一种基于IEEE802.3ad标准的实现链路动态聚合与解聚合的协议&#xff0c;它是链路聚合中常用的一种协议。 链路聚合组中启用了…

2024 值得推荐的免费开源 WAF

WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。区别于传统防火墙&#xff0c;WAF 工作在应用层&#xff0c;对基于 HTTP/HTTPS 协议的 Web 系统有着更好的防护效果&#xff0c;使其免于受到黑客的攻击。 开源 WAF 和商用 WAF&#xff08;奇安信…