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

    水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
  • 相关阅读:
    使用CustomValidate自定义验证控件
    C#中金额的大小写转换
    Andriod出错之Unable to build: the file dx.jar was not loaded from the SDK folder!
    VC 编写的打字练习
    机房工作笔记Ping只有单向通
    web服务协同学习笔记(1)
    Dll 学习3 将MDI子窗口封装在DLL中
    机房工作学习文件共享
    Andriod出错之Failed to find an AVD compatible with target 'Android 2.2'
    Andriod出错之wrapper was not properly loaded first
  • 原文地址:https://www.cnblogs.com/10087622blog/p/9922142.html
Copyright © 2011-2022 走看看