前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >硬件开源,始于FPGA,走向P4可编程PISA

硬件开源,始于FPGA,走向P4可编程PISA

作者头像
用户6874558
发布2023-02-15 15:59:27
1.4K0
发布2023-02-15 15:59:27
举报

本文是杨翔瑞老师工作小结。杨老师的工作成果在:智能网卡大黑马抛出第一块砖~ 也有提及。

这篇工作小结其实早就该写了,只是手头的事情一直比较杂(项目、比赛、大论文、找工作......)加上自己多年习得的拖延症加持,直到NSDI都开会了才动笔,也算给Menshen工作做个自我宣传。

这篇小结是什么?

这篇blog的目的是为简要介绍2020-2021年我在参与NYU的一个项目时所开发的面向Xilinx FPGA并支持P4编程的RMT/PISA硬件流水线,这个开源流水线的512b版本可在Ultrascale+系列FPGA约束到250MHz, 256b的版本可在Virtex7系列FPGA上约束到200MHz,目前这个流水线也作为了Menshen[1](发表于NSDI 2022)的硬件主体设计。

这篇小结不是什么?

这篇工作尽量不去涉及Menshen的软件端(P4C编译器修改)以及Menshen所提供的多租户特性,这些工作是由Wang Tao同学主导的(我主要专注于FPGA端的设计与开发)大家可以看我们发表在NSDI2022的那篇工作。然而,由于当时拉我做RMT的原因就是为了支持Menshen这个项目,因此,部分支持多租户的设计已经不可避免地嵌入了硬件设计当中。

背景

其实第一次了解RMT(Reconfigurable Match Table Architecture)[2]是在2018年导师的研讨课上,但是由于各种原因没有follow这个工作。2020年在伦敦隔离期间联培外导突然问我愿不愿意做一个跟P4有关的硬件工作,大概意思是说NYU那边团队想要做,然而没有任何FPGA开发的基础,如果我愿意加入的话可能会是一个很酷的工作。刚开始其实是拒绝的(因为各种原因一直对P4持比较否定的态度哈哈),结果第一次开会时这个项目的PI(NYU的Anirudh,PIFO的一作)说是要复现RMT SIGCOMM2013的那篇工作,我向来喜欢做复现的工作,于是毫不犹豫答应了。

具体设计与开发工作大概从20年8月下旬回国隔离开始,当时白天除了测核酸就是睡大觉,晚上夜深人静无人打扰开始起床开始写Design Doc,大概一周之后开始撸verilog),到21年1月第一版上板逻辑与时序通过(当时用了Xilinx的AU250的卡,后来给多种卡做了兼容),并且与P4C编译器联调通过,大约用了5个月的时间。当然,当时的初版虽然能够支持P4大部分语法,但仍有一些小的bug:比如个别长度的报文进到流水线输出时被改变长度;某些流水级的加法指令不生效之类的。后来陆陆续续进行了一些bug fix工作。因此现在的版本已经相对完善。

为什么需要一个开源RMT的FPGA实现?

言归正传,那为什么要做一个开源的RMT?熟悉P4的童鞋们都知道,虽然目前商用Intel Tofino交换机能够几乎完全支持P4,但是其硬件架构是闭源的而且严格保密。很早以前组里就讨论过:P4的关键是它的底层硬件设计如果交换机/网卡无法支持将P4规则映射到芯片,那P4语言就是无米之炊。后来,大家为了脱离tofino做research,赛灵思和斯坦福搞出了P4NetFPGA。乍一看P4NetFPGA是一个跟我们的开源RMT很像的工作,然而事实并不是这样。P4NetFPGA的工作流程如下图所示:

P4NetFPGA工作流程

The P4NetFPGA Workflow for Line-Rate Packet Processing (sibanez12.github.io)

很明显,P4NetFPGA跟RMT/PISA架构没有任何关系,这个项目实际上是通过打通P4→SDNet→verilog流程的方式支持的P4,也就是说每次编译P4,都会生成新的verilog代码,并且需要重新走FPGA的综合、布局布线、产生bit流以及加载到FPGA的全流程,是一种compile-time的方案,因此也就无法对研究支持P4的芯片架构提供任何帮助。另外支持P4的就是软件的BMV2[3],虽然没有了解BMV2的实现,但是软件和硬件的数据平面有着巨大鸿沟,无法支撑SW/HW的系统研究。

综上,若能够提供一种面向FPGA的开源RMT实现,那么就能够很好地支持大家对可编程网络核心技术的研究,从而不是仅仅使用P4语言在人家规定的圈子里玩。因此这些当时的现状就motivate了这个工作。

RMT基本特点

1.自定义协议解析

RMT提出的时间其实较早,在2013年就发表在SIGCOMM上。当时的背景是SDN与OpenFlow大火,而作为OpenFlow的提出者Stanford大学的Nick Mckeown团队则发现了OpenFlow在承载SDN的关键弊病:无法支持自定义协议的解析。这里的问题主要是解析器Parser的设计。因此RMT提出了将OpenFlow中Match-Action的抽象应用到报文协议解析中,支持自定义的协议解析。粗略地说,RMT中的parser是通过match-action逐步提取报文的前4096b中的有效字段,并循环压入报文头向量(PHV)中来实现协议解析的。如此,用户可通过配置不同的match-action表项实现自定义的协议字段提取。

2. 更加复杂的动作执行引擎

现在有很多人用P4做除了网络转发以外的各种工作,比如网络遥测(INT[4]),拥塞控制(如HPCC[5]),KVS(NetCache[6]等)还有机器学习训练的网内聚合(Omnireduce[7])等等。其原因就是RMT架构拥有一个能力爆棚的Action Engine。不同于OpenFlow, RMT中PHV匹配到的action不是一个单独的动作,而是一个采用超长指令字(VLIW)并包含几百个(200个)子指令的“动作集”。这些动作指令包括替换、逻辑运算、算数运算以及访存(这里访问的是Switch和NIC内部的Memory)等,可以支持对PHV采取各种各样的操作。而action engine内部通过VLIW指令控制的,并与PHV全域字段互联的crossbar则允许action engine在单stage可对PHV所有字段完成一次修改。

3. 支持跨stage使用table资源

RMT论文的2.1.2的部分描述了如何将物理的SRAM/TCAM等资源与逻辑流水级解耦,作者把这个能力叫做Flexible match table configuration(如下图所示)。听起来确实是个很好的技术:一旦允许网络数据平面可编程,那么每个流水级到底是做IPv4的最长前缀匹配还是做机器学习训练的加法运算是不一定的,如果table width可以灵活配置,那就能节省很多的SRAM/TCAM资源。然而,实话实说,这部分内容应当如何映射为硬件设计我始终没有想明白(若有童鞋知道,欢迎拍我!)。这也是我所设计的开源RMT流水线没有支持这个feature的原因。当然,类似SRAM/TCAM共享的技术也可以通过dRMT类似的方法实现。

RMT论文中对跨stage的table资源共享的示意图

简化版verilog开源RMT流水线

我这个简化版的RMT流水线整体架构与SIGCOMM13的RMT架构几乎相同,整体架构和数据流如图所示(虽然现版本README中Wang Tao同学重新refine了图,不过个人还是觉得之前我画的这个丑图更容易理解):

2020年8月在进行第一版设计时我所做的丑图

图中上半部分是流水线架构,下半部分是各级对应的data flow。Parser用于产生包含头部关键field container与metadata在内的PHV。Key Extractor则从PHV中提取出用于匹配规则的关键字(Key),图中省略掉的是Key Extractor实际上还会根据VLAN ID产生与Key对应的Key Mask,从而在后续Lookup Engine中支持带掩码的匹配操作。在Lookup Engine中, Key|Key_Mask则通过CAM查表获取对应的动作指令(基于超长指令字的action)。接下来,PHV与action将进入Action Engine,在这里,action将会对PHV进行修改,并构造出新的PHV。而Key Extractor,Lookup Engine与Action Engine则构成一级完整的Stage,多个Stage串联构成了整条流水线的核心部分。当结束所有处理后,PHV到达Deparser模块,Deparser将会从Data Cache中读取报文体,并与Parser遵循对应的规则将PHV字段写回报文头部,并输出流水线。

另外,图中data flow部分也标注了流水线中相应数据结构的位宽和简要构成。具体如下:

1.报文头向量(PHV)

PHV的总长为1024b,其中包括24个位宽分别为2B,4B与6B的头部关键字段各8个,以及宽度为256b的metadata信息,即|8x6B|8x4B|8x2B|256b|共计1024b。而metadata除了在低128b复用了NetFPGA的axis_tuser以外,还增加了部分字段定义:

[255:141]:保留字段;

[140:129]:当前报文的VLAN_ID,这个主要用于支持Parser/Deparser与Key Extractor模块中查表;

[128]:当前报文的丢弃位,若为1,则当前报文则会在输出时被丢弃。

2. 查表关键字(Key)

使用宽度为1024b的PHV直接进行查表显然在FPGA上几乎是不可能的,尤其考虑到我们还使用了CAM IP核作为查表引擎。因此,该版本的RMT里增加了Key Extractor的Key提取逻辑(表项格式如下图所示,索引位宽为

=3b),对Key进行瘦身:Key中实际只包含了|2x6B|2x4B|2x2B|共计6个container(后面还携带了20b的if-else指令)。而在Key Extractor中与Key同步产生的等位宽Key Mask与CAM查表引擎配合则能够支持任意位宽的匹配操作。

Key Extractor中Key Extract规则格式图,simple but efficient。

3. 动作指令(Action)

RMT中查表得到的action是采用超长指令字组织的,每个action包含25条位宽为25b的子指令。目前的版本中支持:寄存器加减法,立即数加减法,逻辑运算以及针对stateful table的访存操作等共计7类通用指令,另外还增加了作用于metadata,用于丢弃报文或改变转发端口的2类专用指令。如图所示,opcode位宽为4b,因此还能够再增加最多7类指令。这里我犯了一个非常反人类的错误把子指令设计成了25b这样一种奇葩的位宽= =。当时在设计指令格式时只考虑了尽可能节省SRAM资源占用,而没有考虑后续调试(OS一般以字节为最小单位)以及扩展的(RISC-V兼容设计)便捷性。(想起一个好笑的事:之前有个朋友问我做的这个流水线能不能兼容RISC-V指令,我当场就乐了:“连指令码宽度都不一样怎么兼容哈哈哈哈哈哈”)。

言归正传,寄存器类指令的操作数采用5b表示:高2b表示container的类型(6B/4B/2B),低3b表示container在PHV对应类型containers中的index(0~7)。立即数类和访存类指令则直接将指令的低16b作为立即数值或者访存地址。针对metadata的指令就是图中的第三类,跟NetFPGA的metadata(axis_tuser字段)格式紧耦合。

起初设计文档中对action指令类型的描述。当时只有8类指令,后来在Menshen项目要求下增加了一类用于实现网内分布式同步算法的`loadd`指令。

当时我设计的action子指令格式设计(目前仍在Menshen中应用),非常失败地采用了与任何指令都不兼容并且难以与软件联调的25b指令位宽。

模块小记

与RMT相同的地方就不说了,大家可以阅读SIGCOMM13那篇工作以及我们的代码。下面简要介绍一下与RMT不同和自己感觉有趣的地方。

1.静态Parsing Table

为了简化设计,Parser进行的是全静态解析。简单来说,Parser中仅有一个Parsing Table,每个表项宽度为160b,包含10组宽度为16b的parsing action。每个parsing action中包含了有效位,PHV中container索引,报文头中起始偏移,以及container类型(2B/4B/6B)。这种简化消除了每个PHV container提取时互相之间的依赖关系(killer of parallelization),保证N个cycle内能够并行地提取出所有的container并生成PHV。(btw, 今天读到了清华和futurewei同样发表在今年 NSDI的IPSA架构,采用了一种灵活的分布式parser设计,也是蛮有趣,不过motivation不同)。

2. Action Engine设计

Action Engine中丰富的指令以及灵活的计算模式是P4在网内计算中受到欢迎的原因之一。由于自己之前未从事过CPU相关的设计,因此这部分的设计推倒重来了好几次。但现在总结起来,Action Engine的设计就是两个部分:1)一个可以根据指令的指令操作数灵活、并行提取PHV字段的Crossbar与2)N组用于进行计算并产生PHV字段的ALU单元。RMT论文中的图1(c)非常精确地表述了这个设计,我在开发Action Engine时所做的也就是将这个架构翻译成了verilog。当然,为了支持Menshen,我们在此基础上增加了一些类似页表一样的隔离机制。

经典RMT论文中Action Engine设计,我采用了与其几乎完全相同的设计(除了为了简洁起见,将VLIW Instruction Memory放在了Lookup Engine)。

我copy的Action Engine的设计,与RMT的设计图对照可发现几乎一致。其中page table和vlan_id是用于menshen的租户隔离功能的,此处可以忽略。

3. 控制通路设计

RMT论文中没有描述用于表项配置的控制通路设计,在数据平面开发接近完成时,我们在weekly meeting中开始讨论控制通路的设计。当时可选的也就为两种方式:通过AXI/AXI-lite协议对各个表项进行配置,或者通过在以太网报文基础上通过类似总线模式进行配置。FAST[8]项目的经历以及RMT中多达20多种宽度/深度各异的表让我坚决地选择了具有较好兼容性的后者,并且花了十多天的时间设计并完成了基于UDP报文的控制通路协议。

控制通路的原理非常简单,几乎就是FAST控制通路设计的翻版:将所需配置的表项内容封装在UDP报文中,并且通过特定的UDP端口号将其标记为控制报文(0xf1f2)。而控制报文在进入流水线之后将会被识别并被dispatch到用于表项配置的控制通路。剩下的过程与FAST中相同,首先通过module ID索引到对应的模块,然后通过entry index对模块表项的内容进行修改。当然,我在实现中还考虑了比如支持批量修改、多表在同模块共存等情况,不过原理大致如此。

控制报文格式。采用UDP报文进行封装,并使用0xf1f2作为目的端口号用于标记报文类型。

后记

  1. 时序问题:开发过程中遇到的最大的问题就是时序。我所采用的时钟是PCIe的250MHz usr_clk,时钟周期只有4ns,而Deparser模块由于wire较多而且互联关系复杂,经常时序爆炸。当时绞尽脑汁尝试了各种优化和代码重构方法才最后勉强把逻辑成功约束到了250MHz。欢迎有相关经验的童鞋多多指导交流。
  2. 性能测试:性能请参考arxiv[9]上的性能结果图。21年下半年Wang Tao同学对我的设计进行了优化,因此Menshen的official版本现在已经基本达到了100Gbps(>128B)线速的处理能力,延迟大约为1.25us以内。因此还是不错的。
  3. 后期改进:还是要强调一下由于个人时间和能力的限制,这里的RMT依然是一个非常初级的版本,与Tofino之类的商用芯片无法相提并论。但是个人认为自己做的这个工作是有一点点意义的,至少让人们有了一个可以进行研究的底座,自己也打算在此基础上继续完善。若有童鞋有一些对RMT设计进行增量开发(比如重构Parser,共享stateful table, 增加可编程调度器…)
  4. 代码版本:我们的原始的dev历史与code在这里,Wang Tao同学refine后重新上传并支持Menshen的版本在这里,欢迎大家关注。若是觉得不错,也希望可以为我们增加一颗宝贵的star :)

参考资料:

1.https://www.usenix.org/system/files/nsdi22-paper-wang_tao.pdf

2.https://conferences.sigcomm.org/sigcomm/2013/papers/sigcomm/p99.pdf

3.https://github.com/p4lang/behavioral-model

4.https://p4.org/p4-spec/docs/INT_v2_1.pdf

5.https://dl.acm.org/doi/pdf/10.1145/3341302.3342085

6.https://opennetworking.org/wp-content/uploads/2020/12/p4-ws-2017-netcache.pdf

7.https://sands.kaust.edu.sa/project/omnireduce/

8.https://dl.acm.org/doi/10.1145/3326285.3329067

9.https://arxiv.org/pdf/2101.12691v2.pdf

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深知网络 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这篇小结是什么?
  • 这篇小结不是什么?
    • 这篇工作尽量不去涉及Menshen的软件端(P4C编译器修改)以及Menshen所提供的多租户特性,这些工作是由Wang Tao同学主导的(我主要专注于FPGA端的设计与开发)大家可以看我们发表在NSDI2022的那篇工作。然而,由于当时拉我做RMT的原因就是为了支持Menshen这个项目,因此,部分支持多租户的设计已经不可避免地嵌入了硬件设计当中。
      • 为什么需要一个开源RMT的FPGA实现?
        • RMT基本特点
          • 简化版verilog开源RMT流水线
            • 后记
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档