12. TPH 支援¶
- 版權所有:
2024 Advanced Micro Devices, Inc.
- 作者:
Eric van Tassell <eric.vantassell@amd.com>
Wei Huang <wei.huang2@amd.com>
12.1. 概述¶
TPH (TLP 處理提示) 是一種 PCIe 功能,它允許端點裝置為面向記憶體空間的請求提供最佳化提示。這些提示以轉向標籤 (Steering Tags, STs) 的格式嵌入在請求者的 TLP 報頭中,使系統硬體(例如根聯合體)能夠更好地管理這些請求的平臺資源。
例如,在支援基於 TPH 的直接資料快取注入的平臺上,端點裝置可以在其 DMA 流量中包含適當的 ST,以指定資料應寫入哪個快取。這使得 CPU 核心從快取中獲取資料的可能性更高,從而可能提高效能並減少資料處理中的延遲。
12.2. 如何使用 TPH¶
TPH 在 PCIe 中作為可選的擴充套件功能呈現。Linux 核心在啟動期間處理 TPH 的發現,但如果需要利用 TPH,則由裝置驅動程式請求啟用 TPH。一旦啟用,驅動程式使用提供的 API 獲取目標記憶體的轉向標籤,並將 ST 程式設計到裝置的 ST 表中。
12.2.1. 在 Linux 中啟用 TPH 支援¶
要支援 TPH,核心必須在啟用 CONFIG_PCIE_TPH 選項的情況下構建。
12.2.2. 管理 TPH¶
要為裝置啟用 TPH,請使用以下函式
int pcie_enable_tph(struct pci_dev *pdev, int mode);
此函式為具有特定 ST 模式的裝置啟用 TPH 支援。當前支援的模式包括
PCI_TPH_ST_NS_MODE - 無 ST 模式
PCI_TPH_ST_IV_MODE - 中斷向量模式
PCI_TPH_ST_DS_MODE - 裝置特定模式
pcie_enable_tph() 在啟用前會檢查所請求的模式是否實際受裝置支援。裝置驅動程式可以根據 pcie_enable_tph() 的返回值判斷支援哪種 TPH 模式並正確啟用。
要停用 TPH,請使用以下函式
void pcie_disable_tph(struct pci_dev *pdev);
12.2.3. 管理 ST¶
轉向標籤是平臺特定的。PCIe 規範沒有明確指定 ST 的來源。相反,PCI 韌體規範定義了一個 ACPI _DSM 方法(參見 《針對快取區域性性 TPH 功能修訂的 _DSM ECN》),用於檢索具有各種屬性的目標記憶體的 ST。此實現支援的就是這種方法。
要檢索與特定 CPU 關聯的目標記憶體的轉向標籤,請使用以下函式
int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
unsigned int cpu_uid, u16 *tag);
引數 type 用於指定目標記憶體的型別,即易失性或永續性。引數 cpu_uid 指定記憶體關聯的 CPU。
檢索到 ST 值後,裝置驅動程式可以使用以下函式將 ST 寫入裝置
int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index,
u16 tag);
引數 index 是要寫入 ST 標籤的 ST 表條目索引。pcie_tph_set_st_entry() 將確定 ST 表的正確位置(無論是在 MSI-X 表中還是在 TPH 擴充套件功能空間中),並將轉向標籤寫入 index 引數指向的 ST 條目。
如何使用這些 TPH 函式完全由驅動程式決定。例如,當 RX/TX 佇列的中斷親和性發生變化時,網路裝置驅動程式可以使用上述 TPH API 更新轉向標籤。這是一個 IRQ 親和性通知器的示例程式碼
static void irq_affinity_notified(struct irq_affinity_notify *notify,
const cpumask_t *mask)
{
struct drv_irq *irq;
unsigned int cpu_id;
u16 tag;
irq = container_of(notify, struct drv_irq, affinity_notify);
cpumask_copy(irq->cpu_mask, mask);
/* Pick a right CPU as the target - here is just an example */
cpu_id = cpumask_first(irq->cpu_mask);
if (pcie_tph_get_cpu_st(irq->pdev, TPH_MEM_TYPE_VM, cpu_id,
&tag))
return;
if (pcie_tph_set_st_entry(irq->pdev, irq->msix_nr, tag))
return;
}
12.2.4. 系統範圍停用 TPH¶
- 有一個核心命令列選項可用於控制 TPH 功能
“notph”:TPH 將對所有端點裝置停用。