• 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;
    }
  • 相关阅读:
    Java基础_0205: 程序逻辑结构
    java基础_0204:运算符
    Centos 7 安装MySQL
    Maven 入门
    winx64 MySQL 5.7绿色版安装步骤
    hadoop环境搭建
    配置虚拟机 Linux 静态IP
    JDK开发环境搭建及环境变量配置
    设计模式之命令模式详解(故事版)
    设计模式之 外观模式详解(Service第三者插足,让action与dao分手)
  • 原文地址:https://www.cnblogs.com/long123king/p/3530030.html
Copyright © 2020-2023  润新知