【1】SSO模块提供这些功能:
1、work队列
2、work 调度/反调度
3、对work的排序和同步
【2】work队列
work由一个相关的,可能由硬件单元或core软件创建的work队列节点描述,CN68XX在每一个包到来时集中地使用packet-input硬件单元来创建work队列节点并提交。core软件也可以创建和提交work队列节点给SSO;PKO,PCIe,Timer,和HFA这些硬件单元也可以在执行完自己的处理流程之后把work队列节点提交给SSO
SSO实现了8个 input work 队列,这8个不同的队列提供不同的服务等级QoS,SSO硬件在这些队列的实现中提供了静态的和轮寻加权的处理方法。
input work队列可以无限大,可以比DRAM还大,当DRAM溢出,RWQ就会过来处理,SSO使用FPA pool 8 来自动的管理,申请,返回RWQ,软件负责初始化申请RWQ。
【3】work调度/反调度
core软件向SSO请求work,SSO为发出请求的core选择work,并返回关于选定work的work队列节点指针给core软件,这样节省了很多资源开销
SSO硬件支持64个内核组,每一组都有一个特殊的标记,每一个core在请求woek的时候都会有一个配置组的属性变量,SSO硬件不会将含有A组属性的work调度给不含有A组属性的core
组提供了一个让不同的核执行不同任务的方法,因为所有的core共享一个SSO,例如一个包处理流程的不同阶段,一组core处理完本阶段任务,就会通过管道将包输送给另一组core执行个阶段
一个core可以将包打回给SSO(deschedule),core当前不处理这个work,把这个work打回给SSO,SSO以后再调度这个work ,SSO会将调度desheduled的包的优先级调整到高于调度一个新包的优先级,deschedule会在以下几种状态下有效:
1 可以将work从一组core传递到另一组core,这是一种work管道的实现方式
2 可以防止长时间的同步延时
3 It can make work interruptible.
【4】排序和同步
SSO硬件会将每一个包与一个tag value和 tag type 关联,work队列节点对一个input work 队列的添加work 请求中会包含initial tag tuple(这个initial tag tuple可以由硬件生成,也可由core软件生成),core软件可以在对这个work执行不同的步骤时切换这个tag tuple,用 tag switch方法,如果两个包有相同的tag tuple,则这两个包是保序的。
有三种tag type
1 oedered:保证顺序
2 atomic: 不仅保证顺序,还保证原子性,有相同atomic tag tuple的两个包不能同时被调度
3 unshcheduled:不保证顺序,追求极速的混乱状态
SSO硬件,配合core软件 ,用tag tuple来对相应的work进行排序和同步,且允许无关的work可以不保序和不同步,这对于执行多核功能是有帮助的,两个共享相同tag tuple的包会被保序和同步,反之不保序,不同步。
例如,tag value 可能是五元组的哈系值,同一流应当有相同tag value,所以它们会被保序,多个流有不同的tag value,则它们会被多个核平行处理,并且流与流之间不保序,同一流之间保序。
在不同的处理流程上,core软件可以改变tag tuple
【5】流,处理流程,保序
7-1显 示了一个抽象的图片来描述SSO单元,关注work在SSO流中的每一个阶段的状态,core可以传送work,通常, work流是这样的处理状态:
work先进入input 队列,然后进入 in-flight队列,最后deschedule或者completed
在input 队列中的时候,执行GET WORK动作进入 in-flight队列,在in-flight队列中执行GET-WORK动作,SSO收到请求后执行schedule动作把work调度给core 处理,core可以选择执行deschedule动作不处理SSO并将work打回给SSO。
在任何给定的时间点上,只有一个work可以同时被调度给core(因为我们只有一个SSO),已经调度的work数量取决于一共有多少个core,core在执行完deschedule动作或者完成schedule动作之后没有请求新work的时候是空闲的,已调度的work是in-flight队列的子集(正在处理的work是已调度的work,其实work在core中进行处理的时候,其实体还是存放在in-flight队列里,只不过标识是否被调度的状态位被标为已调度)
任何一个core都可以deschedule一个work,descheduled状态的work继续存放在in-flight队列里,过一会就会被重新调度,但是不会马上被core处理,schedule状态的work会一直保持schedule状态,直到完成tag switch转换(SWTAG),除非要转换到的tag type是混乱的unscheduled,如果下一个tag type是deschedule,则core会马上让work的状态变成descheduled,7-1把SWTAG抽象成一个单箭头,deschedule流程可以发生在SWTAG之后和SWTAG完成之前。
work通过一个input队列进入SSO单元,7-1顶部画出了input队列,SSO单元内部节点包括input队列中的节点和in-flight队列节点,硬件和软件都可以向input队列中添加节点,虽然SSO内部单元个数是有限的,SSO硬件还会在耗尽所有内部单元后继续接收work,这是就会将接收到的work放到RWQ存储链表上,RWQ存储链表上的work节点会在稍后自动的写入SSO内部单元。
当core发出GET-WORK请求的时候,work会被调度到一个core,SSO会用调度一个work给core响应这种请求,SSO硬件也可以调度descheduled状态的work作为GET WORK的响应,SSO会认为descheduled状态的work优先级高于unscheduled状态的work,除了指定索引的GET WORK动作,SSO不会调度一个正在执行tag switch的descheduled状态的work,并且不会调度一个不能立即获得atomic锁的atomic类型的在input队列中的work。简言之,SSO调度器只能调度立即有效的work,在input 队列中 状态为unscheduled的work是一种特殊情况,SSO硬件会在接到GET WORK的请求后立即反调度这种work。
work在一个unscheduled的core执行SWTAG_FULL动作时进入SSO单元,则用这种方式进入SSO单元的work会被立即调度,且与其他scheduled状态的work没有区别(可能是后悔unscheduled了,其实也就是切换了个状态,core把位于in-flight队列中work的unscheduled状态切换到最高优先级的scheduled状态)
保序问题:
首先,如果work在一个input队列,SSO会严格保证其在每一个input队列的入接口顺序
其次,当work在in-flight队列,unschedule状态,顺序严格按照tag tuple划分并保证,SSO不会对有不同tag tuple的work执行强制任何保序或同步,这样的in-flight work是可以被多核平行处理的。
work中的组标识不会影响到in-flight 中work的顺序
第三,当work既位于input队列,又位于SSO内部单元(处于input队列存储空间和in-fligh 队列),则work的顺序是混乱的,SSO的work调度器硬件会跳过不能立即被调度的input-queue节点,SSO调度器永远不会跳过ORDERED和UNSCHEDULED类型的input-queue work节点,SSO调度器会严格按照入接口顺序来调度ORDERED和UNSCHEDULED类型的work,SSO调度器会跳过带有ATOMIC类型并且不能被立即调度的work,所以SSO可以保证input-queue中的ATOMIC类型work的tag 顺序,SSO也会跳过属于不被调度的组的work,所以在不同组之间的work节点是不被保序的,unscheduled的work是不会被SSO硬件同步的,所以彻底不保序。
SSO硬件通过tag switch来保序,每一个in-flight状态的work都会进行一系列相同的tag switch操作,因为in-flight中的work会在每一次tag switch操作时进行相同的排序,借助适当的配置和软件支持,SSO可以保证一个流中的所有work的顺序,CN68XX提供了对于一个流的所有work保序的支持,只要下列配置生效:
(1)所有属于同一个流的包在进入SSO时是进入到同一个input-queue,携带相同的tag value,属于相同的组,
(2)软件在对属于同一个流的包进行处理的时候,不执行切换为UNSCHEDULED状态的 tag switches
SSO的core状态和影响核状态的因素:
一个core接收到一个work,这个work携带的tag type是什么,则core的状态就被设置成什么,例work中type是ORDERED,则接收这个work的core的状态也是ORDERED。
【我的理解】每一个core都有4种状态,ORDERED ATOMIC UNSHEDULED EMPTY
SSO的ADD_WQ 和NOP命令不会影响到SSO的core状态,这两个操作在任何情况下都是合法的
SSO中应该有三条队列,分别对应三种tag_type,一个wqe可能在这三条队列中的其中一条上,然后core来处理这个队列上的这个wqe节点,这个wqe节点携带哪个tag_type,core的状态就被设置为哪个type,如果一个core中没有任何wqe在处理,则core的type就是EMPTY
【】POW操作(这里的POW等同于SSO)
ADDWQ(tag_type,tag , wqp, grp, qos):添加work到被QoS选中的输入队列,函数中的参数值必须匹配,不然POW硬件就会产生不可预测的结果;因为输入工作队列是无限大的所以此操作永远不会失败。
GET_WORK(wait):core请求获得work,如果不能为core找的work那么POW硬件会返回一个错误的结果;如果成功为core找到work就会返回一个指向work队列节点的指针。
NULL_RD:将core POW的状态为NULL_NULL状态转变为NULL状态;当将core POW的状态不是NULL_NULL状态优先于NULL_RD,将不会改变当前状态;在执行NULL_RD函数后返回的结果是NULL_NULL,说明操作失败。
SWTAG(new_tag_type, new_tag):执行tag switch操作;当POW硬件清除完为core挂起的switch bit后就会完成tag switch 操作;SWTAG为NULL时,则此操作不会执行。
SWTAG_FULL(new_tag_type, new_tag, new_wqp, new_grp) :操作与SWTAG操作一致,只是会为包含在POW中的工作另外更新工作队列指针和四位组标识符(new_grp),从空状态开始的所有交换机都必须使用swtag_full。POW硬件从不解释或使用此事务中提供的工作队列指针,但它可能稍后将其传递给软件以完成获取工作;POW硬件存储工作队列指针的<35:3>。swtag_full不能用于切换为空。
DESCHED(nosched):这将执行一个预定事务。当nossed位设置为desched(或swtag_desched)操作时,在随后的clr_nsched操作清除pow条目的nossed位之前,pow硬件不会将数据包调度到核心。POW条目可以在描述之前使用get_cur=1的POW状态加载来确定(参考第7.11.1节)。<50:40>中的索引字段标识POW ID。
请注意,建议在描述时核心处于原子状态,而不是有序状态(参见第7.9节)。如果在描述中设置了nosched,并且如果软件以某种方式通知其他核心POW条目现在在描述列表中,软件应首先在通知其他核心之前等待DESCHED完成。(如果没有这条规则,由不同的核心发起的clr-nsched可以完成,而不会在预定列表中看到pow条目,也不会看到pow条目中设置的nosched位,即使另一个核心在明确通知pow e后启动clr-nsched。NTRY已预定。)软件可以通过GET_cur==0 POW状态加载的Pend_Desched位确定何时完成描述(有关POW状态加载的详细信息,请参阅第7.8节和第7.11.1节)。
SWTAG_DESCHED(new_tag_type,new_tag,new_grp,nosched):这与swtag后面跟着描述的DESCHED相同,只是它还更新了组。它必须遵循与单独的swtag/desced组合相同的所有规则。它必须遵循与swtag相同的启动规则(如图7-2所示)。新的_tag_type参数不能为空。SWTAG描述非常适合将工作从一个组转移到另一个组-工作流水线.
UPD_WQP_GRP (new_wqp, new_grp):为包含在POW内的工作更新工作队列指针(new_wqp)和组标识符(ner_grp).
CLR_NSCHED (wqp, index):为POW节点清除被选中在目录里的nosched bit
NOP: No Operation。