linux网络子系统中对报文的接收和处理时由收包软中断进行处理的。
具体的接收过程请参考我的另一篇博文

这里我们接收分析一下收报软中断的处理

初始化报文接收软中断

static int __init net_dev_init(void)
{
    ......
    open_softirq(NET_RX_SOFTIRQ, net_rx_action);
    ......
}

报文接收软中断的处理函数net_rx_action详解:

static void net_rx_action(struct softirq_action *h)
{
    /*取得本地cpu 的softnet_data 的poll_list  链表*/
    struct list_head *list = &__get_cpu_var(softnet_data).poll_list;
    /*设置软中断处理程序一次允许的最大执行时间为2个jiffies*/
    unsigned long time_limit = jiffies + 2; 
    /*设置软中断接收函数一次最多处理的报文个数为 300 */
    int budget = netdev_budget;
    /*关闭本地cpu的中断,下面判断list是否为空时防止硬中断抢占*/
    local_irq_disable();

/*循环处理pool_list 链表上的等待处理的napi*/
    while (!list_empty(list))
    {
        struct napi_struct *n;
        int work, weight;                                                                                                                                     
        /*如果处理报文超出一次处理最大的个数或允许时间超过最大时间就停止执行,
          跳到softnet_break 处*/
        if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))
        {
            goto softnet_break;
        }
        /*使能本地中断,上面判断list为空已完成,下面调用NAPI
          的轮询函数是在硬中断开启的情况下执行*/
        local_irq_enable();                                                                                                                                     
        /* 取得softnet_data pool_list 链表上的一个napi,
           即使现在硬中断抢占软中断,会把一个napi挂到pool_list的尾端
           软中断只会从pool_list 头部移除一个pool_list,这样不存在临界区*/
        n = list_entry(list->next, struct napi_struct, poll_list);

/*用weighe 记录napi 一次轮询允许处理的最大报文数*/
        weight = n->weight;
        /* work 记录一个napi总共处理的报文数*/
        work = 0;
  
        /*如果取得的napi状态是被调度的,就执行napi的轮询处理函数*/
        if (test_bit(NAPI_STATE_SCHED, &n->state))
        {
            work = n->poll(n, weight);
        }
        WARN_ON_ONCE(work > weight);

/*预算减去已经处理的报文数*/
        budget -= work;

/*禁止本地CPU 的中断,下面会有把没执行完的NAPI挂到softnet_data
          尾部的操作,和硬中断存在临界区。同时while循环时判断list是否
          为空时也要禁止硬中断抢占*/
        local_irq_disable();
  
        /*如果napi 一次轮询处理的报文数正好等于允许处理的最大数,
          说明一次轮询没处理完全部需要处理的报文*/
        if (unlikely(work == weight))
        {
            /*如果napi已经被禁用,就把napi 从 softnet_data 的pool_list 上移除*/
            if (unlikely(napi_disable_pending(n)))
            {
                local_irq_enable();
                napi_complete(n);
                local_irq_disable();
            }
            else
            {
                /*否则,把napi 移到 pool_list 的尾端*/
                list_move_tail(&n->poll_list, list);
            }
        }
    }
out:
    local_irq_enable();
    return;
  
    /*如果处理时间超时,或处理的报文数到了最多允许处理的个数,
      说明还有napi 上有报文需要处理,调度软中断。
      否则,说明这次软中断处理完全部的napi上的需要处理的报文,不再需要
      调度软中断了*/
softnet_break:
    __get_cpu_var(netdev_rx_stat).time_squeeze++;
    __raise_softirq_irqoff(NET_RX_SOFTIRQ);
    goto out;
}

Linux网络子系统中收包软中断相关推荐

  1. linux 网络 指示灯 亮,Linux网络子系统中GRO的实现

    GRO (generic receive offload) GRO是在协议栈接收报文时进行减负的一种处理方式,该方式在设计上考虑了多种协议报文.主要原理是在接收端通过把多个相关的报文(比如TCP分段报 ...

  2. Linux网络子系统

    今天分享一篇经典Linux协议栈文章,主要讲解Linux网络子系统,看完相信大家对协议栈又会加深不少,不光可以了解协议栈处理流程,方便定位问题,还可以学习一下怎么去设计一个可扩展的子系统,屏蔽不同层次 ...

  3. 一文搞定 | Linux 网络子系统

    今天分享一篇经典Linux协议栈文章,主要讲解Linux网络子系统,看完相信大家对协议栈又会加深不少,不光可以了解协议栈处理流程,方便定位问题,还可以学习一下怎么去设计一个可扩展的子系统,屏蔽不同层次 ...

  4. linux 网卡只收到包不发包,【干货分享】Linux虚拟机网卡只能收包不能发包?

    [干货分享]Linux虚拟机网卡只能收包不能发包?: U1 d; M2 ~  ]7 Q: J5 M- v# J3 @ * v; Y  P1 Q$ ]: I' T8 z在ovs场景主机与同主机上的虚拟机 ...

  5. linux 网络路径中网络协议栈有几种,linux网络路径中网络协议栈有几种

    网络路径有很多种,其中的linux网络路径是最常用的,也是最需要关注的.linux网络路径中网络协议栈有几种?电脑新装系统漏洞应不应该修复?了解网络安全常识,首先就要了解计算机网络安全有哪些基本注意事 ...

  6. Linux网络服务中,bond网络模式

    Linux网络服务中,bond网络模式 bond网络模式原理 多块网卡虚拟成一块网卡,实现冗余,多张网卡对外显示一张,具有同一个IP,网络配置都会使用Bonding技术做网口硬件层的冗余,防止单个网口 ...

  7. linux网络子系统研究:数据收发简略流程图

    Linux网络子系统十分庞大复杂,总想着等自己全部弄明白后再动笔写些笔记,但实在太耗时.后来想通了,先从宏观上掌握大体框图,然后再研究细节. 本文先给出一张自己画的网络数据收发简略流程图,每个路径都可 ...

  8. Linux协议栈:基于ping流程窥探Linux网络子系统,及常用优化方法

    初识 Linux 网络栈及常用优化方法 RToax 2020年9月 初识 Linux 网络栈及常用优化方法 1. 文章简介 基于 ping 流程窥探 Linux 网络子系统,同时介绍各个模块的优化方法 ...

  9. linux给网卡添加一个ip地址,linux网络配置中如何给一块网卡添加多个IP地址

    汤向峰每日一题-2017年3月16日: linux网络配置中如何给一块网卡添加多个IP地址 linux系统给网卡配置VIP的方法常见有两种:别名IP.以及辅助IP ================== ...

  10. Windows 10安装Linux子系统、可视化Linux、子系统中openfoam

    Windows 10安装Linux子系统.可视化Linux.子系统中openfoam安装 一. Windows 10安装Linux子系统 打开Windows PowerShell(管理员) 鼠标右键点 ...

最新文章

  1. Android中Service生命周期、启动、绑定、混合使用
  2. Problem 77:Prime summations
  3. SQL Server导入导出工具弱爆了
  4. Windows Server 2003 单网卡启用×××远程外网访问功能
  5. 实验 2 关键字驱动测试(2 学时)实验报告--软件功能测试与性能测试实验
  6. linux修改永久ip地址,centos设置IP地址,永久修改ipv4
  7. 车羊问题c语言编程,C语言-人狼羊菜问题-最容易看懂的解决方法及代码
  8. 用SDWebImage渐变加载图片
  9. 在Windows下运行UNIX程序
  10. 如何清空c盘只剩系统_怎么把C盘东西都删除只留系统东西
  11. 有三个桶,两个大的可装8斤的水,一个小的可装3斤的水,现在有16斤水装满了两大桶就是8斤的桶,小桶空着,如何把这16斤水分给4个人,每人4斤。没有其他任何工具,4人自备容器,分出去的水不可再要回来。
  12. 中大计算机研究生华为,考上中山大学很厉害吗?毕业后有机会去华为吗?本文有答案...
  13. 国内木兰造假!国外无一入选顶会!论两极分化下的编程语言研究
  14. 支付宝H5,微信H5,微信公众号支付回调
  15. 【项目整理】安卓应用商店评论监控平台
  16. jquery循环创建div
  17. 智云通CRM:采购决策有哪些关键节点?
  18. 09-面向对象综合训练综合练习
  19. (MVP框架)登录+数据展示
  20. elementui 使用el-image 控件 解决 通过点击查看按钮两次才能 实现预览图片

热门文章

  1. L1-043 阅览室 (20 分)—团体程序设计天梯赛
  2. 对,信中介不去信一头猪
  3. python3中文乱码解决方法
  4. Python unittest基本框架组成(1)
  5. ECMAScript 6----字符串的扩展
  6. CSS3之3D效果中的transform运用
  7. 树形DP+二分(Information Disturbing HDU3586)
  8. 未将对象引用设置到对象实例(转)
  9. 网管学习日记-ACL
  10. android图片选择库selectp,浅谈android的selector背景选择器