Re: [PATCH AUTOSEL 6.13 13/15] PCI: Store number of supported End-End TLP Prefixes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 28 Jan 2025, Sasha Levin wrote:

> From: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
> 
> [ Upstream commit e5321ae10e1323359a5067a26dfe98b5f44cc5e6 ]
> 
> eetlp_prefix_path in the struct pci_dev tells if End-End TLP Prefixes
> are supported by the path or not, and the value is only calculated if
> CONFIG_PCI_PASID is set.
> 
> The Max End-End TLP Prefixes field in the Device Capabilities Register 2
> also tells how many (1-4) End-End TLP Prefixes are supported (PCIe r6.2 sec
> 7.5.3.15). The number of supported End-End Prefixes is useful for reading
> correct number of DWORDs from TLP Prefix Log register in AER capability
> (PCIe r6.2 sec 7.8.4.12).
> 
> Replace eetlp_prefix_path with eetlp_prefix_max and determine the number of
> supported End-End Prefixes regardless of CONFIG_PCI_PASID so that an
> upcoming commit generalizing TLP Prefix Log register reading does not have
> to read extra DWORDs for End-End Prefixes that never will be there.
> 
> The value stored into eetlp_prefix_max is directly derived from device's
> Max End-End TLP Prefixes and does not consider limitations imposed by
> bridges or the Root Port beyond supported/not supported flags. This is
> intentional for two reasons:
> 
>   1) PCIe r6.2 spec sections 2.2.10.4 & 6.2.4.4 indicate that a TLP is
>      malformed only if the number of prefixes exceed the number of Max
>      End-End TLP Prefixes, which seems to be the case even if the device
>      could never receive that many prefixes due to smaller maximum imposed
>      by a bridge or the Root Port. If TLP parsing is later added, this
>      distinction is significant in interpreting what is logged by the TLP
>      Prefix Log registers and the value matching to the Malformed TLP
>      threshold is going to be more useful.
> 
>   2) TLP Prefix handling happens autonomously on a low layer and the value
>      in eetlp_prefix_max is not programmed anywhere by the kernel (i.e.,
>      there is no limiter OS can control to prevent sending more than N TLP
>      Prefixes).
> 
> Link: https://lore.kernel.org/r/20250114170840.1633-7-ilpo.jarvinen@xxxxxxxxxxxxxxx
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
> Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
> Reviewed-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

Hi,

Why is this being auto selected? It's not a fix nor do I see any 
dependency related tags. Unless the entire TLP consolidation would be 
going into stable, I don't see much value for this change in stable 
kernels.

-- 
 i.

> ---
>  drivers/pci/ats.c             |  2 +-
>  drivers/pci/probe.c           | 14 +++++++++-----
>  include/linux/pci.h           |  2 +-
>  include/uapi/linux/pci_regs.h |  1 +
>  4 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
> index 6afff1f1b1430..c6b266c772c81 100644
> --- a/drivers/pci/ats.c
> +++ b/drivers/pci/ats.c
> @@ -410,7 +410,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
>  	if (WARN_ON(pdev->pasid_enabled))
>  		return -EBUSY;
>  
> -	if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp)
> +	if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp)
>  		return -EINVAL;
>  
>  	if (!pasid)
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 2e81ab0f5a25c..381c22e3ccdbf 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2251,8 +2251,8 @@ static void pci_configure_relaxed_ordering(struct pci_dev *dev)
>  
>  static void pci_configure_eetlp_prefix(struct pci_dev *dev)
>  {
> -#ifdef CONFIG_PCI_PASID
>  	struct pci_dev *bridge;
> +	unsigned int eetlp_max;
>  	int pcie_type;
>  	u32 cap;
>  
> @@ -2264,15 +2264,19 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev)
>  		return;
>  
>  	pcie_type = pci_pcie_type(dev);
> +
> +	eetlp_max = FIELD_GET(PCI_EXP_DEVCAP2_EE_PREFIX_MAX, cap);
> +	/* 00b means 4 */
> +	eetlp_max = eetlp_max ?: 4;
> +
>  	if (pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
>  	    pcie_type == PCI_EXP_TYPE_RC_END)
> -		dev->eetlp_prefix_path = 1;
> +		dev->eetlp_prefix_max = eetlp_max;
>  	else {
>  		bridge = pci_upstream_bridge(dev);
> -		if (bridge && bridge->eetlp_prefix_path)
> -			dev->eetlp_prefix_path = 1;
> +		if (bridge && bridge->eetlp_prefix_max)
> +			dev->eetlp_prefix_max = eetlp_max;
>  	}
> -#endif
>  }
>  
>  static void pci_configure_serr(struct pci_dev *dev)
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index db9b47ce3eefd..21be5a1edf1ad 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -407,7 +407,7 @@ struct pci_dev {
>  					   supported from root to here */
>  #endif
>  	unsigned int	pasid_no_tlp:1;		/* PASID works without TLP Prefix */
> -	unsigned int	eetlp_prefix_path:1;	/* End-to-End TLP Prefix */
> +	unsigned int	eetlp_prefix_max:3;	/* Max # of End-End TLP Prefixes, 0=not supported */
>  
>  	pci_channel_state_t error_state;	/* Current connectivity state */
>  	struct device	dev;			/* Generic device interface */
> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index 1601c7ed5fab7..14a6306c4ce18 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -665,6 +665,7 @@
>  #define  PCI_EXP_DEVCAP2_OBFF_MSG	0x00040000 /* New message signaling */
>  #define  PCI_EXP_DEVCAP2_OBFF_WAKE	0x00080000 /* Re-use WAKE# for OBFF */
>  #define  PCI_EXP_DEVCAP2_EE_PREFIX	0x00200000 /* End-End TLP Prefix */
> +#define  PCI_EXP_DEVCAP2_EE_PREFIX_MAX	0x00c00000 /* Max End-End TLP Prefixes */
>  #define PCI_EXP_DEVCTL2		0x28	/* Device Control 2 */
>  #define  PCI_EXP_DEVCTL2_COMP_TIMEOUT	0x000f	/* Completion Timeout Value */
>  #define  PCI_EXP_DEVCTL2_COMP_TMOUT_DIS	0x0010	/* Completion Timeout Disable */
> 

[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux