← Documents Documentation/PCI/tph.rst GitHub 원문 ↗

Linux 6.18.37 · PCI

TPH 지원

PCIe TPH Steering Tag로 DMA cache locality를 전달하고 mode enable, ACPI _DSM 조회, ST table 기록과 IRQ affinity 갱신을 수행하는 API를 설명합니다.

Source pathDocumentation/PCI/tph.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

tph.rst:1-132

TPH는 Endpoint의 memory request TLP에 Steering Tag를 넣어 Root Complex가 target CPU의 cache locality에 맞게 resource를 관리하도록 돕습니다.

Driver는 device가 지원하는 ST mode로 TPH를 enable하고 ACPI `_DSM`을 통해 memory type·CPU별 tag를 얻어 MSI-X table 또는 TPH Extended Capability의 entry에 기록합니다.

Network queue의 IRQ affinity가 바뀌면 새 CPU에 맞춰 ST도 갱신할 수 있으며, `notph` kernel option은 모든 Endpoint의 TPH를 비활성화합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3
4 ===========
5 TPH Support
6 ===========
7
8 :Copyright: 2024 Advanced Micro Devices, Inc.
9 :Authors: - Eric van Tassell <[email protected]>
10 - Wei Huang <[email protected]>
11
12
13 Overview
14 ========
15
16 TPH (TLP Processing Hints) is a PCIe feature that allows endpoint devices
17 to provide optimization hints for requests that target memory space.
18 These hints, in a format called Steering Tags (STs), are embedded in the
19 requester's TLP headers, enabling the system hardware, such as the Root
20 Complex, to better manage platform resources for these requests.
21
22 For example, on platforms with TPH-based direct data cache injection
23 support, an endpoint device can include appropriate STs in its DMA
24 traffic to specify which cache the data should be written to. This allows
25 the CPU core to have a higher probability of getting data from cache,
26 potentially improving performance and reducing latency in data
27 processing.
28
29
30 How to Use TPH
31 ==============
32
33 TPH is presented as an optional extended capability in PCIe. The Linux
34 kernel handles TPH discovery during boot, but it is up to the device
35 driver to request TPH enablement if it is to be utilized. Once enabled,
36 the driver uses the provided API to obtain the Steering Tag for the
37 target memory and to program the ST into the device's ST table.
38
39 Enable TPH support in Linux
40 ---------------------------
41
42 To support TPH, the kernel must be built with the CONFIG_PCIE_TPH option
43 enabled.
44
45 Manage TPH
46 ----------
47
48 To enable TPH for a device, use the following function::
49
50 int pcie_enable_tph(struct pci_dev *pdev, int mode);
51
52 This function enables TPH support for device with a specific ST mode.
53 Current supported modes include:
54
55 * PCI_TPH_ST_NS_MODE - NO ST Mode
56 * PCI_TPH_ST_IV_MODE - Interrupt Vector Mode
57 * PCI_TPH_ST_DS_MODE - Device Specific Mode
58
59 `pcie_enable_tph()` checks whether the requested mode is actually
60 supported by the device before enabling. The device driver can figure out
61 which TPH mode is supported and can be properly enabled based on the
62 return value of `pcie_enable_tph()`.
63
64 To disable TPH, use the following function::
65
66 void pcie_disable_tph(struct pci_dev *pdev);
67
68 Manage ST
69 ---------
70
71 Steering Tags are platform specific. PCIe spec does not specify where STs
72 are from. Instead PCI Firmware Specification defines an ACPI _DSM method
73 (see the `Revised _DSM for Cache Locality TPH Features ECN
74 <https://members.pcisig.com/wg/PCI-SIG/document/15470>`_) for retrieving
75 STs for a target memory of various properties. This method is what is
76 supported in this implementation.
77
78 To retrieve a Steering Tag for a target memory associated with a specific
79 CPU, use the following function::
80
81 int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
82 unsigned int cpu_uid, u16 *tag);
83
84 The `type` argument is used to specify the memory type, either volatile
85 or persistent, of the target memory. The `cpu_uid` argument specifies the
86 CPU where the memory is associated to.
87
88 After the ST value is retrieved, the device driver can use the following
89 function to write the ST into the device::
90
91 int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index,
92 u16 tag);
93
94 The `index` argument is the ST table entry index the ST tag will be
95 written into. `pcie_tph_set_st_entry()` will figure out the proper
96 location of ST table, either in the MSI-X table or in the TPH Extended
97 Capability space, and write the Steering Tag into the ST entry pointed by
98 the `index` argument.
99
100 It is completely up to the driver to decide how to use these TPH
101 functions. For example a network device driver can use the TPH APIs above
102 to update the Steering Tag when interrupt affinity of a RX/TX queue has
103 been changed. Here is a sample code for IRQ affinity notifier:
104
105 .. code-block:: c
106
107 static void irq_affinity_notified(struct irq_affinity_notify *notify,
108 const cpumask_t *mask)
109 {
110 struct drv_irq *irq;
111 unsigned int cpu_id;
112 u16 tag;
113
114 irq = container_of(notify, struct drv_irq, affinity_notify);
115 cpumask_copy(irq->cpu_mask, mask);
116
117 /* Pick a right CPU as the target - here is just an example */
118 cpu_id = cpumask_first(irq->cpu_mask);
119
120 if (pcie_tph_get_cpu_st(irq->pdev, TPH_MEM_TYPE_VM, cpu_id,
121 &tag))
122 return;
123
124 if (pcie_tph_set_st_entry(irq->pdev, irq->msix_nr, tag))
125 return;
126 }
127
128 Disable TPH system-wide
129 -----------------------
130
131 There is a kernel command line option available to control TPH feature:
132 * "notph": TPH will be disabled for all endpoint devices.
133

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

TPH와 Steering Tag 개요

1-29

이 문서는 2024년 Advanced Micro Devices, Inc. 저작물이며 저자는 Eric van Tassell과 Wei Huang입니다.

TPH(TLP Processing Hints)는 Endpoint device가 memory space를 대상으로 하는 request에 최적화 hint를 제공할 수 있게 하는 PCIe 기능입니다.

이 hint는 Steering Tag(ST) 형식으로 requester의 TLP header에 삽입됩니다. Root Complex 같은 system hardware는 이 tag를 이용해 해당 request에 필요한 platform resource를 더 적절히 관리합니다.

예를 들어 TPH 기반 direct data cache injection을 지원하는 platform에서 Endpoint는 DMA traffic에 적절한 ST를 넣어 data를 어느 cache에 쓸지 지정할 수 있습니다. 그러면 CPU core가 cache에서 data를 얻을 가능성이 높아져 processing 성능이 향상되고 latency가 줄어들 수 있습니다.

TPH 최적화 경로
Endpoint DMA requestTLP Header에 Steering Tag 삽입Root Complex가 hint 해석지정 cache로 data injectionCPU core의 cache hit 가능성 증가

Request TLP에 포함된 Steering Tag가 memory target의 locality를 hardware에 전달합니다.

TPH 구성 요소
요소역할
Endpoint deviceMemory request에 최적화 hint 제공
Steering TagTLP header에 들어가는 platform-specific hint
Root ComplexHint를 사용해 platform resource 관리
CPU cacheDMA data locality를 높여 latency 감소 가능

Hint 생성자와 소비자, 기대 효과를 구분합니다.

.. SPDX-License-Identifier: GPL-2.0


===========
TPH Support
===========

:Copyright: 2024 Advanced Micro Devices, Inc.
:Authors: - Eric van Tassell <[email protected]>
          - Wei Huang <[email protected]>


Overview
========

TPH (TLP Processing Hints) is a PCIe feature that allows endpoint devices
to provide optimization hints for requests that target memory space.
These hints, in a format called Steering Tags (STs), are embedded in the
requester's TLP headers, enabling the system hardware, such as the Root
Complex, to better manage platform resources for these requests.

For example, on platforms with TPH-based direct data cache injection
support, an endpoint device can include appropriate STs in its DMA
traffic to specify which cache the data should be written to. This allows
the CPU core to have a higher probability of getting data from cache,
potentially improving performance and reducing latency in data
processing.

Linux에서 TPH 사용 준비

30-44

TPH는 PCIe의 선택적 extended capability로 제공됩니다. Linux kernel은 boot 중 TPH capability를 발견하지만 실제 사용을 위해 enable을 요청하는 책임은 device driver에 있습니다.

TPH가 enable되면 driver는 제공된 API로 target memory의 Steering Tag를 얻고 device의 ST table에 program합니다.

Kernel은 `CONFIG_PCIE_TPH` option을 활성화하여 build해야 TPH를 지원합니다.

Linux TPH 준비
CONFIG_PCIE_TPH 활성화Boot 중 TPH capability discoveryDevice driver가 enable 요청Target memory의 ST 조회Device ST table program

Discovery는 PCI core가, 정책과 device programming은 driver가 담당합니다.

How to Use TPH
==============

TPH is presented as an optional extended capability in PCIe. The Linux
kernel handles TPH discovery during boot, but it is up to the device
driver to request TPH enablement if it is to be utilized. Once enabled,
the driver uses the provided API to obtain the Steering Tag for the
target memory and to program the ST into the device's ST table.

Enable TPH support in Linux
---------------------------

To support TPH, the kernel must be built with the CONFIG_PCIE_TPH option
enabled.

TPH enable mode와 disable

45-67

`pcie_enable_tph()`는 지정한 ST mode로 device의 TPH 지원을 enable합니다.

int pcie_enable_tph(struct pci_dev *pdev, int mode);

현재 지원 mode는 No ST Mode인 `PCI_TPH_ST_NS_MODE`, Interrupt Vector Mode인 `PCI_TPH_ST_IV_MODE`, Device Specific Mode인 `PCI_TPH_ST_DS_MODE`입니다.

TPH Steering Tag mode
SymbolMode
PCI_TPH_ST_NS_MODENo ST Mode
PCI_TPH_ST_IV_MODEInterrupt Vector Mode
PCI_TPH_ST_DS_MODEDevice Specific Mode

Driver가 device 기능과 사용 방식에 맞춰 요청할 mode입니다.

`pcie_enable_tph()`는 enable하기 전에 요청한 mode를 device가 실제로 지원하는지 확인합니다. Device driver는 함수 반환값으로 어떤 TPH mode가 지원되고 올바르게 enable됐는지 판단할 수 있습니다.

TPH를 disable하려면 `pcie_disable_tph()`를 사용합니다.

void pcie_disable_tph(struct pci_dev *pdev);
TPH mode 협상
Driver의 mode 요청pcie_enable_tph()Device mode 지원 확인TPH enable 또는 error 반환
Driver 종료·정책 변경pcie_disable_tph()TPH disable

요청 mode를 capability와 대조한 뒤 성공한 mode만 활성화합니다.

Manage TPH
----------

To enable TPH for a device, use the following function::

  int pcie_enable_tph(struct pci_dev *pdev, int mode);

This function enables TPH support for device with a specific ST mode.
Current supported modes include:

  * PCI_TPH_ST_NS_MODE - NO ST Mode
  * PCI_TPH_ST_IV_MODE - Interrupt Vector Mode
  * PCI_TPH_ST_DS_MODE - Device Specific Mode

`pcie_enable_tph()` checks whether the requested mode is actually
supported by the device before enabling. The device driver can figure out
which TPH mode is supported and can be properly enabled based on the
return value of `pcie_enable_tph()`.

To disable TPH, use the following function::

  void pcie_disable_tph(struct pci_dev *pdev);

CPU와 memory type에 맞는 ST 조회

68-87

Steering Tag는 platform-specific이며 PCIe specification은 ST의 출처를 규정하지 않습니다.

대신 PCI Firmware Specification은 여러 속성의 target memory에 사용할 ST를 조회하는 ACPI `_DSM` method를 정의합니다. 이 구현은 `Revised _DSM for Cache Locality TPH Features ECN`에 정의된 method를 지원합니다.

특정 CPU와 연결된 target memory의 Steering Tag는 `pcie_tph_get_cpu_st()`로 조회합니다.

int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
                        unsigned int cpu_uid, u16 *tag);

`type`은 target memory가 volatile인지 persistent인지 지정하는 memory type입니다. `cpu_uid`는 해당 memory와 연결된 CPU를 지정하고, 성공하면 `tag`가 Steering Tag를 받습니다.

pcie_tph_get_cpu_st() 인자
인자의미
pdevTPH를 사용하는 PCI device
typeVolatile 또는 persistent target memory type
cpu_uidMemory와 연결된 CPU
tag반환되는 16-bit Steering Tag

Platform firmware에서 올바른 locality tag를 선택하는 입력과 출력입니다.

ST 조회
Target memory type + CPU UIDpcie_tph_get_cpu_st()ACPI _DSMPlatform-specific Steering Tag

PCIe가 출처를 정하지 않으므로 firmware `_DSM`이 platform-specific tag를 제공합니다.

Manage ST
---------

Steering Tags are platform specific. PCIe spec does not specify where STs
are from. Instead PCI Firmware Specification defines an ACPI _DSM method
(see the `Revised _DSM for Cache Locality TPH Features ECN
<https://members.pcisig.com/wg/PCI-SIG/document/15470>`_) for retrieving
STs for a target memory of various properties. This method is what is
supported in this implementation.

To retrieve a Steering Tag for a target memory associated with a specific
CPU, use the following function::

  int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type,
                          unsigned int cpu_uid, u16 *tag);

The `type` argument is used to specify the memory type, either volatile
or persistent, of the target memory. The `cpu_uid` argument specifies the
CPU where the memory is associated to.

ST table 기록과 IRQ affinity 예제

88-127

ST 값을 조회한 뒤 device driver는 `pcie_tph_set_st_entry()`로 device의 ST table entry에 기록합니다.

int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index,
                          u16 tag);

`index`는 tag를 기록할 ST table entry index입니다. 함수는 ST table이 MSI-X table에 있는지 TPH Extended Capability space에 있는지 판단하고 해당 `index` entry에 Steering Tag를 씁니다.

ST table 위치
가능한 위치선택·기록
MSI-X tablepcie_tph_set_st_entry()가 index entry에 기록
TPH Extended Capability spacepcie_tph_set_st_entry()가 index entry에 기록

동일 API가 device capability에 맞는 실제 저장 위치를 선택합니다.

TPH 함수를 언제 어떻게 사용할지는 전적으로 driver가 결정합니다. 예를 들어 network driver는 RX/TX queue의 interrupt affinity가 바뀔 때 새 target CPU의 Steering Tag를 구해 갱신할 수 있습니다.

예제 IRQ affinity notifier는 새 mask를 `irq->cpu_mask`에 복사하고 첫 CPU를 target으로 선택합니다. `TPH_MEM_TYPE_VM`과 CPU ID로 tag를 조회한 뒤 MSI-X vector number인 `irq->msix_nr` index에 tag를 기록합니다. 두 API 중 하나라도 실패하면 즉시 반환합니다.

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;
}
IRQ affinity 변경 시 ST 갱신
IRQ affinity notifiercpumask_copy()cpumask_first()로 target CPU 선택pcie_tph_get_cpu_st()pcie_tph_set_st_entry(msix_nr)

Queue를 처리할 CPU가 바뀌면 locality hint도 같은 CPU에 맞춰 바꿉니다.

After the ST value is retrieved, the device driver can use the following
function to write the ST into the device::

  int pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index,
                            u16 tag);

The `index` argument is the ST table entry index the ST tag will be
written into. `pcie_tph_set_st_entry()` will figure out the proper
location of ST table, either in the MSI-X table or in the TPH Extended
Capability space, and write the Steering Tag into the ST entry pointed by
the `index` argument.

It is completely up to the driver to decide how to use these TPH
functions. For example a network device driver can use the TPH APIs above
to update the Steering Tag when interrupt affinity of a RX/TX queue has
been changed. Here is a sample code for IRQ affinity notifier:

.. code-block:: c

    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;
    }

System 전체 TPH 비활성화

128-132

Kernel command line의 `notph` option으로 TPH 기능을 system 전체에서 제어할 수 있습니다.

`notph`를 지정하면 모든 Endpoint device에서 TPH가 disable됩니다.

Kernel command-line 정책
Option효과
notph모든 Endpoint device의 TPH disable

개별 driver 요청보다 앞서 system-wide TPH 사용을 차단합니다.

Disable TPH system-wide
-----------------------

There is a kernel command line option available to control TPH feature:
    * "notph": TPH will be disabled for all endpoint devices.