pPsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/translations/zh_CN/PCI/tphmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/zh_TW/PCI/tphmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/it_IT/PCI/tphmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ja_JP/PCI/tphmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ko_KR/PCI/tphmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/sp_SP/PCI/tphmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh5/var/lib/git/docbuild/linux/Documentation/PCI/tph.rsthKubhsection)}(hhh](htitle)}(h TPH Supporth]h TPH Support}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh field_list)}(hhh](hfield)}(hhh](h field_name)}(h Copyrighth]h Copyright}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h!2024 Advanced Micro Devices, Inc.h]h paragraph)}(hhh]h!2024 Advanced Micro Devices, Inc.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hAuthorsh]hAuthors}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhKubh)}(hO- Eric van Tassell - Wei Huang h]h bullet_list)}(hhh](h list_item)}(h*Eric van Tassell h]h)}(hj"h](hEric van Tassell <}(hj$hhhNhNubh reference)}(heric.vantassell@amd.comh]heric.vantassell@amd.com}(hj-hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:eric.vantassell@amd.comuh1j+hj$ubh>}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hj ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(h Wei Huang h]h)}(hWei Huang h](h Wei Huang <}(hjQhhhNhNubj,)}(hwei.huang2@amd.comh]hwei.huang2@amd.com}(hjYhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:wei.huang2@amd.comuh1j+hjQubh>}(hjQhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjMubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhK hjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hOverviewh]hOverview}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hX`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.h]hXbTPH (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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXbFor 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.h]hXbFor 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]overviewah ]h"]overviewah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hHow to Use TPHh]hHow to Use TPH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hXWTPH 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.h]hXYTPH 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hjhhubh)}(hhh](h)}(hEnable TPH support in Linuxh]hEnable TPH support in Linux}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK(ubh)}(hQTo support TPH, the kernel must be built with the CONFIG_PCIE_TPH option enabled.h]hQTo support TPH, the kernel must be built with the CONFIG_PCIE_TPH option enabled.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK*hjhhubeh}(h]enable-tph-support-in-linuxah ]h"]enable tph support in linuxah$]h&]uh1hhjhhhhhK(ubh)}(hhh](h)}(h Manage TPHh]h Manage TPH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK.ubh)}(h8To enable TPH for a device, use the following function::h]h7To enable TPH for a device, use the following function:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjhhubh literal_block)}(h4int pcie_enable_tph(struct pci_dev *pdev, int mode);h]h4int pcie_enable_tph(struct pci_dev *pdev, int mode);}hj/sbah}(h]h ]h"]h$]h&]hhuh1j-hhhK2hjhhubh)}(hfThis function enables TPH support for device with a specific ST mode. Current supported modes include:h]hfThis function enables TPH support for device with a specific ST mode. Current supported modes include:}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hjhhubh block_quote)}(h{* PCI_TPH_ST_NS_MODE - NO ST Mode * PCI_TPH_ST_IV_MODE - Interrupt Vector Mode * PCI_TPH_ST_DS_MODE - Device Specific Mode h]j)}(hhh](j)}(hPCI_TPH_ST_NS_MODE - NO ST Modeh]h)}(hjVh]hPCI_TPH_ST_NS_MODE - NO ST Mode}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hjTubah}(h]h ]h"]h$]h&]uh1jhjQubj)}(h*PCI_TPH_ST_IV_MODE - Interrupt Vector Modeh]h)}(hjmh]h*PCI_TPH_ST_IV_MODE - Interrupt Vector Mode}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjkubah}(h]h ]h"]h$]h&]uh1jhjQubj)}(h*PCI_TPH_ST_DS_MODE - Device Specific Mode h]h)}(h)PCI_TPH_ST_DS_MODE - Device Specific Modeh]h)PCI_TPH_ST_DS_MODE - Device Specific Mode}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK9hjubah}(h]h ]h"]h$]h&]uh1jhjQubeh}(h]h ]h"]h$]h&]j*uh1jhhhK7hjMubah}(h]h ]h"]h$]h&]uh1jKhhhK7hjhhubh)}(h`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()`.h](htitle_reference)}(h`pcie_enable_tph()`h]hpcie_enable_tph()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 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 }(hjhhhNhNubj)}(h`pcie_enable_tph()`h]hpcie_enable_tph()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK;hjhhubh)}(h,To disable TPH, use the following function::h]h+To disable TPH, use the following function:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK@hjhhubj.)}(h,void pcie_disable_tph(struct pci_dev *pdev);h]h,void pcie_disable_tph(struct pci_dev *pdev);}hjsbah}(h]h ]h"]h$]h&]hhuh1j-hhhKBhjhhubeh}(h] manage-tphah ]h"] manage tphah$]h&]uh1hhjhhhhhK.ubh)}(hhh](h)}(h Manage STh]h Manage ST}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKEubh)}(hX~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 `_) for retrieving STs for a target memory of various properties. This method is what is supported in this implementation.h](hSteering Tags are platform specific. PCIe spec does not specify where STs are from. Instead PCI Firmware Specification defines an ACPI _DSM method (see the }(hj hhhNhNubj,)}(hj`Revised _DSM for Cache Locality TPH Features ECN `_h]h0Revised _DSM for Cache Locality TPH Features ECN}(hjhhhNhNubah}(h]h ]h"]h$]h&]name0Revised _DSM for Cache Locality TPH Features ECNrefuri4https://members.pcisig.com/wg/PCI-SIG/document/15470uh1j+hj ubhtarget)}(h7 h]h}(h]/revised-dsm-for-cache-locality-tph-features-ecnah ]h"]0revised _dsm for cache locality tph features ecnah$]h&]refurij%uh1j& referencedKhj ubhx) for retrieving STs for a target memory of various properties. This method is what is supported in this implementation.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKGhjhhubh)}(hkTo retrieve a Steering Tag for a target memory associated with a specific CPU, use the following function::h]hjTo retrieve a Steering Tag for a target memory associated with a specific CPU, use the following function:}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKNhjhhubj.)}(h~int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type, unsigned int cpu_uid, u16 *tag);h]h~int pcie_tph_get_cpu_st(struct pci_dev *pdev, enum tph_mem_type type, unsigned int cpu_uid, u16 *tag);}hjNsbah}(h]h ]h"]h$]h&]hhuh1j-hhhKQhjhhubh)}(hThe `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.h](hThe }(hj\hhhNhNubj)}(h`type`h]htype}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubhg argument is used to specify the memory type, either volatile or persistent, of the target memory. The }(hj\hhhNhNubj)}(h `cpu_uid`h]hcpu_uid}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh> argument specifies the CPU where the memory is associated to.}(hj\hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKThjhhubh)}(hsAfter the ST value is retrieved, the device driver can use the following function to write the ST into the device::h]hrAfter the ST value is retrieved, the device driver can use the following function to write the ST into the device:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKXhjhhubj.)}(hgint pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag);h]hgint pcie_tph_set_st_entry(struct pci_dev *pdev, unsigned int index, u16 tag);}hjsbah}(h]h ]h"]h$]h&]hhuh1j-hhhK[hjhhubh)}(hX-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.h](hThe }(hjhhhNhNubj)}(h`index`h]hindex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhG argument is the ST table entry index the ST tag will be written into. }(hjhhhNhNubj)}(h`pcie_tph_set_st_entry()`h]hpcie_tph_set_st_entry()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 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 }(hjhhhNhNubj)}(h`index`h]hindex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh argument.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK^hjhhubh)}(hXIt 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:h]hXIt 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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhjhhubj.)}(hXgstatic 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; }h]hXgstatic 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; }}hjsbah}(h]h ]h"]h$]h&]hhforcelanguagechighlight_args}uh1j-hhhKihjhhubeh}(h] manage-stah ]h"] manage stah$]h&]uh1hhjhhhhhKEubh)}(hhh](h)}(hDisable TPH system-wideh]hDisable TPH system-wide}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubhdefinition_list)}(hhh]hdefinition_list_item)}(hThere is a kernel command line option available to control TPH feature: * "notph": TPH will be disabled for all endpoint devices.h](hterm)}(hGThere is a kernel command line option available to control TPH feature:h]hGThere is a kernel command line option available to control TPH feature:}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1j3hhhKhj/ubh definition)}(hhh]j)}(hhh]j)}(h7"notph": TPH will be disabled for all endpoint devices.h]h)}(hjMh]h;“notph”: TPH will be disabled for all endpoint devices.}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjKubah}(h]h ]h"]h$]h&]uh1jhjHubah}(h]h ]h"]h$]h&]jjuh1jhhhKhjEubah}(h]h ]h"]h$]h&]uh1jChj/ubeh}(h]h ]h"]h$]h&]uh1j-hhhKhj*ubah}(h]h ]h"]h$]h&]uh1j(hjhhhNhNubeh}(h]disable-tph-system-wideah ]h"]disable tph system-wideah$]h&]uh1hhjhhhhhKubeh}(h]how-to-use-tphah ]h"]how to use tphah$]h&]uh1hhhhhhhhKubeh}(h] tph-supportah ]h"] tph supportah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjjjjjj jjjjjj1j.jj|u nametypes}(jjjj jjj1juh}(jhjjjjjjjjjjj.j(j|ju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.