【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.hqwc.cn/news/417756.html

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

相关文章

51单片机驱动点阵屏

目录 1设计目的 2设计方案 2.1材料选择 2.2电源设计 2.3控制设计 3焊接调试 3.1焊接 3.2调试 4程序 1设计目的 此次设计的东西是一个点阵屏&#xff0c;通过点阵屏实现电梯屏幕功能。显示内容包括向上运行箭头和向下运行箭头&#xff0c;以及1-12的楼层。 2设计方案 …

单表查询 -- MySQL(3)

目录 题目&#xff1a; 创建表&#xff1a; 问题&#xff08;17个&#xff09;&#xff1a; 1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工资和最低工资。 5、列出职工…

数据恢复轻松搞定:如何处理.adver的数据勒索

引言&#xff1a; 勒索病毒日益猖獗&#xff0c;.adver 勒索病毒作为新兴威胁之一&#xff0c;给用户的数据安全带来了不小的挑战。本文将深入介绍.adver勒索病毒的特点、被加密数据的恢复方法&#xff0c;以及全面的预防措施&#xff0c;帮助您更好地了解并应对这一数字威胁。…

什么是内网穿透?

简介&#xff1a; 书面来说&#xff1a;内网穿透是一种网络技术&#xff0c;用于将内部私有网络中的服务暴露给公共网络&#xff0c;使得外部网络可以通过公网访问内网的服务。通常情况下&#xff0c;内网中的设备和服务由于位于私有网络中&#xff0c;无法直接通过公网IP进行…

群发邮件效果追踪:掌握数据,优化营销策略

我们在邮件群发结束后&#xff0c;如果想要了解到这次群发活动的效果怎么样&#xff0c;就需要通过一些数据。比如说邮件达到率、打开率、跳出率、退订率等。这些信息可以将收件人的行为数据化&#xff0c;让我们可以更清晰地对活动进行深入分析让我们及时地找出问题和优点&…

【原文链接】Tri-Perspective View for Vision-Based 3D Semantic Occupancy Prediction

原文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Huang_Tri-Perspective_View_for_Vision-Based_3D_Semantic_Occupancy_Prediction_CVPR_2023_paper.pdf 1. 引言 体素表达需要较大的计算量和特别的技巧&#xff08;如稀疏卷积&#xff09;&…

嵌入式学习-网络编程-Day6

嵌入式学习-网络编程-Day6 一、思维导图 二、作业 1.基于UDP的网络聊天室&#xff08;2024.1.21号前上交&#xff09; 项目需求&#xff1a; 1.如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息 2.如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信…

无刷电机行业调研:市场销售规模达到537亿元

无刷直流电机(BLDC&#xff1a;Brushless Direct Current Motor)&#xff0c;也被称为电子换向电机(ECM或EC电机)或同步直流电机&#xff0c;是一种使用直流电(DC)电源的同步电机。无刷直流电机实质上为采用直流电源输入&#xff0c;并用逆变器变为三相交流电源&#xff0c;带位…

java idea 中的 Scratches and Consoles

IDEA 中&#xff0c;"Scratches and Consoles" 是一个用于临时代码编辑和交互式开发的工具窗口&#xff0c;作用如下&#xff1a;Scratches&#xff08;草稿&#xff09;&#xff1a;Scratches 是一个用于临时编写和运行代码片段的工具&#xff0c;你可以在其中创建临…

鸿蒙开发系列教程(五)--ArkTS语言:组件开发

1、基础组件 组件API文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/84_u58f0_u660e_u5f0f_u5f00_u53d1_u8303_u5f0f_uff09-0000001427744776-V2 查看组件API 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 容…

hdu 4507 吉哥系列故事——恨7不成妻

吉哥系列故事——恨7不成妻 题意 一个正整数和 7 7 7 有关当且仅当满足以下条件之一&#xff1a; 数位中某一位是 7 7 7数位和能被 7 7 7 整除这个整数能被 7 7 7 整除 统计 [ l , r ] [l,r] [l,r] 内所有和 7 7 7 无关 的数字的 平方和 思路 这道题需要一点思维。我…

CodeWave学习笔记--采购管理系统

1.CodeWave是什么&#xff1f; CodeWave是一款智能低代码开发平台&#xff0c;基于网易自研拥有大规模参数和深度学习能力的智能模型底座产品架构&#xff0c;为企业级应用提供更加智能化研发的软件生产方式。IT人员可以轻易实现从“智能生成”到“可视化拖拽调整”的全栈低代…