接收端縮放第 2 版(RSSv2)
接收端調整可改善在多處理器系統上處理網路數據的相關系統效能。 NDIS 6.80 和後續版本支援 RSS 第 2 版(RSSv2),它透過提供每個 VPort 的佇列動態分配來擴展 RSS 功能。
概述
相較於 RSSv1,RSSv2 可縮短 CPU 負載測量與更新間接數據表之間的時間,以避免在高流量情況下變慢。 為了達成此目的,RSSv2 會在處理要求的處理器內容中,於 IRQL = DISPATCH_LEVEL 執行其動作,而且只會在指向目前處理器的間接數據表專案子集上運作。 這表示 RSSv2 可以動態分散接收佇列到多個處理器,比 RSSv1 更有回應。
RSSv2 中引進了兩個 OID,OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 和 OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES,分別為迷你埠驅動程式設定適當的 RSS 功能及控制間接取值數據表。 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2是一般 OID,而 OID_GEN_RSS_SET_INDIRECTION_ENTRIES 是無法傳回NDIS_STATUS_PENDING的同步 OID。 如需這些 OID 的詳細資訊,請參閱其個別參考頁面。 如需同步 OID 的詳細資訊,請參閱 NDIS 6.80 中的同步 OID 要求介面。
RSSv2 術語
本文使用下列詞彙:
術語 | 定義 |
---|---|
RSSv1 | 第一代接收端負載調整機制。 使用 OID_GEN_RECEIVE_SCALE_PARAMETERS。 |
RSSv2 | 本文所述,Windows 10 版本 1803 和更新版本中支援的第二代接收端調整機制。 |
調整實體 | 原生 RSS 模式中的迷你埠配接器本身,或 RSSv2 模式中的 VPort。 |
ITE | 指定縮放實體的間接尋址表項 (ITE)。 每個 VPort 的 ITE 總數不能超過 非預設PFVPort的重定位表項目數 或 預設VPort的重定位表項目數,或在原生 RSS 模式下的 128。 NumberOfIndirectionTableEntriesPerNonDefaultPFVPort 和 NumberOfIndirectionTableEntriesForDefaultVPort 是 NDIS_NIC_SWITCH_CAPABILITIES 結構的成員。 |
縮放模式 | 控制 ITE 在運行時間處理方式的個別 VPort vmswitch 原則。 這可以是靜態的(由於負載變更沒有 ITE 移動)或者是動態的(根據當前的流量負載進行擴展和合併)。 |
佇列 | 用於支援 ITE 的基礎硬體物件(佇列)。 視硬體和間接數據表而定,組態佇列可能會支援多個 ITE。 佇列總數,包括預設佇列所使用的佇列,不能超過系統管理員通常設定的預先設定限制。 |
默認處理器 | 接收無法計算哈希值的封包的處理器。 每個 VPort 都有預設處理器。 |
主要處理器 | 在 VPort 建立期間,指定的處理器為 ProcessorAffinity 的 NDIS_NIC_SWITCH_VPORT_PARAMETERS 結構成員。 此處理器可以在運行時間更新,並指定 VMQ 流量的導向位置。 |
來源 CPU | 目前 ITE 所對應的處理器。 |
目標 CPU | ITE 正在重新映射的處理器(使用 RSSv2)。 |
動作專案 CPU | 正在進行 RSSv2 請求的處理器。 |
在迷你埠驅動程式中公告 RSSv2 功能
迷你埠驅動程式透過設定 NDIS_RECEIVE_SCALE_CAPABILITIES 結構的 CapabilitiesFlags 成員為 NDIS_RSS_CAPS_SUPPORTS_INDEPENDENT_ENTRY_MOVE 旗標,來宣告支援 RSSv2。 若要啟用 RSSv2 的 CPU 負載平衡功能,以及啟用非預設 VPorts (VMQs) 的 RSSv1 動態平衡 NDIS_RECEIVE_FILTER_DYNAMIC_PROCESSOR_AFFINITY_CHANGE_SUPPORTED 旗標,則需要具備這項功能。
注意
上層協定假設可以重新指派預設 VPort 的主要處理器,以便於使用 RSSv2 微型端口驅動程式。
如果迷你埠適配卡未公告 RSSv2 功能,則即使要求這些 VPort 執行動態分散,所有已啟用 VMQ 的 VPort 都會維持在靜態傳播模式中。 RSSv1 OID 用於設定 RSS 參數,OID_GEN_RECEIVE_SCALE_PARAMETERS,適用於仍在靜態分配模式的這些 VPorts。
迷你埠驅動程式只需要實作一個 RSS 控制機制 - RSSv1 或 RSSv2。 如果驅動程式公告 RSSv2 支援,NDIS 會視需要將 RSSv1 OID 轉換為 RSSv2 OID,以設定每個 VPort 散佈。 迷你埠驅動程序必須支援兩個新的 OID,並修改 RSSv1 OID_GEN_RECEIVE_SCALE_PARAMETERS OID 的行為,如下所示:
- OID_GEN_RECEIVE_SCALE_PARAMETERS 僅用於 RSSv2 中的查詢要求,而不是用於設定 RSS 參數。
- OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 是一種查詢和設定 OID,用於配置擴展實體的參數,例如佇列數量、ITE 數量、RSS 的啟用/停用,以及哈希密鑰的更新。
- OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES 是方法 OID,用來執行間接取值表條目的修改。
處理 RSSv2 OID
OID_GEN_RECEIVE_SCALE_PARAMETERS 僅用於查詢指定縮放實體的目前 RSS 參數。 在 RSSv1 中,此 OID 是用來設定參數。 針對支援 RSSv2 的小型端口驅動程式,NDIS 會自動為驅動程式執行這個功能轉換,並發出以下兩個 OID 用於設定參數。
OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 是一般 OID,其處理方式與在 RSSv1 中對待 OID_GEN_RECEIVE_SCALE_PARAMETERS OID 的方式相同。 在 NDIS 6.80 之前,NDIS 輕量篩選驅動程式 (LFS) 看不到此 OID。
不過,OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES是無法傳回NDIS_STATUS_PENDING 同步OID。 此 OID 必須在源自 OID 的處理器內容中執行並完成。 如同 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2,NDIS 6.80 之前的 NDIS LWFs 也無法查看此項目。 不允許 NDIS 6.80 和更新版本中的 LWF 延遲此 OID 或移至另一個處理器。 其負載包含一系列簡單的「移動 ITE」動作,每個動作都包含將單一 ITE 從可伸縮實體移動到不同目標 CPU 的命令。 陣列的元素可以引用不同的縮放實體 (VPorts)。
每種類型的 NDIS 驅動程式、迷你連接埠、篩選和通訊協定都有支援同步 OID 要求介面的進入點:
NDIS 驅動程序類型 | 同步 OID 處理程式 | 用於產生同步 OID 的函式 |
---|---|---|
Miniport | MiniportSynchronousOidRequest | N/A |
濾波器 | NdisFSynchronousOidRequest | |
協定 | N/A | NdisSynchronousOidRequest |
RSS 狀態轉換、ITE 更新和主要/預設處理器
轉向參數
在RSSv2中,不同的參數可用來根據 RSS 狀態(已啟用或停用)將流量導向正確的 CPU。 停用 RSS 時,只會使用主要處理器來引導流量。 啟用 RSS 時,預設處理器和所有 ITE 都會用於引導流量。 下表摘要說明這些 轉向參數 標示為「使用中」或「非使用中」:
轉向參數 | RSS 已停用 | 已啟用 RSS |
---|---|---|
主要處理器 | 活躍 | 無效 |
默認處理器 | 無效 | 活躍中 |
ITE[0..N] | 無效 | 積極 |
當轉向參數處於 作用中 狀態時,它會引導流量。 從 RSS 狀態轉換使參數 所在的狀態變為無效的那一刻起,迷你埠驅動程式必須追蹤該參數的變更,直至反向轉換再次激活它。 這表示迷你埠驅動程序必須追蹤默認處理器和間接數據表專案的所有更新,同時停用該縮放實體的 RSS。 啟用 RSS 時,預設處理器和間接表的當前追蹤狀態應該生效。
例如,請考慮軟體 vRSS 已啟用時的案例。 在此情況下,間接數據表已存在於上層通訊協定中,而且會由上層的軟體散佈程式代碼主動使用。 如果在硬體 RSS 啟用期間,所有項目在更新到 移動的間接資料表項目之前就開始指向主要處理器,且這些更新是由 硬體發出並執行的,那麼主要處理器可能會遇到短暫的停頓。 如果迷你埠驅動程式已追蹤默認處理器和 ITE 資訊,它可以將流量導向到上層已預期的位置。
雖然迷你埠驅動程式必須追蹤非使用中轉向參數的所有更新,但它們應該延遲這些參數的驗證,直到 RSS 狀態變更嘗試讓這些參數 作用中。 例如,在硬體 RSS 被停用以進行軟體散佈的情況下,上層通訊協定可以使用任何處理器來進行散佈(包括網路介面卡的 RSS 集合之外的處理器)。 上層可確保在 RSS 狀態轉換時,所有 非使用中 參數都適用於新的 RSS 狀態。 不過,迷你埠驅動程序仍應先驗證參數,如果發現任何追蹤 非使用中 轉向參數無效,應導致 RSS 狀態轉換失敗。
導向參數的初始狀態和更新
下表描述建立后調整實體的初始狀態(例如 VPort 建立之後),以及如何更新參數:
參數 | 描述 |
---|---|
主要處理器 |
|
默認處理器 |
|
間接映射表 |
|
ITE 和主要/預設處理器的更新(使用 OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES)會從目前將對應項目指向的處理器進行呼叫。 對於指定的 VPort,上層可確保不會有OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID 移動 ITE 或設定主要/預設處理器,在這些情況下:
- 在OID_GEN_RECEIVE_SCALE_PARAMETERS_V2進行時。
- 啟動 VPort 刪除順序後。 例如,上層會在完成最後一個 OID 以移動 ITEs 之後,才發出設定篩選器 OID 的指令。
停用 RSS 功能
在 RSS 停用期間,上層通訊協定可能會選擇將所有 ITE 指向主要處理器,然後發出 OID 以停用 RSS,或選擇將間接數據表保留 as-is 並停用 RSS。 不論是哪一種情況,接收流量都應該以主要處理器為目標。
RSSv2 會維護 RSSv1 的需求,允許上層通訊協定刪除 VPort,而不需要先停用 RSS。 上層可以將 VPort 上的接收篩選器設為零,以確保不會有接收流量流經 VPort,然後在不禁用 RSS 的情況下繼續進行 VPort 的刪除。 上層系統保證在 VPort 刪除期間或之後,不會發出任何 OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID。
在 RSS 停用和 VPort 刪除期間,迷你端口驅動程式應該負責處理所有可能因為先前的佇列移動而存在的擱置內部作業。
RSSv2 不變量
上層通訊協定可確保在執行管理功能或 ITE 移動之前,不會違反重要的不因數。 例如:
- 在減少佇列數目之前,上層可確保間接數據表不會參考比 VPort 的新佇列數目更多的處理器。
- 上層不應該要求間接數據表更新,該更新違反 VPort 目前設定的佇列數目。 迷你埠驅動程式應強制執行此規則並返回失敗狀態。
- 在變更 VMMQ-RESTRICTED 介面卡的間接表項數量之前,上層會確保間接轉換資料表的內容會正規化為 2 的次方。
相關連結
OID_GEN_RECEIVE_SCALE_PARAMETERS_V2
OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES
NDIS 6.80 中的同步 OID 請求介面