关于 DPDK 的 一些零散的杂言杂语的念头/看法

回顾了之前 DPDK 的一些学习。有一些零散的杂言杂语的念头/看法,原本分散在各处,之前没有记录下来。这里简单记录补充一下。


===============================================================================================================

@@@ #1. DPDK 的各种 API subset 的定义,肯定是从 通用性的角度 来定义,目标是 “期望尽量generic,定义一些common framework,期望所有 NIC / PMD 都尽量遵循 这些common framework的定义”。但是,这种 “期望”,有时可能会造成一些理解和使用上的混乱。

---------------------------------------------------------------------------------------------------------------

--- 例子 #1. Generic flow API (rte_flow)


    这个 API subset 的 common framework 所定义的模型是:


        期望 NIC 内部有一个 硬件上的 HW component "flow engine"(__逻辑上的定义,名字随意),可以对其配置 flow rules。


        一条 flow rule = matching items + actions。 其中,matching items 是定义了 packet metadata(__比如说,5-tuple,VLAN, 等等 )。 

                #
                # --- 注意 flow rule 在 DPDK framework 中的结构体定义,是 generic 的,但具体配置到 NIC flow engine 时,会被 NIC/PMD “翻译”为 NIC-specific 的格式。
                #


        对 ingress / egress packets, "flow engine" 在硬件上的处理是,根据 flow rules table,对 packets 判断其是属于哪一条 flow rule,并执行 rule 中的 actions。

    问题在于:

        并不是所有 NIC 都会有一个 HW component "flow engine"。        # 或者,没有明显的 "flow engine"。

        并不是所有 有"flow engine",都支持 common framework 所定义的 全部 matching items types 和 actions types。


    ------------------------------------------------------

    比如说:

        
        Marvell PPv2 (Packet Processor v2) 1/10 Gbps adapter    # 见: << Network Interface Controller Drivers---nics >> / Chapter 36. MVPP2 POLL MODE DRIVER        


            我手头上并没有 MVPP2 的 datasheet。但是之前做过 基于 Marvell xCat switch chip 的交换机项目,知道 Marvell 的网卡,一般会有 "Policy Engine", "Tunnel-Termination", "Tunnel-Start"(__这些都是 Marvell datasheet 中本身的名字,可以认为它们共同算作 Marvell NIC 的 "flow engine" )。


            从 Marvell NIC 所支持的硬件能力来看,其是可以:

                    对 匹配 matching items 的 tunnel packet,进行 DECAP,得到 inner packet。

                    或者,对匹配 matching items 的 non-tunnel packet,进行 ENCAP,得到 tunnel packet .

            

        Marvell NIC 所支持的 tunnel protocol,又并不是 DPDK 所定义的。


        DPDK rte_flow framework,定义了这些 tunnel 相关的 flow action:

            RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
            RTE_FLOW_ACTION_TYPE_VXLAN_DECAP


            RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP        # 字面缩写好像是 "Next Version GRE"
            RTE_FLOW_ACTION_TYPE_NVGRE_DECAP        # --- 但实际上是 Network Virtualization using Generic Routing Encapsulation (NVGRE)


            ... 等等。


        而 Marvell NIC (__我只提我看到过的 ) 只支持 GRE tunnel 和 MPLS tunnel。


        所以,在 DPDK 中的 MVPP2 PMD,就不支持 DPDK rte_flow framework 的 这些 tunnel 相关的 flow actions。


            --- <tip>: 可能目前看到的,就只有 /drivers/net/mlx5/ 对 tunnel flow actions 支持得比较好。

    ------------------------------------------------------

    又比如说:


        Intel e1000 或者 ixgbe 或者 i40e。


        它们 datasheet 中,并没有明确提到 "flow engine" 这么一个 HW component。

        但是有 "flow redirector" (FDIR) 和其他各种 filter tables。
        

        注意,它们的 "flow redirector" (FDIR) 和 "filter tables" 的大致功能是: 对匹配的 packets,进行 drop 或者 multi-rxq-assignment (__即,enqueue 到不同的 rx_ring 中 )。

        所以,它们的 PMD 中对 DPDK rte_flow framework 的支持,        # igb_flow.c, ixgbe_flow.c, i40e_flow.c
        基本上只支持这些 action types:

            RTE_FLOW_ACTION_TYPE_DROP

            RTE_FLOW_ACTION_TYPE_QUEUE            # enqueue 到不同的 rx_ring 中


        rte_flow framework 所定义的大部分其他 action types,都不支持。


    ------------------------------------------------------

    从 DPDK programming 使用 Generic flow API (rte_flow) 的角度来看,


        #a. 需要 熟悉 underlying NIC / PMD,它们 对 rte_flow 的支持如何,支持哪些内容,不支持哪些内容。

            
            需要看一看 underlying PMD 的 xxx_flow.c 和 datasheet。

        #b. 依赖 rte_flow API,判断 underlying NIC / PMD 是否支持一条 flow rule

                /* Check whether a flow rule can be created on a given port. */
                int
                rte_flow_validate(uint16_t port_id,
                          const struct rte_flow_attr *attr,
                          const struct rte_flow_item pattern[],
                          const struct rte_flow_action actions[],
                          struct rte_flow_error *error)             


            其内部会调用不同 PMD 的 xxx_flow.c 的 xxx_flow_validate(),进行判断和检查,比如说:

                igb_flow_validate()

                ixgbe_flow_validate()

                i40e_flow_validate()


            检查支持的话,再去实际地配置 flow rule。

                /* Create a flow rule on a given port. */
                struct rte_flow *
                rte_flow_create(uint16_t port_id,
                        const struct rte_flow_attr *attr,
                        const struct rte_flow_item pattern[],
                        const struct rte_flow_action actions[],
                        struct rte_flow_error *error)


    ------------------------------------------------------
        
---------------------------------------------------------------------------------------------------------------

===============================================================================================================

@@@ #2. DPDK API中,有一些 API subset 在其 文档 上并没有描述得很清楚,比如说,没有说明白 这些 API subset 是和NIC硬件上相关 或者是 纯粹的软件上实现的逻辑,可能会造成一些理解和使用上的混乱。    ---    需要自己理清楚,来判断在实际工作中,是否适合使用。


---------------------------------------------------------------------------------------------------------------

--- 例子 #1. QoS 相关的内容。        # 是相当混乱的一部分内容。


 在 DPDK 中,QoS 大概有这些内容(__以他们相关的头文件):        # 见文档: << Programmer's Guide---prog_guide >>


    ingress:        # 主要是 metering 和 policing


        <rte_mtr.h>


        <rte_meter.h>, <rte_policer.h>        # 见 文档 / 14. Traffic Metering and Policing API


    egress:            # 主要是 scheduling

    
        <rte_tm.h>        # 见 文档 / 15. Traffic Management API


        <rte_sched.h>    # 见 文档 / 44. Quality of Service (QoS) Framework

 这4者之间的关联关系是: ....... 没有任何关联关系。    


 --- 所以,很容易在理解和使用上造成混乱。

    ------------------------------------------------------

    ingress <rte_mtr.h>


        是 通过 Generic flow API (rte_flow) (__上面提到过的)来使用。配置 flow rule 的 action type:

                RTE_FLOW_ACTION_TYPE_METER

        让 NIC 硬件中的 "flow engine",对 匹配的 packets 进行 metering / policing。


        --- 即,metering / policing 逻辑,是由 NIC 硬件上来做的。


            但注意,并不是所有 NIC/PMD,都支持 这个 RTE_FLOW_ACTION_TYPE_METER。    # 只有少数才支持。


    ------------------------------------------------------

    ingress <rte_meter.h>, <rte_policer.h>


        和 NIC 硬件没有关系。完全是一个 软件上的 API subset。


        --- 在 软件上,由 CPU 来执行 执行 metering/policing 的逻辑。
    

    ------------------------------------------------------

    ingress <rte_mtr.h> 和 <rte_meter.h>, <rte_policer.h> 之间的关联关系是: 没有关系。


    ------------------------------------------------------

    egress <rte_tm.h>


        大致功能是,配置 NIC 硬件上的 multi-tx-queue 的 weight, RED policy, shaper rate limiting 等。


        其定义了 node hierarchy 的模型。

            这个模型是多层次的,其中 leaf node 对应一条 HW tx-queue。


        不同的 NIC/PMD 所支持的层次数量,和 具体的层次定义,并不相同。
    
            比如说:
    
                    ixgbe: port / tc / queue        # 三层        # ixgbe_tm.c
    
    
                    mvpp: root / queue                # 二层        # mrvl_tm.c
                
            
                    octecon: root / sch1 / sch2 / sch3 / sch4 / queue    # 好多层,搞不明白    # otx_tm.c


        node hierarchy模拟的通用定义是: (__我猜想的),指定不同层次 的 weight, RED policy, shaper rate limiting。


        但 NIC / PMD 的实际支持,可能 就只是: 对 HW tx-queue 设置 rate limiting,而已。

            比如说:
     
                    ixgbe: ixgbe_hierarchy_commit()        # 其并不对 port / tc 进行什么设置,只是设置 queue 的 rate limit。

        
    ------------------------------------------------------

    egress <rte_sched.h>


        纯软件的 SW-level 的 API subset,和 NIC 硬件上的 hw_tx_ring scheduling 没有任何关系。


        其所定义的 5-level tree hierarchy,和 上面 <rte_tm.h> 定义的 node hierarchy,没有任何关系。

        <rte_sched.h> 和 Linux tc ( Qdisc ) 相似:


            在 packet TX 时,将 egress packets 给 enqueue 到 hierarchy 中 进行排队什么的,然后从 hierarchy 中 dequeue 一些 packets 进行 actual TX。


    ------------------------------------------------------

    egress <rte_tm.h> 和 <rte_sched.h> 之间的关联关系是: 没有关系。

    
    ------------------------------------------------------

---------------------------------------------------------------------------------------------------------------

--- 例子 #2. Bond


    见: << Programmer's Guide---prog_guide >> / 22. Link Bonding Poll Mode Driver Library


    大部分 switch chip,都支持 将多个 ports 组成一个 bond ports 的,这是硬件上的功能。


    而 DPDK 的 bonding PMD,完全是软件上的功能。            # 和 Linux bonding framework 一样。


    不过,DPDK 文档上一开始就说明白了,是 "pure-software library":

        DPDK also includes a pure-software library that allows physical PMDs to be bonded together to create a single logical PMD.


---------------------------------------------------------------------------------------------------------------

--- 例子 #3. <rte_flow_classifier.h>        # 见 << Programmer's Guide---prog_guide >> / 29. Flow Classification Library


    << Programmer's Guide---prog_guide >> 

        / 12. Generic flow API (rte_flow)        # <rte_flow.h>

        / 29. Flow Classification Library        # <rte_flow_classifier.h>
    

 这两者的关系是: ..... 基本没有关系。


 <rte_flow.h> (__前面提到过的),是去配置 NIC 硬件中的 "flow engine" 的 flow rules。


 <rte_flow_classifier.h>,则是:


        完全是在 SW-level 实现的 library。和 low-level PMD 和 NIC 都无关。


        之所以 在名字上叫做 "flow",是因为它“借用”了 <rte_flow.h> 定义的 data structure:

                   const struct rte_flow_attr *attr,
                   const struct rte_flow_item pattern[],
                   const struct rte_flow_action actions[],


        其 classify 逻辑的执行,也完全是由 DPDK app 显式地调用 API:

                    rte_flow_classifier_query() 

        来进行的。 --- 在 SW-level 执行。


        它 到底是做什么用的呢?

            The initial implementation supports counting of IPv4 5-tuple packets which match a particular Flow rule only.

            --- 也就是说,当前的功能,只是:  在 SW-level,对 匹配 flow match patterns 的 packets,进行 counting。 --- 统计计数而已。
                

---------------------------------------------------------------------------------------------------------------

===============================================================================================================

@@@ #3. 对于 DPDK 的 spinlock / rwlock 和 RCU


---------------------------------------------------------------------------------------------------------------

spinlock / rwlock


    Linux kernel 的 API 是:

        spin_lock() / spin_unlock()
        spin_lock_bh() / spin_unlock_bh()
        spin_lock_irqsave() / spin_unlock_irqrestore()


    而 DPDK API 只是:

        rte_spinlock_lock() / rte_spinlock_unlock()

    他们内部都是 使用 CPU 的 atomic_compare_exchange ( CAS ) instructions 来实现的。
    
    不过,Linux 会 关闭 preemption / bh / irq。


    但 DPDK locking 为什么不在意 preemption / bh / irq ?


        #1. 因为 DPDK 是 user-level programming,没有 bh。

            至于 irq .... DPDK 也关闭了 NIC 的 rx-tx irq,只是进行 polling。

        #2. 至于 preemption ..... 和 DPDK 的 lcore (__或者说 multi-thread model )定义有关。


            一个 DPDK application,只允许,一个 CPU core 运行一个 thread。

            不会有 2 个 DPDK thread 运行在同一个 CPU 上的情况。


            --- 以上限制,是由 DPDK EAL layer,在代码上施加的(__通过 pthread_set_affinity() )。


---------------------------------------------------------------------------------------------------------------

RCU


    Linux kernel RCU 的 quiescent state 的条件是:            # 不精确,但大致是这样理解。


        所有 CPU 都返回 user-level 一次。    # 这样,所有CPU 原本的 kernel-level stack 都被“清空”了。
                                            #
                                            # 再进入 kernel-level 的 代码,是无法从 kernel-level stack 中
                                            # 或者 kernel list/hlist 等datastructure 中,再获得 
                                            # 需要RCU defered free 的 数据的 “指针引用”。
                                            #


        然后,RCU 的 defered free,会自动由 RCU layer 来进行。


        所以,并不需要 kernel code,自己来检查和“报告” RCU quiescent state。

    而 DPDK RCU,需要 application 本身来调用 DPDK RCU API,来 检查和“报告” RCU quiescent state。


    所以,会比 Linux kernel RCU 的用法,麻烦和绕一些(__很多)。


---------------------------------------------------------------------------------------------------------------

===============================================================================================================
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值