Commit ab02bafc authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/tph'

- Add and document TLP Processing Hints (TPH) support so drivers can enable
  and disable TPH and the kernel can save/restore TPH configuration (Wei
  Huang)

- Add TPH Steering Tag support so drivers can retrieve Steering Tag values
  associated with specific CPUs via an ACPI _DSM to direct DMA writes
  closer to their consumers (Wei Huang)

* pci/tph:
  PCI/TPH: Add TPH documentation
  PCI/TPH: Add Steering Tag support
  PCI: Add TLP Processing Hints (TPH) support
parents efcbd9d3 48d0fd2b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18,3 +18,4 @@ PCI Bus Subsystem
   pcieaer-howto
   endpoint/index
   boot-interrupts
   tph
+132 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0


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

:Copyright: 2024 Advanced Micro Devices, Inc.
:Authors: - Eric van Tassell <eric.vantassell@amd.com>
          - Wei Huang <wei.huang2@amd.com>


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.


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.

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

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.

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

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.
+4 −0
Original line number Diff line number Diff line
@@ -4678,6 +4678,10 @@
		nomio		[S390] Do not use MIO instructions.
		norid		[S390] ignore the RID field and force use of
				one PCI domain per PCI function
		notph		[PCIE] If the PCIE_TPH kernel config parameter
				is enabled, this kernel boot option can be used
				to disable PCIe TLP Processing Hints support
				system-wide.

	pcie_aspm=	[PCIE] Forcibly enable or ignore PCIe Active State Power
			Management.
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ PCI Support Library
.. kernel-doc:: drivers/pci/pci-sysfs.c
   :internal:

.. kernel-doc:: drivers/pci/tph.c
   :export:

PCI Hotplug Support Library
---------------------------

+9 −0
Original line number Diff line number Diff line
@@ -173,6 +173,15 @@ config PCI_PASID

	  If unsure, say N.

config PCIE_TPH
	bool "TLP Processing Hints"
	help
	  This option adds support for PCIe TLP Processing Hints (TPH).
	  TPH allows endpoint devices to provide optimization hints, such as
	  desired caching behavior, for requests that target memory space.
	  These hints, called Steering Tags, can empower the system hardware
	  to optimize the utilization of platform resources.

config PCI_P2PDMA
	bool "PCI peer-to-peer transfer support"
	depends on ZONE_DEVICE
Loading