3.2 CXL.cache
3.2.1 概覽
CXL.cache協議將設備和主機之間的交互定義為多個請求,每個請求至少有一條相關的響應消息,有時還有數據傳輸。該接口在每個方向上由三個通道組成:請求(Request)、響應(Response)和數據(Data)。通道按其方向命名,D2H表示設備到主機,H2D表示主機到設備。
D2H請求通道,將新請求從設備傳送到主機。請求通常以內存為目標。每個請求將收到0、1或2個響應,和最多一個64字節的緩存行。通道可以反壓(Back Pressure)。
D2H響應通道,將設備的所有響應傳送到主機。設備對監聽的響應返回該緩存行在設備緩存中的狀態,并可能表示數據正返回到主機提供的數據緩沖區。對于鏈路層信用,它們可能仍會被暫時阻止,但不應要求完成任何其他交易來釋放信用。
D2H數據通道,將所有數據和字節啟用從設備傳輸到主機。數據傳輸可以是隱式(由于監聽)或顯式寫回(由于緩存容量而導致的“逐出”)的結果。在所有情況下,都將傳輸完整的64字節緩存行。D2H數據傳輸必須進行,否則可能會出現死鎖。它們可能會因鏈路層信用暫時被阻止,但不得要求完成任何其他交易來釋放信用。
H2D請求通道,將請求從主機傳送到設備。這些請求都是為保持一致性的監聽。可能會返回數據,請求攜帶數據緩沖區的位置,任何返回數據都應寫入該緩沖區。
H2D響應通道,攜帶排序消息并提取寫入數據。每個響應都攜帶來自原始設備請求的請求標識符,以指示響應應該路由到哪里。
H2D數據通道,為設備讀取請求提供數據。在所有情況下,都將傳輸完整的64字節緩存行。
3.2.2 CXL.cache通道描述
通常,所有CXL.cache通道都必須彼此獨立工作。然而,有一個特例,為了保證正確性,必須維護通道之間的順序。主機需要等待設備觀察到H2D響應上發送的全局排序(GlobalOrdering,GO)消息,然后再發送相同地址的后續監聽。為了限制跟蹤GO消息所需的緩沖量,主機保證通過CXL.cache發送的GO消息后,在一定周期內不能再發送的監聽。
每個通道都必須使用信用來發送任何消息,并從接收方收集信用返回。在操作過程中,每當接收器處理完消息后,它都會返回一個信用。如果沒有可用的信用,發送方必須等待接收方返回信用。下表描述了哪些通道必須被排空才能繼續,哪些通道可以無限期阻塞。
3.2.3 CXL.cache寫描述
CXL.cache每個通道消息的字段定義如下。
3.2.3.1 D2H請求
關于Opcode,后面的章節會詳細描述這些D2H請求。
3.2.3.2 D2H響應
3.2.3.3 D2H數據
3.2.3.4 H2D請求
3.2.3.5 H2D響應
3.2.3.6 H2D數據
3.2.4 CXL.cache事務描述
3.2.4.1 D2H請求
D2H請求,有四種語義:CXL.cacheRead,CXL.cache Read0,CXL.cacheRead0/Write,CXL.cache Write。
CXL.cache Read
CXL.cache Read需要D2H請求信用,在D2H CXL.cache請求通道上發送請求消息。CXL.cache Read請求需要0或1條響應(GO)消息和64字節緩存行的數據信息。響應(如果存在)和數據消息都指向初始D2H請求分組的CQID字段中提供的設備跟蹤器條目。在收到來自主機的所有消息之前,設備條目必須保持活動狀態。為確保向前進度,設備必須具有保留的數據緩沖區,以便在發送請求后能夠立即接受所有64字節的數據。但是,由于先前的數據返回沒有排出,設備可能暫時無法接受來自主機的數據。一旦從主機接收到響應消息和數據消息,就可以認為事務已完成,并且條目已從設備中解除分配。
下圖顯示了CXL.cache Read的過程。需注意,響應(GO)消息可以在數據消息之前、之后或之間接收。
CXL.cache Read0
CXL.cache Read0接受響應消息,但是沒有數據消息。響應消息指向初始D2H請求消息的CQID值中指示的設備條目。一旦收到這些請求的GO消息,就可以認為它們已完成,并且條目已從設備中解除分配。主機不得為這些事務發送數據消息。
CXL.cache Write
CXL.cache Write需要D2H請求信用。主機收到請求消息后,需要發送兩條單獨的或一條合并的GO-I和WritePull消息。GO消息絕不能在WritePull之前到達設備,但它可以在組合消息中到達。如果事務是posted類型的寫,那么合并的回復消息類型更能派上用場。如果是non-posted類型的寫,host需要先發GO-I消息,再發WritePull消息。
下圖顯示了完成CXL.cache Write事務的過程,WritePull消息觸發數據消息。
下圖顯示了WritePull是來自GO的單獨消息的情況(強序不可緩存寫請求)。
下圖顯示了主機FastGO和ExtCmp的響應(弱序寫請求)。
至于什么是強序,弱序,就不解釋了。
CXL.cache Read0-Write
CXL.cache Read0-Write需要D2H請求信用。WritePull消息會觸發設備發出64-byte數據給主機。一旦設備接收到GO-I消息并發送了所有所需的數據消息,則認為CXL.cache Read0-Wrtie事務已完成。此時,可以從設備中釋放條目。主機在接收到所有64字節的數據并發送GO-I響應消息后,會認為Read0-Write結束。
D2H請求的opcode如下:
RdCurr:這些是來自設備的完整緩存行讀取請求,以獲取最新數據,但不會更改任何緩存(包括主機)中的現有狀態。主機不需要跟蹤發出RdCurr的設備中的緩存行。RdCurr獲取數據,但無法占有。設備接收到處于無效狀態的行,這意味著它只能使用一次該行,無法緩存該行。
RdOwn:來自設備的完整緩存行讀取請求,用于緩存處于任何可寫(writable)狀態的行。通常,RdOwn請求接收處于Exclusive(GO-E)或Modified(GO-M)狀態的行。處于Modified狀態的緩存行,必須將其寫回主機。在錯誤情況下,RdOwn請求可能會收到處于Invalid(GO-I)或Error(GO-Err)狀態的行。兩者都將返回全是1的數據。設備負責處理錯誤。
RdShared:設備發起讀取完整緩存行的請求,用于緩存處于Shared狀態的行。通常,RdShared請求接收處于共享(GO-S)狀態的行。在錯誤情況下,RdShared請求可能會收到處于Invalid(GO-I)或Error(GO-Err)狀態的行。兩者都將返回全是1的數據。設備負責處理錯誤。
RdAny:備發起讀、讀取完整緩存行的請求,用于緩存處于任何狀態的行。在錯誤情況下,RdAny請求可能會收到處于Invalid(GO-I)或Error(GO-Err)狀態的行。兩者都將返回全是1的數據。設備負責處理錯誤。
RdOwnNoData:設備向指定的緩存行地址發起該請求,目的是擁有獨占的權限。在錯誤情況下,RdOwnNoData請求可能會收到處于Error(GO-Err)狀態的行。設備負責處理錯誤。
ItoMWr:設備對指定的緩存行地址發起獨占權限請求,并以原子方式將緩存行寫回主機。由于設備會將整個緩存行的數據都修改掉,所以不需要主機將該緩存行數據發給設備。當主機給了請求該緩存行的獨占權限后,設備會回復響應消息GO-I-WritePull。設備不需要再保留寫回的數據。如果錯誤發生,設備回復GO-Err-WritePull,主機丟棄設備寫回的數據。設備處理該錯誤。
MemWr:與ItoMWr有些類似,但是寫回數據的位置可能不同。只有當命令命中緩存時,數據才會寫入其中;如果未命中,數據將直接寫入內存。一旦請求被授予所有權,典型的響應就是GO-I-WritePull。設備不保留該行的副本。如果錯誤發生,設備回復GO-Err-WritePull,主機丟棄設備寫回的數據。設備處理該錯誤。
ClFlush:設備發起請求,無效掉指定地址的緩存行。主機返回的典型響應是GO-I。
CleanEvict:設備發送請求給主機,要求evict一條64-byte的Exclusive緩存行。該請求會收到GO-WritePull或GO-WritePullDrop類型的響應消息。不論設備收到哪種響應消息,都必須放棄對該緩存行的監聽所有權限。如果收到的是GO-WritePull,那么設備將數據發送給主機,如果是GO-WritePullDrop,那么主機直接將該組數據丟棄。
DirtyEvict:設備發送請求給主機,要求evict一條64-byte的Modified緩存行。請求發出后,應該收到的響應消息是GO-WritePull,這也意味著device對該緩存行失去了監聽所有權,并需要將數據發送出去。一旦設備發起了這樣的一個請求,并且在設備接收到GO-WritePul或GO-WritePullDrop響應消息前,訪問的緩存地址已經被監聽了,這時候,設備需要設置數據消息的Bogus字段,用來指示這個數據也許不是最新的。當有錯誤出現,主機回復GO-Err-WritePull,這個時候設備寫回的數據會被主機丟棄掉。設備負責處理錯誤。
CleanEvictNoData:設備發起請求給主機,以便在設備中刪除一條干凈的緩存行。此請求的唯一目的是更新主機中的監聽過濾器(snoop filter),并且不會交換任何數據。只有在主機掛載內存的地址范圍內,才需要CleanRecictNodeData。對于設備掛載內存的地址范圍,等效操作可以在設備內部完成,而無需向主機發送事務。
WOWrInv:弱順序寫無效緩存行(0-63byte)請求,可以設置字節啟用組合。通常,WOWrInv接收一個FastGO-WritePull,后跟一個ExtCmp。收到FastGO-WritePull后,設備會將數據發送到主機。對于主機掛載內存,一旦內存中的寫入完成,主機就會發送ExtCmp。在錯誤情況下,將收到GO-Err-Writepull。設備將正常發送數據,但主機將丟棄數據。設備負責處理錯誤。在所有情況下,在GO錯誤之后,主機仍將發送ExtCmp。
WOWrInvF:與WOWrInv類似,不同的是它是一條完整的緩存行(64byte),沒有字節使能。
WrInv:這是一個0-64字節的寫無效行請求。通常,WrInv會收到一個WritePull,然后是GO。獲得WritePull后,設備將數據發送到主機。一旦內存中的寫入完成(主機掛載內存或設備掛載內存),主機將發送GO。在錯誤情況下,會收到GO-Err。設備負責處理錯誤。
CacheFlushed:設備通過此請求通知主機其緩存已刷新,并且不再包含處于Shared、Exclusive或Modified狀態的任何緩存行。主機可以使用此信息清除其監聽過濾器,阻止對設備的監聽并返回GO。一旦設備接收到GO,在設備發送下一個可緩存D2H請求之前,保證不會從主機接收任何監聽。
下表是D2H請求與對應的H2D響應(非設備掛載內存)
下表是D2H請求與對應的響應(設備掛載內存)
3.2.4.2 D2H響應
D2H響應編碼:
RspIHitI:這是設備對主機的監聽請求的響應,表示在設備端沒有此緩存行副本。如果設備返回RspIHitI,主機可以認為該緩存行已從設備中清除。
RspVHitV:這是設備對主機的監聽請求的響應,表示在設備端有此緩存行副本,但是狀態沒有改變。如果設備返回RspVHitV,主機可以認為設備至少有一個該緩存行的副本。
RspIHitSE:這是設備對主機的監聽請求的響應,表示在設備端該緩存行是干凈的,而且現在無效了。如果設備返回RspIHitSE,主機可以認為該緩存行已經從設備清掉了。
RspSHitSE:這是設備對主機的監聽請求的響應,表示在設備端該緩存行是干凈的,而且現在降級為Shared。如果設備返回RspSHitSE,主機將認為此緩存行副本還保留在設備中。
RspSFwdM:H2D的監聽請求命中的緩存行是Modified狀態,之后變為了Shared狀態。設備可以將狀態變為Invalid。設備會通過D2H CXL.cache數據通道發送64-byte給主機。
RspIFwdM:H2D的監聽請求命中的緩存行是Modified狀態,之后變為了Invalid狀態。主機可以認為設備不再有該緩存行的副本。設備會通過D2H CXL.cache數據通道發送64-byte給主機。
RspVFwdV:緩存行的狀態沒有發生變化。設備僅把當前的數據發送給主機。
3.2.4.3 H2D請求
下圖是H2D監聽完成的過程。主機可以按照與數據消息的任何相對順序接收響應消息。對于監聽數據傳輸,字節啟用字段始終為1,也就是全部啟用。
H2D請求和相關的響應:
SnpData:主機發起的監聽請求,主機想將這條緩存行狀態修改為Shared或者是Exclusive。設備響應一般發送數據。設備接到該請求后,必須無效掉自己的副本或者降級修改狀態為Shared。如果設備修改過此緩存行,必須把“臟”數據發送給主機。
SnpInv:主機發起的監聽請求,主機想擁有這條緩存行的所有權,狀態修改為Exclusive。這種請求一般是由于主機要對該緩存行進行寫操作。如果設備內有“臟”數據,那么必須將該數據返回給host。
SnpCur:該監聽請求是為了獲得最新的緩存行數據,但是并不改變它的現有狀態。如果設備中的緩存數據處于Modified狀態,必須返回一份數據給主機。主機和設備兩端的緩存行狀態不需要改變,主機不更新緩存。
3.2.4.4 H2D響應
H2D響應編碼:
WritePull:主機告訴設備,把數據發給主機,但是不用改變緩存行的狀態。用于WrInv請求,該消息需要先于GO-I消息發出,因為GO-I消息發出,意味著I/O的寫操作已經完成。
GO:(Global Observation)表示讀請求是一致的,寫請求是一致的,連貫的。系統設備已觀察到該事務,RspType字段中編碼的MESI狀態表示與該事務相關的數據應置于請求者緩存的哪個狀態。
GO_WritePull:這是GO+WritePull消息。沒有緩存狀態需要傳輸給設備。GO+WritePull消息用于posted寫類型
ExtCmp:系統觀察到了有Fast_GO數據。訪問存儲會得到最新的數據
GO_WritePull_Drop:此消息的語義與Go_WritePull相同,只是設備不應向主機發送數據。當主機確定不需要數據時,可以發送此響應來代替GO_WritePull。由于始終需要傳輸字節啟用,因此不會為部分寫入發送此響應
Fast_GO:與GO消息類似,區別是,該消息意味著只有本地知道了,而GO消息是全系統知道了。當事務是完全可觀測的時候,在該消息后面會發出ExtCmp消息。如果設備不支持該消息,則忽略這條消息,一直等待ExtCmp消息。
Fast_GO_WritePull:與GO_WritePull類似,但是該消息告訴設備,請求只是被本地觀測到。當事務是完全可觀測的時候,在該消息后面會發出ExtCmp消息。如果設備不支持該消息,則忽略這條消息,一直等待ExtCmp消息。主機不需要傳輸緩存狀態給設備。
GO_ERR_WritePull:與GO_WritePull類似,但該消息是告訴設備,請求出現了錯誤,需要設備去處理。對于WritePull,設備一定要把數據發送給主機,主機會將該數據丟棄。主機不需要傳輸緩存狀態給設備。
3.2.5 可緩存性詳述和請求限制
本小節的細節和限制適用于所有的設備。
3.2.5.1 GO-M響應
主機的GO-M響應表明設備被授予修改數據(modified data)的唯一副本。設備必須緩存此數據,并在完成后將其寫回。
3.2.5.2 Device/Host Snoop-GO-Data假設
當主機向設備返回GO響應時,期望到達接收GO的請求的相同地址的監聽將看到該GO的結果。例如,如果主機發送GO-E請求RdOwn,然后緊接著向同一地址發送監聽,接下來會期望設備將緩存行轉換為M狀態,并且返回RspIFwdM響應給主機。為了實現這一目的,CXL.cache鏈路層確保設備將接收這兩條消息,以使順序完全明確。當主機向設備發送監聽請求時,要求在主機收到監聽響應并收到所有隱式寫回(implicit writeback,IWB)數據之前,不會向設備中含有該地址的任何請求發送GO響應。當主機向設備返回數據,并且該請求的GO尚未發送到設備時,主機可能在發送GO消息之前不會向該地址發送監聽請求。
從根本上講,與讀取請求相關的GO也適用于該請求返回的數據。為讀取請求發送數據意味著數據有效,這意味著即使GO尚未到達,設備也可以使用它。
3.2.5.3 Device/Host Snoop/WritePull假設
在主機收到來自64字節地址的所有WritePull數據之前,主機不可以對該地址啟動監聽。相反,在主機收到對掛起的寫入地址監聽的響應之前,主機不可以啟動WritePull。
1.2.5.4?CXL.cache上逐出(Evicts)的監聽響應和數據傳輸
如果已在CXL.cache D2H請求通道上發出設備逐出事務,但尚未從主機收到WritePull,并且監聽命中WB,則設備必須跟蹤此監聽命中。當設備開始處理WritePull時,設備必須在發送到主機的所有D2H數據消息中設置Bogus字段。目的是向主機傳達請求數據已作為IWB數據發送,因此逐出的數據可能已過時。
3.2.5.5 對相同地址的多個監聽
只允許主機在某一時刻對指定設備的指定緩存行地址有一個未完成監聽。也就是說,主機必須等到接收到監聽響應和所有IWB數據(如果有)后,才能將下一個監聽請求發送到該地址。
3.2.5.6 對同一緩存行的多個讀請求
只有在以下特定情況下,才允許對同一緩存行執行多個讀請求。
3.2.5.7 對同一緩存行的多個逐出
不允許對同一緩存行發起多次逐出請求。
3.2.5.8 對同一緩存行的多個寫請求
允許在CXL.cache上對同一緩存行執行多個WrInv/WOWrInv/ItoMWr/MemWr。主機或交換機可以自由的進行重新排序請求,并且設備按照重新排序的順序接收相應的H2D響應。但是,通常不建議設備對同一緩存行發出多個寫請求。
3.2.5.9 GO
只有在主機保證請求將擁有緩存行的所有權之后,才會發送GO響應。
3.2.5.10 FastGO
FastGO只允許用于不需要嚴格排序的請求。
3.2.5.11 逐出到設備掛載的內存
設備僅允許向設備掛載的內存發出WrInv和WOWrInv*。
3.2.5.12 CXL.cache上的內存類型
要在CXL.cache上發出請求,設備需要通過CXL.io上的ATS請求從主機獲取主機物理地址。
編輯:黃飛
?
評論
查看更多