来看下NAPI和非NAPI的区别:

(1) 支持NAPI的网卡驱动必须提供轮询方法poll()。

(2) 非NAPI的内核接口为netif_rx(),NAPI的内核接口为napi_schedule(),或者类似的__napi_schedule之类的,总之都是在硬中断中调用对应的函数。

(3) 非NAPI使用共享的CPU队列softnet_data->input_pkt_queue,NAPI使用设备内存(或者

设备驱动程序的接收环)。

crash> struct softnet_data--------------会创建一个percpu变量
struct softnet_data {
struct Qdisc *output_queue;
struct Qdisc **output_queue_tailp;
struct list_head poll_list;------各个napi_struct的poll_list 串接在这个成员
struct sk_buff *completion_queue;
struct sk_buff_head process_queue;----这个就是从input_pkt_queue 中取下的链表,用两个成员是为了减少锁冲突
unsigned int processed;
unsigned int time_squeeze;
unsigned int cpu_collision;
unsigned int received_rps;
#ifdef CONFIG_RPS
struct softnet_data *rps_ipi_list;
struct call_single_data csd;
struct softnet_data *rps_ipi_next;
unsigned int cpu;
unsigned int input_queue_head;
unsigned int input_queue_tail;
#endif
unsigned int dropped;
struct sk_buff_head input_pkt_queue;----入向的报文,非napi模式的,就放这个链
struct napi_struct backlog;---这个napi设备是虚拟的,为了能适配napi模式的poll,它的poll函数初始化为process_backlog
}
不支持napi的时候,网卡驱动将收到的报文,构造skb,然后调用netif_rx-->netif_rx_internal-->enqueue_to_backlog 这个流程用于将skb塞入到指定cpu的 softnet_data 变量的 input_pkt_queue,为了兼容napi的收包模式,之前初始化的napi设备,也就是 softnet_data 的backlog成员,

将 利用 ____napi_schedule(sd, &sd->backlog); 来加入对应的poll_list中,这样触发软中断之后,会在 net_rx_action 函数中处理。

那 net_rx_action 它的流程就比较简单了,它首先将 当前cpu的  softnet_data 变量 的poll_list链摘到一个临时链里面,然后循环调用napi_poll,

napi_poll 就根据不同napi_struct结构的配额,调用napi_struct的poll函数,对于刚加入的backlog成员来说,它的poll函数就是之前初始化的process_backlog ,这样就在软中断中统一了各个
poll函数了。
static int napi_poll(struct napi_struct *n, struct list_head *repoll)
{
。。。
if (test_bit(NAPI_STATE_SCHED, &n->state)) {
work = n->poll(n, weight);//调用这个napi自己的poll函数,对于backlog这个napi_struct 来说,就是 process_backlog函数了,比如对于ixgbe驱动,pll为ixgbe_poll
trace_napi_poll(n);
}
。。。。

当网卡支持napi接口,会如何处理收到的报文呢,其实就是利用 napi_schedule或者__napi_schedule,只要加入到了 softnet_data 的poll_list ,就等着报文来了。比如看一下i40e的驱动情况:

stap -d i40e netif_rx.stp
System Call Monitoring Started ( seconds)...
WARNING: DWARF expression stack underflow in CFI
0xffffffff815930b0 : __napi_schedule+0x0/0x50 [kernel]-----------把napi_struct 加入到对应poll_list,然后触发收包NET_RX_SOFTIRQ软中断
0xffffffffc01ce4a9 : i40e_msix_clean_rings+0x39/0x50 [i40e]
0xffffffff81136e44 : __handle_irq_event_percpu+0x44/0x1c0 [kernel]
0xffffffff81136ff2 : handle_irq_event_percpu+0x32/0x80 [kernel]
0xffffffff8113707c : handle_irq_event+0x3c/0x60 [kernel]
0xffffffff81139d7f : handle_edge_irq+0x7f/0x150 [kernel]
0xffffffff8102d314 : handle_irq+0xe4/0x1a0 [kernel]
0xffffffff816c9d9d : __irqentry_text_start+0x4d/0xf0 [kernel]
0xffffffff816bc362 : ret_from_intr+0x0/0x15 [kernel]

有一点点不同的是,在 netif_rx 中是需要申请skb,然后来将skb挂到收包队列去,而napi_schedule调用的各个napi设备的poll函数,由于实现的不一样,所以skb有可能是取的ring_buf

带的skb,然后将skb推送到协议栈。

linux 3.10 的中断收包笔记的更多相关文章

  1. Linux(10.5-10.11)学习笔记

    3.2程序编码 unix> gcc -01 -o p p1.c p2.c -o用于指定输出(out)文件名. -01,-02 告诉编译器使用第一级或第二级优化 3.2.1机器级代码 机器级编程两 ...

  2. Linux(10.18-10.25)学习笔记

    一.学习目标 1. 了解常见的存储技术(RAM.ROM.磁盘.固态硬盘等) 2. 理解局部性原理 3. 理解缓存思想 4. 理解局部性原理和缓存思想在存储层次结构中的应用 5. 高速缓存的原理和应用 ...

  3. linux网络收包过程

    记录一下linux数据包从网卡进入协议栈的过程,不涉及驱动,不涉及其他层的协议处理. 内核是如何知道网卡收到数据的,这就涉及到网卡和内核的交互方式: 轮询(poll):内核周期性的检查网卡,查看是否收 ...

  4. 《linux设备驱动开发详解》笔记——10中断与时钟

    10.1 中断与定时器 中断一般有如下类型: 内部中断和外部中断:内部中断来自CPU,例如软件中断指令.溢出.除0错误等:外部中断有外部设备触发 可屏蔽中断和不可屏蔽中断 向量中断和非向量中断,ARM ...

  5. 代码学习-Linux内核网卡收包过程(NAPI)【转】

    转自:https://blog.csdn.net/crazycoder8848/article/details/46333761 版权声明:本文没有任何版权限制,任何人可以以任何方式使用本文. htt ...

  6. 《Linux内核设计与实现》读书笔记(八)- 中断下半部的处理

    在前一章也提到过,之所以中断会分成上下两部分,是由于中断对时限的要求非常高,需要尽快的响应硬件. 主要内容: 中断下半部处理 实现中断下半部的机制 总结中断下半部的实现 中断实现示例 1. 中断下半部 ...

  7. Linux系统针对网卡中断的优化处理

    摘要: 中断: 当网卡接收到数据包后,会触发硬中断,通知CPU来收包.硬中断是一个CPU和网卡交互的过程.这其实会消耗CPU资源.特别是在使用速度极快的万兆网卡 之后,大量的网络交互使得CPU很大一部 ...

  8. 《Linux就该这么学》培训笔记_ch02_一些必须掌握的Linux命令

    本文在原来作者的基础上做一些符合自己的修改.原文参考: <Linux就该这么学>培训笔记_ch02_一些必须掌握的Linux命令.     本章的内容虽然多,基本都是书本原话,但是笔记能精 ...

  9. 《Linux就该这么学》培训笔记_ch08_iptables与firewall防火墙

    <Linux就该这么学>培训笔记_ch08_iptables与firewall防火墙 文章最后会post上书本的笔记照片. 文章主要内容: 防火墙管理工具 iptables firewal ...

随机推荐

  1. 第11章 拾遗4:IPv6(2)_给计算机配置IPv6地址

    4. 给计算机配置IPv6地址 4.1 无状态自动配置IPv6地址 (1)网络拓扑 ①无状态地址自动配置是指不需要DHCP服务器进行管理,由客户端向路由器发送前缀请求(RS)询问其所在网段.路由器收到 ...

  2. KafkaAPI实战

    新旧API使用 Flume和Kafka集成: Kafka有两套API: 过时的API 和新API 准备工作 <dependencies> <dependency> <gr ...

  3. CS229 7.2 应用机器学习方法的技巧,准确率,召回率与 F值

    建立模型 当使用机器学习的方法来解决问题时,比如垃圾邮件分类等,一般的步骤是这样的: 1)从一个简单的算法入手这样可以很快的实现这个算法,并且可以在交叉验证集上进行测试: 2)画学习曲线以决定是否更多 ...

  4. solr学习之域的管理与中文分析器配置

    该文使用  Centos6.5 64 位    solr4.10.3   IK-Analyzer中文分析器 一.solr域 在solr中域的概念与lucene中域的概念相同,数据库的一条记录或者一个文 ...

  5. Ddr2,ddr3,ddr4内存条的读写速率

    理论极限值是可以计算的:1333MHz * 64bit(单通道,双通道则128bit) / 8(位到字节单位转换) = 10.664GB/s.这只是理论,实际发挥还要看内存控制器,实际上1333单条跑 ...

  6. [SHOI2012]信用卡凸包(计算几何)

    /* 考验观察法?? 可以发现最终答案等于所有作为圆心的点求出凸包的周长加上一个圆的周长 向量旋转 (x1, y1) 相较于 (x2, y2) 旋转角c 答案是 (dtx * cosc - dty * ...

  7. QQ聊天字体选择

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  8. python连接数据库——create_engine和conn.cursor

    python操作数据库的方法: 一种是导入sqlalchemy包,另一种是导入psycopg2包. 具体用法如下(此处以postgre数据库举例) 第一种: # 导入包 from sqlalchemy ...

  9. Linux架构分布式集群之基础篇

    部署linux环境,安装jdk 1.安装rar命令行 wget http://www.rarlab.com/rar/rarlinux-x64-4.2.0.tar.gz由于在此目录下解压rar后linu ...

  10. Dom4j解析、生成Xml

    1以下代码未Xml的解析和生成代码 <?xml version="1.0" encoding="UTF-8"?> <users> < ...