zoukankan      html  css  js  c++  java
  • linux 3.10 的中断收包笔记

    来看下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推送到协议栈。

    水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
  • 相关阅读:
    LOJ #2109. 「JLOI2015」骗我呢 数形结合+组合+容斥
    LOJ #2729. 「JOISC 2016 Day 1」俄罗斯套娃 扫描线+贪心
    LOJ #2508. 「AHOI / HNOI2018」游戏 拓扑排序
    LOJ #2106. 「JLOI2015」有意义的字符串 构造+矩阵乘法
    LOJ #2471. 「九省联考 2018」一双木棋 记忆化搜索
    python的md5和base64加密
    [转]python的find()方法
    [转]python的startswith()方法
    获取http请求的响应状态
    with...as...用法
  • 原文地址:https://www.cnblogs.com/10087622blog/p/9922142.html
Copyright © 2011-2022 走看看