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