当前位置: 首页 > news >正文

Linux NAPI ------------- epoll边缘触发模式

Linux处理网络数据包的一般流程

分组到达内核的时间是不可预测的。所有现代的设备驱动程序都使用中断来通知内核有分组到达。
网络驱动程序对特定于设备的中断设置了一个处理例程,因此每当该中断被引发时(即分组到达),内核都调用该处理程序,将数据从网卡传输到物理内存,或通知内核在一定时间后进行处理。
几乎所有的网卡都支持DMA模式,能够自行将数据传输到物理内存。

支持高速网络设备

每次一个以太网帧到达时,都使用一个IRQ来通知内核。 对低速设备来说,在下一个分组到达之前,IRQ的处理通常已经结束。
由于下一个分组也通过IRQ通知,如果前一个分组的IRQ尚未处理完成,则会导致问题,高速设备通常就是这样。
现代以太网卡的运作高达10 000 Mbit/s,如果使用旧式方法来驱动此类设备,将造成所谓的“中断风暴”。

NAPI原理 (类比epoll边缘触发模式)

为解决该问题,NAPI使用了IRQ和轮询的组合
假定某个网络适配器此前没有分组到达,但从现在开始,分组将以高频率频繁到达。这就是NAPI
设备的情况,如下所述。

  1. 第一个分组将导致网络适配器发出IRQ。为防止进一步的分组导致发出更多的IRQ,驱动程序 会关闭该适配器的Rx
    IRQ。并将该适配器放置到一个轮询表上。
  2. 只要适配器上还有分组需要处理,内核就一直对轮询表上的设备进行轮询。
  3. 重新启用Rx中断。

如果在新的分组到达时,旧的分组仍然处于处理过程中,工作不会因额外的中断而减速。虽然对
设备驱动程序(和一般意义上的内核代码)来说轮询通常是一个很差的方法,但在这里该方法没有什
么不利之处:在没有分组还需要处理时,将停止轮询,设备将回复到通常的IRQ驱动的运行方式。在
没有中断支持的情况下,轮询空的接收队列将不必要地浪费时间,但NAPI并非如此。
NAPI的另一个优点是可以高效地丢弃分组。如果内核确信因为有很多其他工作需要处理,而导
致无法处理任何新的分组,那么网络适配器可以直接丢弃分组,无须复制到内核。
只有设备满足如下两个条件时,才能实现NAPI方法。
(1) 设备必须能够保留多个接收的分组,例如保存到DMA环形缓冲区中。下文将该缓冲区称为Rx
缓冲区。
(2) 该设备必须能够禁用用于分组接收的IRQ。而且,发送分组或其他可能通过IRQ进行的操作,
都仍然必须是启用的

napi机制和循环轮循

循环处理所有设备

内核以循环方式处理链表上的所有设备:内核依次轮询各个设备,如果已经花费了一定的时间来
处理某个设备,则选择下一个设备进行处理。
此外,某个设备都带有一个相对权重,表示与轮询表中其他设备相比,该设备的相对重要性。较快的设备权重较大,较慢的设备权重较小。由于权重指定了在一个轮询的循环中处理多少分组,这确保了内核将更多地注意速度较快的设备。

NAPI细节

现在我们已经弄清楚了NAPI的基本原理,接下来将讨论其实现细节。
与旧的API相比,关键性的变化在于,支持NAPI的设备必须提供一个 poll 函数。
该方法是特定于设备的,在用 netif_napi_add注册网卡时指定。调用该函数注册,表明设备可以且必须用新方法处理。

<netdevice.h>
static inline void netif_napi_add(struct net_device *dev,
struct napi_struct *napi,
int (*poll)(struct napi_struct *, int),
int weight);
  • dev 指向所述设备的 net_device 实例
  • poll 指定了在IRQ禁用时用来轮询设备的函数
  • weight指定了设备接口的相对权重。实际上可以对 weight 指定任意整数值。通常10/100 Mbit网卡的驱动程序
    指定为16,而1 000/10 000 Mbit网卡的驱动程序指定为64。无论如何,权重都不能超过该设备可以在
    Rx缓冲区中存储的分组的数目。
  • netif_napi_add 还需要另一个参数,是一个指向 struct napi_struct 实例的指针。该结构用于
    管理轮询表上的设备。其定义如下:
<netdevice.h>
struct napi_struct {
struct list_head poll_list;
unsigned long state;
int weight;
int (*poll)(struct napi_struct *, int);
};

轮询表通过一个标准的内核双链表实现, poll_list 用作链表元素。
weight 和 poll 的语义同上文所述。
state 可以是 NAPI_STATE_SCHED 或 NAPI_STATE_DISABLE ,前者表示设备将在内核的下一次循
环时被轮询,后者表示轮询已经结束且没有更多的分组等待处理,但设备尚未从轮询表移除。
请注意,struct napi_struct 经常嵌入到一个更大的结构中,后者包含了与网卡有关的、特定
于驱动程序的数据。这样在内核使用 poll 函数轮询网卡时,可用 container_of 机制获得相关信息。

实现 poll 函数

poll 函数需要两个参数:一个指向 napi_struct 实例的指针和一个指定了“预算”的整数,预算
表示内核允许驱动程序处理的分组数目。我们并不打算处理真实网卡的可能的奇异之处,因此讨论一
个伪函数,该函数用于一个需要NAPI的超高速适配器:

static int hyper_card_poll(struct napi_struct *napi, int budget)
{struct nic *nic = container_of(napi, struct nic, napi);struct net_device *netdev = nic->netdev;int work_done;work_done = hyper_do_poll(nic, budget);if (work_done < budget) {netif_rx_complete(netdev, napi);hcard_reenable_irq(nic);}return work_done;
}

在从 napi_struct 的容器获得特定于设备的信息之后,调用一个特定于硬件的方法(这里是
hyper_do_poll )来执行所需要的底层操作从网络适配器获取分组,并使用像此前那样使用
netif_receive_skb 将分组传递到网络实现中更高的层。

hyper_do_poll 最多允许处理 budget 个分组。
该函数返回实际上处理的分组的数目。必须区分以下两种情况。

  1. 如果处理分组的数目小于预算,那么没有更多的分组,Rx缓冲区为空,否则,肯定还需要处
    理剩余的分组(亦即,返回值不可能小于预算)。因此, netif_rx_complete 将该情况通知内
    核,内核将从轮询表移除该设备。接下来,驱动程序必须通过特定于硬件的适当方法来重新 启用IRQ。
  2. 已经完全用掉了预算,但仍然有更多的分组需要处理。设备仍然留在轮询表上,不启用中断。
实现IRQ处理程序

NAPI也需要对网络设备的IRQ处理程序做一些改动。这里仍然不求助于任何具体的硬件,而介绍
针对虚构设备的代码:

static irqreturn_t e100_intr(int irq, void *dev_id)
{struct net_device *netdev = dev_id;struct nic *nic = netdev_priv(netdev);if(likely(netif_rx_schedule_prep(netdev, &nic->napi))) {hcard_disable_irq(nic);__netif_rx_schedule(netdev, &nic->napi);}return IRQ_HANDLED;
}

假定特定于接口的数据保存在 net_device->private 中,这是大多数网卡驱动程序使用的方法。
使用辅助函数 netdev_priv 访问该字段。
现在需要通知内核有新的分组可用。这需要如下二阶段的方法。

  1. netif_rx_schedule_prep 准备将设备放置到轮询表上。本质上,这会安置 napi_struct-> flags
    中的 NAPI_STATE_SCHED 标志。
  2. 如果设置该标志成功(仅当NAPI已经处于活跃状态时,才会失败),驱动程序必须用特定于设 备的适当方法来禁用相应的IRQ。调用
    __netif_rx_schedule 将设备的 napi_struct 添加到轮询表, 并引发软中断 NET_RX_SOFTIRQ 。这通知内核在 net_rx_action 中开始轮询
处理Rx软中断

在讨论了为支持NAPI驱动程序需要做哪些改动之后,我们来考察一下内核需要承担的职责。
net_rx_action 依旧是软中断 NET_RX_SOFTIRQ 的处理程序。
下图给出了其代码流程图:

net_rx_action流程图
本质上,内核通过依次调用各个设备特定的 poll 方法,处理轮询表上当前的所有设备。设备的权
重用作该设备本身的预算,即轮询的一步中可能处理的分组数目。
必须确保在这个软中断的处理程序中,不会花费过多时间。如果如下两个条件成立,则放弃处理。

  1. 处理程序已经花费了超出一个 jiffie 的时间。
  2. 所处理分组的总数,已经超过了 netdev_budget 指定的预算总值。通常,总值设置为300,但 可以通过
    /proc/sys/net/core/netdev_budget 修改。

这个预算不能与各个网络设备本身的预算混淆!在每个轮询步之后,都从全局预算中减去处理的
分组数目,如果该预算值下降到0,则退出软中断处理程序。
在轮询了一个设备之后,内核会检查所处理的分组数目,与该设备的预算是否相等。如果相等,
那么尚未获得该设备上所有等待的分组,即代码流程图中 work == weight 所表示的情况。内核接下
来将该设备移动到轮询表末尾,在链表中所有其他设备都处理过之后,继续轮询该设备。显然,这实
现了网络设备之间的循环调度。

相关文章:

Linux NAPI ------------- epoll边缘触发模式

Linux处理网络数据包的一般流程 分组到达内核的时间是不可预测的。所有现代的设备驱动程序都使用中断来通知内核有分组到达。 网络驱动程序对特定于设备的中断设置了一个处理例程&#xff0c;因此每当该中断被引发时&#xff08;即分组到达&#xff09;&#xff0c;内核都调用…...

使用poi-tl填充word模板,并转化为pdf输出

后端 依赖 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.0</version> </dependency>Word版本 Word版本填充代码 // 培训详情HashMap<String, Object> textMap new Ha…...

计算机视觉-机器学习-人工智能 顶会会议召开地址

计算机视觉-机器学习-人工智能 顶会会议召开地址 最近应该要整理中文资料的参考文献&#xff0c;很多会议文献都需要补全会议地点&#xff08;新国标要求&#xff09;。四处百度感觉也挺麻烦的&#xff0c;而且没有比较齐全的网站可以搜索。因此自己整理了一下计算机视觉-机器…...

GAN的原理分析与实例

为了便于理解&#xff0c;可以先玩一玩这个网站&#xff1a;GAN Lab: Play with Generative Adversarial Networks in Your Browser! GAN的本质&#xff1a;枯叶蝶和鸟。生成器的目标&#xff1a;让枯叶蝶进化&#xff0c;变得像枯叶&#xff0c;不被鸟准确识别。判别器的目标&…...

什么是POM设计模式?

为什么要用POM设计模式 前期&#xff0c;我们学会了使用PythonSelenium编写Web UI自动化测试线性脚本 线性脚本&#xff08;以快递100网站登录举栗&#xff09;&#xff1a; import timefrom selenium import webdriver from selenium.webdriver.common.by import Bydriver …...

没有数据线,在手机上查看电脑备忘录怎么操作

在工作中&#xff0c;电脑和手机是我最常用的工具。我经常需要在电脑上记录一些重要的工作事项&#xff0c;然后又需要在手机上查看这些记录&#xff0c;以便随时了解工作进展。但是&#xff0c;每次都需要通过数据线来传输数据&#xff0c;实在是太麻烦了。 有一次&#xff0…...

Elasitcsearch--解决CPU使用率升高

原文网址&#xff1a;Elasitcsearch--解决CPU使用率升高_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决ES导致的CPU使用率升高的问题。 问题描述 线上环境 Elasticsearch CPU 使用率飙升常见问题如下&#xff1a; Elasticsearch 使用线程池来管理并发操作的 CPU 资源。…...

vue和jQuery有什么区别

Vue 和 jQuery 是两种不同类型的前端工具&#xff0c;它们有一些显著的区别&#xff1a; Vue 响应式数据绑定&#xff1a;Vue 提供了双向数据绑定和响应式更新的能力&#xff0c;使得数据与视图之间的关系更加直观和易于维护。组件化开发&#xff1a;Vue 鼓励使用组件化的方式…...

[Android] Binder all-in-all

前言&#xff1a; Binder 是一种 IPC 机制&#xff0c;使用共享内存实现进程间通讯&#xff0c;既可以传递消息&#xff0c;也可以传递创建在共享内存中的对象&#xff0c;而Binder本身就是用共享内存实现的&#xff0c;因此遵循Binder写法的类是可以实例化后在进程间传递的。…...

无人零售柜:快捷舒适购物体验

无人零售柜&#xff1a;快捷舒适购物体验 通过无人零售柜和人工智能技术&#xff0c;消费者在购物过程中可以自由选择商品&#xff0c;根据个人需求和喜好查询商品清单。这种自主选择的购物环境能够为消费者提供更加舒适和满意的体验。此外&#xff0c;无人零售柜还具有节约时间…...

Bash script进阶笔记

数组类型 arr(1 2 3) # 最基础的方式声明数组&#xff0c;用小括号()&#xff0c;元素之间逗号分隔 arr([1]10 [2]20 [3]30) # 初始化时指定index declare -a arr(1 2 3) # 用declare -a声明数组&#xff0c;小括号外面可选使用单引号、双引号 declare -a arr‘(1 2 3)’…...

OpenCV图像处理——Python开发中OpenCV视频流的多线程处理方式

前言 在做视觉类项目中&#xff0c;常常需要在Python环境下使用OpenCV读取本地的还是网络摄像头的视频流&#xff0c;之后再调入各种模型&#xff0c;如目标分类、目标检测&#xff0c;人脸识别等等。如果使用单线程处理&#xff0c;很多时候会出现比较严重的时延&#xff0c;…...

webGL开发智慧城市流程

开发智慧城市的WebGL应用程序涉及多个方面&#xff0c;包括城市模型、实时数据集成、用户界面设计等。以下是一个一般性的流程&#xff0c;您可以根据项目的具体需求进行调整&#xff0c;希望对大家有所帮助。 1.需求分析&#xff1a; 确定智慧城市应用程序的具体需求和功能。考…...

Django讲课笔记02:Django环境搭建

文章目录 一、学习目标二、相关概念&#xff08;一&#xff09;Python&#xff08;二&#xff09;Django 三、环境搭建&#xff08;一&#xff09;安装Python1. 从官方网站下载最新版本的Python2. 运行安装程序并按照安装向导进行操作3. 勾选添加到路径复选框4. 完成安装过程5.…...

黑豹程序员-原生JS拖动div到任何地方-自定义布局

效果图 代码html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /…...

<软考高项备考>《论文专题 - 7 论文的项目背景之技术架构》

1 技术架构概况 ➢ 架构前端:HTML ➢ 后端:Java ➢ 数据库: Oracle ➢ 大数据:MapReduce ➢ 人工智能:Python ➢ 物联网:RFID识别&#xff0c;http传输&#xff0c;Java ➢ 开发APP: IOS、Android 2 常用开发语言 序号语言说明1JavaJava是一种跨平台的编程语言&#xff0c;广…...

6.3 C++11 原子操作与原子类型

一、原子类型 1.多线程下的问题 在C中&#xff0c;一个全局数据在多个线程中被同时使用时&#xff0c;如果不加任何处理&#xff0c;则会出现数据同步的问题。 #include <iostream> #include <thread> #include <chrono> long val 0;void test() {for (i…...

智能优化算法应用:基于狮群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于狮群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于狮群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.狮群算法4.实验参数设定5.算法结果6.参考文献7.MA…...

BERT、GPT学习问题个人记录

目录 1. 为什么过去几年大家都在做BERT, 做GPT的人少。 2. 但最近做GPT的多了以及为什么GPT架构的scaling&#xff08;扩展性&#xff09;比BERT好。 3.BERT是否可以用来做生成&#xff0c;如果可以的话为什么大家都用GPT不用BERT. 4. BERT里的NSP后面被认为是没用的&#x…...

HeartBeat监控Mysql状态

目录 一、概述 二、 安装部署 三、配置 四、启动服务 五、查看数据 一、概述 使用heartbeat可以实现在kibana界面对 Mysql 服务存活状态进行观察&#xff0c;如有必要&#xff0c;也可在服务宕机后立即向相关人员发送邮件通知 二、 安装部署 参照章节&#xff1a;监控组件…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...