网络数据包收发流程(二):不配置NAPI的情况

简介: 上一篇讲的是内核配置成NAPI的情况,那也是绝大多数内核使用的配置现在讲讲内核不配置成NAPI时的情况一、no NAPI 数据结构不配置NAPI的时候,网络设备不使用自己的napi_struct结构,所有网络设备驱动都使用同一个napi_struct,即cpu私有变量__get_cpu_var(softnet_data).backlog每当收到数据包时,网络设备驱动会把__get_cpu_var(softnet_data).backlog挂到__get_cpu_var(softnet_data).poll_list上面。
上一篇讲的是内核配置成NAPI的情况,那也是绝大多数内核使用的配置
现在讲讲内核不配置成NAPI时的情况

一、no NAPI 数据结构
img_d6e97912a76084905e28865c76cbecd4.jpg
不配置NAPI的时候,网络设备不使用自己的napi_struct结构,
所有网络设备驱动都使用同一个napi_struct,即cpu私有变量 __get_cpu_var(softnet_data).backlog

每当收到数据包时,网络设备驱动会把 __get_cpu_var(softnet_data).backlog挂到 __get_cpu_var(softnet_data).poll_list上面。

所以软中断里net_rx_action遍历cpu私有变量 __get_cpu_var(softnet_data).poll_list时,
上面挂的napi_struct只有一个

二、内核启动时的准备工作

也是在 net_dev_init中,初始化了cpu私有变量的napi_struct,即所有网络设备驱动使用的napi_struct

__init net_dev_init()
{
    //每个CPU都有一个私有变量 _get_cpu_var(softnet_data)
    //
_get_cpu_var(softnet_data).poll_list很重要,软中断中需要遍历它的
    for_each_possible_cpu(i) {
        struct softnet_data *queue;
        queue = &per_cpu(softnet_data, i);
        skb_queue_head_init(&queue->input_pkt_queue); // 不配置NAPI时,才使用这个接收队列
        queue->completion_queue = NULL;
          INIT_LIST_HEAD(&queue->poll_list);
        queue->backlog.poll = process_backlog;        // poll钩子函数初始化
        queue->backlog.weight = weight_p;             //

    }
    open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); //在软中断上挂网络接收handler
    open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); //在软中断上挂网络发送handler

}

三、中断里接受以太网包

TSEC的接收中断处理函数

gfar_receive

{
    gfar_write(&priv->regs->ievent, IEVENT_RX_MASK);
#ifdef CONFIG_GFAR_NAPI
    // test_and_set当前net_device的napi_struct.state 为 NAPI_STATE_SCHED
    // 在软中断里调用 net_rx_action 会检查状态 napi_struct.state
    if (netif_rx_schedule_prep(dev, &priv->napi)) { 
        tempval = gfar_read(&priv->regs->imask);            
        tempval &= IMASK_RX_DISABLED;
        gfar_write(&priv->regs->imask, tempval);   
        // 将当前net_device的 napi_struct.poll_list 挂到
        // CPU私有变量 &__get_cpu_var(softnet_data).poll_list 上,并触发软中断
        // 所以,在软中断中调用 net_rx_action 的时候,就会执行当前net_device的
        // napi_struct.poll()钩子函数,即 gfar_poll()
        __netif_rx_schedule(dev, &priv->napi);  
    }

#else
    gfar_clean_rx_ring(dev, priv->rx_ring_size);
#endif
}

gfar_clean_rx_ring  
  
-->gfar_process_frame  
      -- > 初始化了skb->dev,这样在软中断里才能判断这个数据包来自哪里
      --> RECEIVE(skb) // 调用 netif_rx(skb)


#ifdef CONFIG_GFAR_NAPI
#define RECEIVE(x) netif_receive_skb(x)
#else
#define RECEIVE(x) netif_rx(x)
#endif

netif_rx(skb)
{
   queue = &__get_cpu_var(softnet_data);
   __skb_queue_tail(&queue->input_pkt_queue, skb); //将skb放到接收队列(在net_dev_init初始化)中
   napi_schedule(&queue->backlog); //将cpu私有变量的的napi_struct挂到cpu私有变量的poll_list上
                                   //test_and_set napi_struct.state为 NAPI_STATE_SCHED
                                   //触发网络接收软中断
}

软中断net_rx_action中调用poll钩子函数

虽说软中断里也遍历cpu私有变量的poll_list,事实上poll_list现在只挂一个napi_struct结构
即cpu私有变量的backlog成员(它在net_dev_init中初始化),所以现在调用的poll钩子函数就是process_backlog了

static int process_backlog(struct napi_struct *napi, int quota)
{
    struct softnet_data *queue = &__get_cpu_var(softnet_data);
    napi->weight = weight_p;
    do {
        struct sk_buff *skb;
        struct net_device *dev;

        local_irq_disable();
        skb = __skb_dequeue(&queue->input_pkt_queue); //从接收队列中取出skb,
        if (!skb) {                                   //这些skb是在netif_rx中进入队列的
            __napi_complete(napi);
            local_irq_enable();
            break;
        }
        local_irq_enable();
        dev = skb->dev;
        netif_receive_skb(skb);     //进入协议协议栈
        dev_put(dev);
    } while (++work     return work;
}

目录
相关文章
|
1月前
|
安全 网络安全 数据安全/隐私保护
|
1月前
|
网络协议 网络架构
网络工程师必知:什么是OSPF多区域?如何配置?
网络工程师必知:什么是OSPF多区域?如何配置?
46 2
网络工程师必知:什么是OSPF多区域?如何配置?
|
1月前
|
网络协议 Linux
图形界面配置网络
本文介绍了在Linux上配置网络服务的步骤。首先打开RHEL-01服务器,找到桌面网络配置选项,进入网络配置面板。点击面板右下角的小齿轮,进入有线配置面板,选择IPv4选项,将地址设置为手动。接下来配置IP地址、子网掩码、网关和DNS服务器。配置完成后,使用新的IP地址进行访问。
41 4
图形界面配置网络
|
28天前
|
监控 负载均衡 网络协议
OSPF在小型网络中的应用:简化配置与高效管理
OSPF在小型网络中的应用:简化配置与高效管理
95 1
|
1月前
|
网络虚拟化 数据安全/隐私保护 数据中心
对比了思科和华为网络设备的基本配置、接口配置、VLAN配置、路由配置、访问控制列表配置及其他重要命令
本文对比了思科和华为网络设备的基本配置、接口配置、VLAN配置、路由配置、访问控制列表配置及其他重要命令,帮助网络工程师更好地理解和使用这两个品牌的产品。通过详细对比,展示了两者的相似之处和差异,强调了持续学习的重要性。
51 2
|
1月前
|
网络协议 Linux
通用网卡配置文件配置网络
本文介绍了在RHEL 7系统中配置网络的方法。首先,通过编辑位于`/etc/sysconfig/network-scripts`目录下的网卡配置文件(例如`ifcfg-ens33`),设置静态IP地址、子网掩码、网关和DNS等参数。接着,使用`systemctl`命令重启网络服务,确保配置生效。此外,还介绍了使用`nmtui`图形界面工具进行网络配置的步骤,包括修改IP地址、保存配置和重启网络。最后,通过`ip addr`或`ifconfig`命令验证配置是否成功。
97 2
|
2月前
|
网络协议 安全 网络安全
Cisco-网络端口地址转换NAPT配置
Cisco-网络端口地址转换NAPT配置
|
2月前
|
机器学习/深度学习 数据采集 算法
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
这篇博客文章介绍了如何使用包含多个网络和多种训练策略的框架来完成多目标分类任务,涵盖了从数据准备到训练、测试和部署的完整流程,并提供了相关代码和配置文件。
64 0
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
|
2月前
|
存储 网络协议 Java
【网络】UDP回显服务器和客户端的构造,以及连接流程
【网络】UDP回显服务器和客户端的构造,以及连接流程
60 2
|
2月前
|
存储 缓存 Ubuntu
配置网络接口的“IP”命令10个
【10月更文挑战第18天】配置网络接口的“IP”命令10个
77 0
下一篇
DataWorks