linux 3.10 的中断收包笔记

摘要:
非NAPI内核接口是netif_Rx(),NAPI的内核接口是NAPI_Schedule()或类似的__NAPI_总之,Schedule在硬中断中调用相应的函数。非NAPI使用共享CPU队列softnet_data-˃input_pkt_queue,NAPI使用设备内存。这个网络的作用过程相对简单。它首先将数据变量的当前CPU_Poll的软网_列表链拾取到一个临时链中,然后循环调用napi _ Poll,napi_ Poll基于不同的napi_结构的配额,调用napi_对于新添加的backlog成员,结构的Poll函数是先前初始化的进程_ backlog,它统一了软中断中的所有轮询功能。

来看下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 (10 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 的中断收包笔记》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇网站统计功能的设计与实现C# SerialPort运行方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux下tomcat的启动、关闭

路径         不论是要启动,还是要关闭tomcat服务,都是要去到tomcat安装目录下的bin路径,当然你要是电脑关机自然是不需要的。 启动          常用的启动命令有两个:         (1)  ./startup.sh          用这个命令启动之后,终端只会显示启动成功。不会有其他的信息。甚至tomcat服务是不是真的启动...

Linux下如何确认磁盘是否为SSD

方法 法1:通过查看/sys/block/sda/queue/rotational 通过cat /sys/block/sda/queue/rotational进行查看,返回值0即为SSD;返回1即为HDD。 法2:通过lsscsi查看 lsscsi - list SCSI devices (or hosts) and their attributes 实例...

go语言学习--内核态和用户态(协程)

go中的一个特点就是引入了相比于线程更加轻量级的协程(用户态的线程),那么什么是用户态和内核态呢? 一、什么是用户态和内核态 当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈...

Linux (三)

chmod:用来改变文件或目录的访问权限 语法格式:chmod 【参数选项】 【mode】【文件或者目录】 参数选项: -v :显示权限变更的详细信息 -R :对当前目录下的所有文件以及子目录进行相同的权限变更 ​ (以递归的当时逐个变更) mode :是权限标记。可以有符号标记和八进制数两种格式。 文件或者目录 :要设置的文件名或者目录名,必须输入...

linux上传文件常用命令

pscp常用命令:1、上传文件到Linux目录 windows-->linux:pscp -pw linux密码 windows文件名 linux用户名@linuxIP:linux路径  pscp -pw 123456 console_1.0.7.jar root@192.168.21.180:/home/work/ 2、上传文件目录到Linux目录...

Linux下C++编程环境搭建

  有更简单的方法:在装机器的时候选择  开发工作站系统  development workstation 工作站。免去安装java jdk ,eclipse ,g++,ssh等等各种工具的麻烦。  需要注意的是通过虚拟机安装的时候,要先创建空虚拟机,再从虚拟光驱安装,不要直接选择操作系统类型,不然会默认给安装最简化版的。光中文的设置,和输入法安装 就能让...