总体概览如下:

假设upcall handler线程有两个,vport有四个,那么每个vport下都将持有两个NetLink连接的信息,这两个NetLink连接将被用来上送upcall消息。
每个NetLink连接被对应的upcall handler线程接管,多个vport在同一线程中的NetLink连接被epoll管理。
1:每个vport下都挂多个NetLink连接,数量等同于upcall处理线程的数量
2:线程中routine函数为udpif_upcall_handler,伪码如下:
     routine {
          while(线程不设自杀标记) {
               if(从epoll中收到了一些upcall消息,则进一步处理upcall) {
                    continue; 
               } else {
                    注册poll:当epoll_fd有骚动时解除当前线程的block
               }
               block当前线程
          }
     }
3:每个NetLink连接被称为一个upcall channel
 
1:upcall处理线程的创建
upcall处理线程随着vswitchd进程的启动而被创建,概览如下:

最终所有线程信息会被记录在 ofproto_dpif->backer->udpif下
 
2:vport的创建与channels的创建
在基于本机内核的datapath实现的openflow交换机场景下,用户态的datapath接口将采用dpif_netlink_***系列函数。vport的创建在用户态最终将调用到dpif_netlink_port_add,这是dpif_netlink_port_add__的包裹函数。
 
先说一点我对NetLink连接的理解
     1:创建socket
     2:可选的bind步骤,在这一步,应当在本端地址结构中赋值nl_pid为当前进程ID,并bind之。
     3:建立连接connect,这一步对端地址结构的nl_pid值如果为非0值 ,那么连接的就是一个用户态进程。如果nl_pid值为0,则连接的是内核。
     如果没有第2步,那么在connect之后,内核会为这个NetLink连接的本端bind地址结构自动指定一个nl_pid值,以标识该连接。此时通过getsockname取到的本端地址结构中的nl_pid字段将不是发起连接一方的进程ID。

3:内核cache miss
内核cache miss后,会发送upcall消息,
 
netdev_frame_hook(pskb)
    |
    \-> netdev_port_receive(skb, NULL/skb_tunnel_info(skb))
        |
        \-> ovs_vport_receive(ovs_netdev_get_vport(skb->dev), skb, tun_info = NULL/skb_tunnel_info(skb))
            |
            \-> error = ovs_flow_key_extract(tun_info, skb, &key)
            |
            \-> ovs_dp_process_packet(skb, &key)
                |
                \-> flow = ovs_flow_tbl_lookup_stats(&dp->table, key, skb_get_hash(skb), &n_mask_hit)
                    if(unlikely(!flow)) {
                        ...
                        upcall.cmd = OVS_PACKET_CMD_MISS;
                        upcall.portid = ovs_vport_find_upcall_portid(p, skb);
                        |
                        \-> 在vport下的upcall_portids里钦定一个port号,作为NetLink的目的地
                        ...
                        error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
                    }
即是从upcall的vport下挂的socksp中选择一个nl_pid,以这个nl_pid做为upcall消息发送的目的地址
由上面的图能看出来,在vport下选择不同的socksp中的nl_pid,会导致消息被发往不同的epoll
 
 
4:dpif_handler[]->epoll_fd与用户态线程间的关联

那么在udpif_upcall_handler() -> recv_upcalls() -> dpif_recv() -> dpif_netlink_recv() -> dpif_netlink_recv__()中有以下代码:
 

这里的参数handler_id来自于线程routine函数的入参handler实例下的handler_id。
即对于x号线程,它会取dpif_handler[]数组中的x号元素下的epoll_fd去处理。

body,td { font-family: Consolas; font-size: 10pt }

OVS 中的 upcall 线程的更多相关文章

  1. 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

    [源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...

  2. Java中的守护线程和非守护线程(转载)

    <什么是守护线程,什么是非守护线程> Java有两种Thread:"守护线程Daemon"(守护线程)与"用户线程User"(非守护线程). 用户线 ...

  3. springmvc中request的线程安全问题

    SpringMvc学习心得(四)springmvc中request的线程安全问题 标签: springspring mvc框架线程安全 2016-03-19 11:25 611人阅读 评论(1) 收藏 ...

  4. Unity 中 使用c#线程

    使用条件   天下没有免费的午餐,在我使用unity的那一刻,我就感觉到不自在,因为开源所以不知道底层实现,如果只是简单的做点简单游戏,那就无所谓的了,但真正用到实际地方的时候,就会发现一个挨着一个坑 ...

  5. Java中的守护线程 & 非守护线程(简介)

    Java中的守护线程 & 非守护线程 守护线程 (Daemon Thread) 非守护线程,又称用户线程(User Thread) 用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守 ...

  6. HttpApplication中的异步线程

    一.Asp.net中的线程池设置 在Asp.net的服务处理中,每当服务器收到一个请求,HttpRuntime将从HttpApplication池中获取一个HttpApplication对象处理此请求 ...

  7. c#中如何跨线程调用windows窗体控件

    c#中如何跨线程调用windows窗体控件?   我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来做这个问题,下面我将详细的介绍.首 ...

  8. c#中如何跨线程调用windows窗体控件?

    我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来做这个问题,下面我将详细的介绍.首先来看传统方法: public partial c ...

  9. C#如何判断线程池中所有的线程是否已经完成之Demo

    start: System.Threading.RegisteredWaitHandle rhw = null; new Action(() => { ; i < ; i++) { new ...

随机推荐

  1. C++ struct 初始化的问题

    struct student { int age; string name; int id; }; 初始化: student st1={10, "li ming", 01}; 修改 ...

  2. Unity 类似FingerGestures 的相机跟随功能

    本文原创,转载请注明出处:http://www.cnblogs.com/AdvancePikachu/p/6555188.html 最近在做一款VR项目,有一个查看功能,分为自由查看和跟随查看. 自由 ...

  3. User Browsing Model简介

    搜索引擎的点击日志提供了很多有价值的query-doc相关性信息,但是这些信息是有偏的,因为对于用户没有点击过的doc,我们无法确定其是否真实地被用户浏览过.即日志中记录的展现信息与实际的展现信息之间 ...

  4. spring 动态创建数据源

    项目需求如下,公司对外提供服务,公司本身有个主库,另外公司会为每个新客户创建一个数据库,客户的数据库地址,用户名,密码,都保存在主数据库中.由于不断有新的客户加入,所以要求,项目根据主数据库中的信息, ...

  5. EZChart - 在线图表生成器

    朋友写材料时,需要用到一些分析图表,嫌Excel的太丑,就为他写了一个在线图表生成器. 纯静态实现,基于:H5 + Bootstrap + FusionCharts 本地存储使用H5的localSto ...

  6. AIX误删除LV后如何进行现场保护和数据恢复工作

    在AIX环境下,若因维护误操作.存储mapping错误等,不小心将LV误删除,这种损失通常是巨大的.删除后的不当保护及恢复操作可能使数据无法恢复,也可能增加处理的时间与算法复杂度.如何有效保护现场,并 ...

  7. nginx参数的详细说明

    #开启进程数 <=CPU数 worker_processes 1; #错误日志保存位置 #error_log logs/error.log; #error_log logs/error.log ...

  8. Angular杂谈系列2-Angular2升级Angular4指南

    什么什么?Angualr4都发布了,之前不都才Angualr2的么?又要推翻重来,啊? 那当然不是,Angualr4只是一个版本号而已,本质上还是Angular2:以后,谷歌把新版本的Angualr称 ...

  9. PHP的虚拟域名的配置

    由于本人的自己搭建的php环境,Wamp环境.虚拟域名是写程序的一个最基本的配置,也对项目的调试有一定的真实感.我在学习虚拟域名的时候是受到了一些的问题,所以说写这个是为了帮助新人少走弯路, 也是为了 ...

  10. 蓝桥杯- 煤球数目-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...