zoukankan      html  css  js  c++  java
  • netif_rx解析

    netif_rx函数是在网上收到数据包后,通过中断机制通知CPU而间接调用的中断处理例程。

    首先,会将Packet传给netpoll框架,该框架用于在网络协议栈不可用的情况下,也能够提供给内核一个收发Packet的接口,用于一些特殊场合的调试等用途。

    netpoll只是一种框架和一些接口,只有依赖这个框架和接口实现的netpoll实例,netpoll才能发挥它的功能。类似于kernel中的vfs,vfs本身并不会去做具体的文件操作,只是为不同的文件系统提供了一个框架。netpoll不依赖于网络协议栈,因此在内核网络及I/O子系统尚未可用时,也可以发送或接收数据包。当然netpoll能够处理的数据包类型也很有限,只有UDP和ARP数据包,并且只能是以太网报文。注意这里对UDP数据包的处理并不像四层的UDP协议那样复杂,并且netpoll可以发挥作用要依赖网络设备的支持。

    如果netpoll没有处理Packet,那么就塞到CPU的backlog队列中,即softnet_data->input_pkt_queue队列中。

    那么内核是怎么选择塞给哪个CPU的呢,有一种机制叫RPS(receive flow steering), 是Google提交的Patch,主要用于解析负载均衡问题。但是在这之前,网卡的中断信号是连接到哪个CPU的引脚上的呢,这可能要继续研究APIC的结构,以后再拾这条线。

    还有一种机制叫NAPIhttp://blog.csdn.net/efan_linux/article/details/4642019

    /*
     * enqueue_to_backlog is called to queue an skb to a per CPU backlog
     * queue (may be a remote CPU queue).
     */
    static int enqueue_to_backlog(struct sk_buff *skb, int cpu,
                      unsigned int *qtail)
    {
        struct softnet_data *sd;
        unsigned long flags;
     
        sd = &per_cpu(softnet_data, cpu);
     
        local_irq_save(flags);
     
        rps_lock(sd);
        if (skb_queue_len(&sd->input_pkt_queue) <= netdev_max_backlog) {
            if (skb_queue_len(&sd->input_pkt_queue)) {
    enqueue:
                __skb_queue_tail(&sd->input_pkt_queue, skb);
                input_queue_tail_incr_save(sd, qtail);
                rps_unlock(sd);
                local_irq_restore(flags);
                return NET_RX_SUCCESS;
            }
     
            /* Schedule NAPI for backlog device
             * We can use non atomic operation since we own the queue lock
             */
            if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) {
                if (!rps_ipi_queued(sd))
                    ____napi_schedule(sd, &sd->backlog);
            }
            goto enqueue;
        }
     
        sd->dropped++;
        rps_unlock(sd);
     
        local_irq_restore(flags);
     
        atomic_long_inc(&skb->dev->rx_dropped);
        kfree_skb(skb);
        return NET_RX_DROP;
    }
  • 相关阅读:
    hdu-3376-Matrix Again(最小费用最大流)
    CF-164C. Machine Programming(最小费用最大流)
    splay模板
    POJ-3580-SuperMemo(splay的各种操作)
    pygame安装
    hg 证书验证失败
    hdu-3487-Play with Chain-(splay 区间翻转,切割,插入)
    jvm 重载 重写
    多线程踩坑
    hashmap时间复杂度
  • 原文地址:https://www.cnblogs.com/long123king/p/3530030.html
Copyright © 2011-2022 走看看