11. TPH 支持¶
- 版权所有:
2024 Advanced Micro Devices, Inc.
- 作者:
Eric van Tassell <eric.vantassell@amd.com>
Wei Huang <wei.huang2@amd.com>
11.1. 概述¶
TPH(TLP 处理提示)是一项 PCIe 功能,允许端点设备为针对内存空间的请求提供优化提示。 这些提示以称为转向标签 (ST) 的格式嵌入到请求者的 TLP 标头中,使系统硬件(例如根复合体)能够更好地管理这些请求的平台资源。
例如,在具有基于 TPH 的直接数据缓存注入支持的平台上,端点设备可以在其 DMA 流量中包含适当的 ST,以指定数据应写入哪个缓存。 这允许 CPU 内核从缓存中获取数据的概率更高,从而可能提高性能并减少数据处理中的延迟。
11.2. 如何使用 TPH¶
TPH 在 PCIe 中以可选的扩展功能呈现。 Linux 内核在启动期间处理 TPH 发现,但如果需要使用 TPH,则由设备驱动程序请求启用 TPH。 启用后,驱动程序使用提供的 API 获取目标内存的转向标签,并将 ST 编程到设备的 ST 表中。
11.2.1. 在 Linux 中启用 TPH 支持¶
为了支持 TPH,内核必须在启用 CONFIG_PCIE_TPH 选项的情况下构建。
11.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);
11.2.3. 管理 ST¶
转向标签是平台特定的。 PCIe 规范未指定 ST 的来源。 相反,PCI 固件规范定义了一个 ACPI _DSM 方法(请参阅 修订后的缓存局部性 TPH 功能 ECN 的 _DSM),用于检索各种属性的目标内存的 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;
}
11.2.4. 全系统禁用 TPH¶
- 有一个内核命令行选项可用于控制 TPH 功能
“notph”:将禁用所有端点设备的 TPH。